18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#ifndef API_BASE_CONTAINERS_STRING_H
178bf80f4bSopenharmony_ci#define API_BASE_CONTAINERS_STRING_H
188bf80f4bSopenharmony_ci
198bf80f4bSopenharmony_ci#include <cstddef>
208bf80f4bSopenharmony_ci#include <cstdint>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ci#include <base/containers/allocator.h>
238bf80f4bSopenharmony_ci#include <base/containers/iterator.h>
248bf80f4bSopenharmony_ci#include <base/containers/string_view.h>
258bf80f4bSopenharmony_ci#include <base/containers/type_traits.h>
268bf80f4bSopenharmony_ci#include <base/namespace.h>
278bf80f4bSopenharmony_ci#include <base/util/log.h>
288bf80f4bSopenharmony_ci
298bf80f4bSopenharmony_ciBASE_BEGIN_NAMESPACE()
308bf80f4bSopenharmony_citemplate<class CharT>
318bf80f4bSopenharmony_ciclass basic_string;
328bf80f4bSopenharmony_ci
338bf80f4bSopenharmony_ciusing string = BASE_NS::basic_string<char>;
348bf80f4bSopenharmony_ciusing wstring = BASE_NS::basic_string<wchar_t>;
358bf80f4bSopenharmony_ci
368bf80f4bSopenharmony_citemplate<class CharT>
378bf80f4bSopenharmony_ciclass basic_string {
388bf80f4bSopenharmony_cipublic:
398bf80f4bSopenharmony_ci    using string_view = basic_string_view<CharT>;
408bf80f4bSopenharmony_ci    using value_type = CharT;
418bf80f4bSopenharmony_ci    using pointer = value_type*;
428bf80f4bSopenharmony_ci    using const_pointer = const value_type*;
438bf80f4bSopenharmony_ci    using reference = value_type&;
448bf80f4bSopenharmony_ci    using const_reference = const value_type&;
458bf80f4bSopenharmony_ci    using const_iterator = BASE_NS::const_iterator<basic_string>;
468bf80f4bSopenharmony_ci    using iterator = BASE_NS::iterator<basic_string>;
478bf80f4bSopenharmony_ci    using const_reverse_iterator = BASE_NS::reverse_iterator<const_iterator>;
488bf80f4bSopenharmony_ci    using reverse_iterator = BASE_NS::reverse_iterator<iterator>;
498bf80f4bSopenharmony_ci    using size_type = size_t;
508bf80f4bSopenharmony_ci    using difference_type = ptrdiff_t;
518bf80f4bSopenharmony_ci
528bf80f4bSopenharmony_ci    static constexpr size_type npos = size_type(-1);
538bf80f4bSopenharmony_ci
548bf80f4bSopenharmony_ci    template<typename T>
558bf80f4bSopenharmony_ci    using StringViewLikeNotCStr =
568bf80f4bSopenharmony_ci        enable_if_t<is_convertible_v<const T&, string_view> && !is_convertible_v<const T&, const_pointer>>;
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_ci    template<typename T>
598bf80f4bSopenharmony_ci    using StringViewLike = enable_if_t<is_convertible_v<const T&, string_view>>;
608bf80f4bSopenharmony_ci
618bf80f4bSopenharmony_ci    basic_string() noexcept : basic_string(default_allocator()) {}
628bf80f4bSopenharmony_ci
638bf80f4bSopenharmony_ci    ~basic_string()
648bf80f4bSopenharmony_ci    {
658bf80f4bSopenharmony_ci        if (!is_short()) {
668bf80f4bSopenharmony_ci            allocator_.free(data_.longString.begin);
678bf80f4bSopenharmony_ci        }
688bf80f4bSopenharmony_ci    }
698bf80f4bSopenharmony_ci
708bf80f4bSopenharmony_ci    explicit basic_string(allocator& alloc) noexcept : allocator_(alloc)
718bf80f4bSopenharmony_ci    {
728bf80f4bSopenharmony_ci        set_short(true);
738bf80f4bSopenharmony_ci        data_.shortString.begin[1] = '\0';
748bf80f4bSopenharmony_ci        data_.shortString.size = static_cast<value_type>(shortCapacity);
758bf80f4bSopenharmony_ci    }
768bf80f4bSopenharmony_ci
778bf80f4bSopenharmony_ci    basic_string(const basic_string& str) : basic_string(str, default_allocator()) {}
788bf80f4bSopenharmony_ci
798bf80f4bSopenharmony_ci    basic_string(const basic_string& str, allocator& alloc) : allocator_(alloc)
808bf80f4bSopenharmony_ci    {
818bf80f4bSopenharmony_ci        if (str.data_.longString.isShort) {
828bf80f4bSopenharmony_ci            data_.shortString = str.data_.shortString;
838bf80f4bSopenharmony_ci        } else {
848bf80f4bSopenharmony_ci            const auto len = str.data_.longString.size;
858bf80f4bSopenharmony_ci            if (auto ptr = allocator_.alloc(len + 1); ptr) {
868bf80f4bSopenharmony_ci                // destination and source are valid and the allocation sizes are for at least len characters.
878bf80f4bSopenharmony_ci                CloneData(ptr, len * sizeof(value_type), str.data_.longString.begin, len * sizeof(value_type));
888bf80f4bSopenharmony_ci                ptr[len] = '\0';
898bf80f4bSopenharmony_ci
908bf80f4bSopenharmony_ci                data_.longString = str.data_.longString;
918bf80f4bSopenharmony_ci                data_.longString.capacity = len;
928bf80f4bSopenharmony_ci                data_.longString.begin = ptr;
938bf80f4bSopenharmony_ci            } else {
948bf80f4bSopenharmony_ci                set_short(true);
958bf80f4bSopenharmony_ci                data_.shortString.begin[1] = '\0';
968bf80f4bSopenharmony_ci                data_.shortString.size = static_cast<value_type>(shortCapacity);
978bf80f4bSopenharmony_ci            }
988bf80f4bSopenharmony_ci        }
998bf80f4bSopenharmony_ci    }
1008bf80f4bSopenharmony_ci
1018bf80f4bSopenharmony_ci    basic_string(basic_string&& a) noexcept : allocator_(a.allocator_), data_(BASE_NS::move(a.data_))
1028bf80f4bSopenharmony_ci    {
1038bf80f4bSopenharmony_ci        a.set_short(true);
1048bf80f4bSopenharmony_ci        a.data_.shortString.begin[1] = '\0';
1058bf80f4bSopenharmony_ci        a.data_.shortString.size = static_cast<value_type>(shortCapacity);
1068bf80f4bSopenharmony_ci    }
1078bf80f4bSopenharmony_ci
1088bf80f4bSopenharmony_ci    basic_string(const_pointer const str) : basic_string(str, default_allocator()) {}
1098bf80f4bSopenharmony_ci
1108bf80f4bSopenharmony_ci    basic_string(const_pointer const str, allocator& alloc) : basic_string(str, constexpr_strlen(str), alloc) {}
1118bf80f4bSopenharmony_ci
1128bf80f4bSopenharmony_ci    basic_string(const_pointer const str, size_type count) : basic_string(str, count, default_allocator()) {}
1138bf80f4bSopenharmony_ci
1148bf80f4bSopenharmony_ci    basic_string(const_pointer const str, size_type count, allocator& alloc) : allocator_(alloc)
1158bf80f4bSopenharmony_ci    {
1168bf80f4bSopenharmony_ci        construct(str, count);
1178bf80f4bSopenharmony_ci    }
1188bf80f4bSopenharmony_ci
1198bf80f4bSopenharmony_ci    basic_string(size_type count, const value_type a) : basic_string(count, a, default_allocator()) {}
1208bf80f4bSopenharmony_ci
1218bf80f4bSopenharmony_ci    basic_string(size_type count, const value_type a, allocator& alloc) : allocator_(alloc)
1228bf80f4bSopenharmony_ci    {
1238bf80f4bSopenharmony_ci        set_short(true);
1248bf80f4bSopenharmony_ci        data_.shortString.size = static_cast<value_type>(shortCapacity);
1258bf80f4bSopenharmony_ci        assign(count, a);
1268bf80f4bSopenharmony_ci    }
1278bf80f4bSopenharmony_ci
1288bf80f4bSopenharmony_ci    template<class StringT, class = StringViewLikeNotCStr<StringT>>
1298bf80f4bSopenharmony_ci    explicit basic_string(const StringT& a) : basic_string(a, default_allocator())
1308bf80f4bSopenharmony_ci    {}
1318bf80f4bSopenharmony_ci
1328bf80f4bSopenharmony_ci    template<class StringT, class = StringViewLikeNotCStr<StringT>>
1338bf80f4bSopenharmony_ci    explicit basic_string(const StringT& a, allocator& alloc) : allocator_(alloc)
1348bf80f4bSopenharmony_ci    {
1358bf80f4bSopenharmony_ci        if constexpr (is_same_v<StringT, string_view>) {
1368bf80f4bSopenharmony_ci            construct(a.data(), a.size());
1378bf80f4bSopenharmony_ci        } else {
1388bf80f4bSopenharmony_ci            const auto view = string_view(a);
1398bf80f4bSopenharmony_ci            construct(view.data(), view.size());
1408bf80f4bSopenharmony_ci        }
1418bf80f4bSopenharmony_ci    }
1428bf80f4bSopenharmony_ci
1438bf80f4bSopenharmony_ci    template<class StringT, class = StringViewLike<StringT>>
1448bf80f4bSopenharmony_ci    basic_string(const StringT& a, size_type pos, size_type n) : basic_string(a, pos, n, default_allocator())
1458bf80f4bSopenharmony_ci    {}
1468bf80f4bSopenharmony_ci
1478bf80f4bSopenharmony_ci    template<class StringT, class = StringViewLike<StringT>>
1488bf80f4bSopenharmony_ci    basic_string(const StringT& a, size_type pos, size_type n, allocator& alloc)
1498bf80f4bSopenharmony_ci        : basic_string(string_view(a).substr(pos, n), alloc)
1508bf80f4bSopenharmony_ci    {}
1518bf80f4bSopenharmony_ci
1528bf80f4bSopenharmony_ci    bool empty() const noexcept
1538bf80f4bSopenharmony_ci    {
1548bf80f4bSopenharmony_ci        return !size();
1558bf80f4bSopenharmony_ci    }
1568bf80f4bSopenharmony_ci
1578bf80f4bSopenharmony_ci    void clear()
1588bf80f4bSopenharmony_ci    {
1598bf80f4bSopenharmony_ci        assign("", 0);
1608bf80f4bSopenharmony_ci    }
1618bf80f4bSopenharmony_ci
1628bf80f4bSopenharmony_ci    value_type& back()
1638bf80f4bSopenharmony_ci    {
1648bf80f4bSopenharmony_ci        return *(data() + size() - 1);
1658bf80f4bSopenharmony_ci    }
1668bf80f4bSopenharmony_ci
1678bf80f4bSopenharmony_ci    const value_type& back() const
1688bf80f4bSopenharmony_ci    {
1698bf80f4bSopenharmony_ci        return *(data() + size() - 1);
1708bf80f4bSopenharmony_ci    }
1718bf80f4bSopenharmony_ci
1728bf80f4bSopenharmony_ci    value_type& front()
1738bf80f4bSopenharmony_ci    {
1748bf80f4bSopenharmony_ci        return *data();
1758bf80f4bSopenharmony_ci    }
1768bf80f4bSopenharmony_ci
1778bf80f4bSopenharmony_ci    const value_type& front() const
1788bf80f4bSopenharmony_ci    {
1798bf80f4bSopenharmony_ci        return *data();
1808bf80f4bSopenharmony_ci    }
1818bf80f4bSopenharmony_ci
1828bf80f4bSopenharmony_ci    size_type capacity() const noexcept
1838bf80f4bSopenharmony_ci    {
1848bf80f4bSopenharmony_ci        if (is_short()) {
1858bf80f4bSopenharmony_ci            return shortCapacity;
1868bf80f4bSopenharmony_ci        } else {
1878bf80f4bSopenharmony_ci            return data_.longString.capacity;
1888bf80f4bSopenharmony_ci        }
1898bf80f4bSopenharmony_ci    }
1908bf80f4bSopenharmony_ci
1918bf80f4bSopenharmony_ci    size_type length() const noexcept
1928bf80f4bSopenharmony_ci    {
1938bf80f4bSopenharmony_ci        return size();
1948bf80f4bSopenharmony_ci    }
1958bf80f4bSopenharmony_ci
1968bf80f4bSopenharmony_ci    size_type size() const noexcept
1978bf80f4bSopenharmony_ci    {
1988bf80f4bSopenharmony_ci        if (is_short()) {
1998bf80f4bSopenharmony_ci            return shortCapacity - data_.shortString.size;
2008bf80f4bSopenharmony_ci        } else {
2018bf80f4bSopenharmony_ci            return data_.longString.size;
2028bf80f4bSopenharmony_ci        }
2038bf80f4bSopenharmony_ci    }
2048bf80f4bSopenharmony_ci
2058bf80f4bSopenharmony_ci    basic_string& operator=(const basic_string& a)
2068bf80f4bSopenharmony_ci    {
2078bf80f4bSopenharmony_ci        if (&a != this) {
2088bf80f4bSopenharmony_ci            assign(a.data(), a.length());
2098bf80f4bSopenharmony_ci        }
2108bf80f4bSopenharmony_ci        return *this;
2118bf80f4bSopenharmony_ci    }
2128bf80f4bSopenharmony_ci
2138bf80f4bSopenharmony_ci    basic_string& operator=(basic_string&& a) noexcept
2148bf80f4bSopenharmony_ci    {
2158bf80f4bSopenharmony_ci        if (&a != this) {
2168bf80f4bSopenharmony_ci            if (!is_short()) {
2178bf80f4bSopenharmony_ci                allocator_.free(data_.longString.begin);
2188bf80f4bSopenharmony_ci            }
2198bf80f4bSopenharmony_ci            allocator_ = a.allocator_;
2208bf80f4bSopenharmony_ci            data_ = BASE_NS::move(a.data_);
2218bf80f4bSopenharmony_ci
2228bf80f4bSopenharmony_ci            a.set_short(true);
2238bf80f4bSopenharmony_ci            a.data_.shortString.begin[1] = '\0';
2248bf80f4bSopenharmony_ci            a.data_.shortString.size = static_cast<value_type>(shortCapacity);
2258bf80f4bSopenharmony_ci        }
2268bf80f4bSopenharmony_ci        return *this;
2278bf80f4bSopenharmony_ci    }
2288bf80f4bSopenharmony_ci
2298bf80f4bSopenharmony_ci    basic_string& operator=(const value_type ch)
2308bf80f4bSopenharmony_ci    {
2318bf80f4bSopenharmony_ci        auto ptr = data();
2328bf80f4bSopenharmony_ci        *ptr++ = ch;
2338bf80f4bSopenharmony_ci        *ptr++ = '\0';
2348bf80f4bSopenharmony_ci        set_size(1);
2358bf80f4bSopenharmony_ci        return *this;
2368bf80f4bSopenharmony_ci    }
2378bf80f4bSopenharmony_ci
2388bf80f4bSopenharmony_ci    basic_string& operator=(const_pointer const a)
2398bf80f4bSopenharmony_ci    {
2408bf80f4bSopenharmony_ci        if (data() != a) {
2418bf80f4bSopenharmony_ci            assign(a, constexpr_strlen(a));
2428bf80f4bSopenharmony_ci        }
2438bf80f4bSopenharmony_ci        return *this;
2448bf80f4bSopenharmony_ci    }
2458bf80f4bSopenharmony_ci
2468bf80f4bSopenharmony_ci    template<class StringT, class = StringViewLikeNotCStr<StringT>>
2478bf80f4bSopenharmony_ci    basic_string& operator=(const StringT& a)
2488bf80f4bSopenharmony_ci    {
2498bf80f4bSopenharmony_ci        const auto view = string_view(a);
2508bf80f4bSopenharmony_ci        if (data() != view.data()) {
2518bf80f4bSopenharmony_ci            assign(view.data(), view.length());
2528bf80f4bSopenharmony_ci        } else {
2538bf80f4bSopenharmony_ci            resize(view.length());
2548bf80f4bSopenharmony_ci        }
2558bf80f4bSopenharmony_ci        return *this;
2568bf80f4bSopenharmony_ci    }
2578bf80f4bSopenharmony_ci
2588bf80f4bSopenharmony_ci    basic_string& assign(const_pointer const str)
2598bf80f4bSopenharmony_ci    {
2608bf80f4bSopenharmony_ci        const auto view = string_view(str);
2618bf80f4bSopenharmony_ci        return assign(view.data(), view.length());
2628bf80f4bSopenharmony_ci    }
2638bf80f4bSopenharmony_ci
2648bf80f4bSopenharmony_ci    basic_string& assign(const_pointer const str, size_type count)
2658bf80f4bSopenharmony_ci    {
2668bf80f4bSopenharmony_ci        if (count) {
2678bf80f4bSopenharmony_ci            reserve(count);
2688bf80f4bSopenharmony_ci            const pointer dst = data();
2698bf80f4bSopenharmony_ci            const size_type cap = capacity();
2708bf80f4bSopenharmony_ci            if (static_cast<size_type>((dst > str) ? (dst - str) : (str - dst)) >= count) {
2718bf80f4bSopenharmony_ci                CloneData(dst, cap * sizeof(value_type), str, count * sizeof(value_type));
2728bf80f4bSopenharmony_ci            } else {
2738bf80f4bSopenharmony_ci                MoveData(dst, cap * sizeof(value_type), str, count * sizeof(value_type));
2748bf80f4bSopenharmony_ci            }
2758bf80f4bSopenharmony_ci            dst[count] = '\0';
2768bf80f4bSopenharmony_ci        } else {
2778bf80f4bSopenharmony_ci            const pointer dst = data();
2788bf80f4bSopenharmony_ci            *dst = '\0';
2798bf80f4bSopenharmony_ci        }
2808bf80f4bSopenharmony_ci        set_size(count);
2818bf80f4bSopenharmony_ci        return *this;
2828bf80f4bSopenharmony_ci    }
2838bf80f4bSopenharmony_ci
2848bf80f4bSopenharmony_ci    basic_string& assign(size_type count, value_type ch)
2858bf80f4bSopenharmony_ci    {
2868bf80f4bSopenharmony_ci        if (count) {
2878bf80f4bSopenharmony_ci            reserve(count);
2888bf80f4bSopenharmony_ci            const pointer dst = data();
2898bf80f4bSopenharmony_ci            const size_type cap = capacity();
2908bf80f4bSopenharmony_ci            count = (count <= cap) ? count : cap;
2918bf80f4bSopenharmony_ci            // dst is valid, count fits capacity
2928bf80f4bSopenharmony_ci            ClearToValue(dst, cap * sizeof(value_type), static_cast<uint8_t>(ch), count * sizeof(value_type));
2938bf80f4bSopenharmony_ci            dst[count] = '\0';
2948bf80f4bSopenharmony_ci            set_size(count);
2958bf80f4bSopenharmony_ci        } else {
2968bf80f4bSopenharmony_ci            const pointer dst = data();
2978bf80f4bSopenharmony_ci            *dst = '\0';
2988bf80f4bSopenharmony_ci            set_size(0);
2998bf80f4bSopenharmony_ci        }
3008bf80f4bSopenharmony_ci        return *this;
3018bf80f4bSopenharmony_ci    }
3028bf80f4bSopenharmony_ci
3038bf80f4bSopenharmony_ci    const_iterator cbegin() const noexcept
3048bf80f4bSopenharmony_ci    {
3058bf80f4bSopenharmony_ci        return begin();
3068bf80f4bSopenharmony_ci    }
3078bf80f4bSopenharmony_ci
3088bf80f4bSopenharmony_ci    const_iterator cend() const noexcept
3098bf80f4bSopenharmony_ci    {
3108bf80f4bSopenharmony_ci        return end();
3118bf80f4bSopenharmony_ci    }
3128bf80f4bSopenharmony_ci
3138bf80f4bSopenharmony_ci    iterator begin() noexcept
3148bf80f4bSopenharmony_ci    {
3158bf80f4bSopenharmony_ci        return iterator(data());
3168bf80f4bSopenharmony_ci    }
3178bf80f4bSopenharmony_ci
3188bf80f4bSopenharmony_ci    iterator end() noexcept
3198bf80f4bSopenharmony_ci    {
3208bf80f4bSopenharmony_ci        return iterator(data() + size());
3218bf80f4bSopenharmony_ci    }
3228bf80f4bSopenharmony_ci
3238bf80f4bSopenharmony_ci    const_iterator begin() const noexcept
3248bf80f4bSopenharmony_ci    {
3258bf80f4bSopenharmony_ci        return const_iterator(data());
3268bf80f4bSopenharmony_ci    }
3278bf80f4bSopenharmony_ci
3288bf80f4bSopenharmony_ci    const_iterator end() const noexcept
3298bf80f4bSopenharmony_ci    {
3308bf80f4bSopenharmony_ci        return const_iterator(data() + size());
3318bf80f4bSopenharmony_ci    }
3328bf80f4bSopenharmony_ci
3338bf80f4bSopenharmony_ci    pointer data() noexcept
3348bf80f4bSopenharmony_ci    {
3358bf80f4bSopenharmony_ci        if (is_short()) {
3368bf80f4bSopenharmony_ci            return data_.shortString.begin + 1;
3378bf80f4bSopenharmony_ci        } else {
3388bf80f4bSopenharmony_ci            return data_.longString.begin;
3398bf80f4bSopenharmony_ci        }
3408bf80f4bSopenharmony_ci    }
3418bf80f4bSopenharmony_ci
3428bf80f4bSopenharmony_ci    const_pointer data() const noexcept
3438bf80f4bSopenharmony_ci    {
3448bf80f4bSopenharmony_ci        if (is_short()) {
3458bf80f4bSopenharmony_ci            return data_.shortString.begin + 1;
3468bf80f4bSopenharmony_ci        } else {
3478bf80f4bSopenharmony_ci            return data_.longString.begin;
3488bf80f4bSopenharmony_ci        }
3498bf80f4bSopenharmony_ci    }
3508bf80f4bSopenharmony_ci
3518bf80f4bSopenharmony_ci    const_pointer c_str() const
3528bf80f4bSopenharmony_ci    {
3538bf80f4bSopenharmony_ci        return data();
3548bf80f4bSopenharmony_ci    }
3558bf80f4bSopenharmony_ci
3568bf80f4bSopenharmony_ci    operator string_view() const noexcept
3578bf80f4bSopenharmony_ci    {
3588bf80f4bSopenharmony_ci        return string_view(data(), size());
3598bf80f4bSopenharmony_ci    }
3608bf80f4bSopenharmony_ci
3618bf80f4bSopenharmony_ci    size_type copy(pointer dst, size_type todo) const
3628bf80f4bSopenharmony_ci    {
3638bf80f4bSopenharmony_ci        if (const auto len = size(); todo > len) {
3648bf80f4bSopenharmony_ci            todo = len;
3658bf80f4bSopenharmony_ci        }
3668bf80f4bSopenharmony_ci        auto ptr = data();
3678bf80f4bSopenharmony_ci        const auto end = ptr + todo;
3688bf80f4bSopenharmony_ci        while (ptr != end) {
3698bf80f4bSopenharmony_ci            *dst++ = *ptr++;
3708bf80f4bSopenharmony_ci        }
3718bf80f4bSopenharmony_ci        return todo;
3728bf80f4bSopenharmony_ci    }
3738bf80f4bSopenharmony_ci
3748bf80f4bSopenharmony_ci    void reserve(size_type size)
3758bf80f4bSopenharmony_ci    {
3768bf80f4bSopenharmony_ci        if (size > capacity()) {
3778bf80f4bSopenharmony_ci            // setup new storage with old data
3788bf80f4bSopenharmony_ci            allocate(size);
3798bf80f4bSopenharmony_ci        }
3808bf80f4bSopenharmony_ci    }
3818bf80f4bSopenharmony_ci
3828bf80f4bSopenharmony_ci    void resize(size_type size, value_type ch)
3838bf80f4bSopenharmony_ci    {
3848bf80f4bSopenharmony_ci        if (const auto oldSize = length(); size < oldSize) {
3858bf80f4bSopenharmony_ci            data()[size] = '\0';
3868bf80f4bSopenharmony_ci        } else if (size > oldSize) {
3878bf80f4bSopenharmony_ci            reserve(size);
3888bf80f4bSopenharmony_ci            const auto ptr = data() + oldSize;
3898bf80f4bSopenharmony_ci            const size_type cap = capacity();
3908bf80f4bSopenharmony_ci            size = (size <= cap) ? size : cap;
3918bf80f4bSopenharmony_ci            const auto count = size - oldSize;
3928bf80f4bSopenharmony_ci            // ptr is valid, count fits capacity
3938bf80f4bSopenharmony_ci            ClearToValue(ptr, cap * sizeof(value_type), static_cast<uint8_t>(ch), count * sizeof(value_type));
3948bf80f4bSopenharmony_ci            ptr[count] = '\0';
3958bf80f4bSopenharmony_ci        }
3968bf80f4bSopenharmony_ci
3978bf80f4bSopenharmony_ci        set_size(size);
3988bf80f4bSopenharmony_ci    }
3998bf80f4bSopenharmony_ci
4008bf80f4bSopenharmony_ci    void resize(size_type size)
4018bf80f4bSopenharmony_ci    {
4028bf80f4bSopenharmony_ci        resize(size, '\0');
4038bf80f4bSopenharmony_ci    }
4048bf80f4bSopenharmony_ci
4058bf80f4bSopenharmony_ci    template<class StringT, class = StringViewLikeNotCStr<StringT>>
4068bf80f4bSopenharmony_ci    basic_string& operator+=(const StringT& a)
4078bf80f4bSopenharmony_ci    {
4088bf80f4bSopenharmony_ci        const auto view = string_view(a);
4098bf80f4bSopenharmony_ci        return append(view.data(), view.length());
4108bf80f4bSopenharmony_ci    }
4118bf80f4bSopenharmony_ci
4128bf80f4bSopenharmony_ci    basic_string& operator+=(const value_type a)
4138bf80f4bSopenharmony_ci    {
4148bf80f4bSopenharmony_ci        return push_back(a);
4158bf80f4bSopenharmony_ci    }
4168bf80f4bSopenharmony_ci
4178bf80f4bSopenharmony_ci    basic_string& operator+=(const_pointer const a)
4188bf80f4bSopenharmony_ci    {
4198bf80f4bSopenharmony_ci        return append(a, constexpr_strlen(a));
4208bf80f4bSopenharmony_ci    }
4218bf80f4bSopenharmony_ci
4228bf80f4bSopenharmony_ci    const_reference operator[](size_type i) const
4238bf80f4bSopenharmony_ci    {
4248bf80f4bSopenharmony_ci        return data()[i];
4258bf80f4bSopenharmony_ci    }
4268bf80f4bSopenharmony_ci
4278bf80f4bSopenharmony_ci    reference operator[](size_type i)
4288bf80f4bSopenharmony_ci    {
4298bf80f4bSopenharmony_ci        return data()[i];
4308bf80f4bSopenharmony_ci    }
4318bf80f4bSopenharmony_ci
4328bf80f4bSopenharmony_ci    basic_string& replace(const_iterator first, const_iterator last, const string_view& str)
4338bf80f4bSopenharmony_ci    {
4348bf80f4bSopenharmony_ci        const auto pos = first - cbegin();
4358bf80f4bSopenharmony_ci        const auto replace = last - first;
4368bf80f4bSopenharmony_ci        const auto add = static_cast<difference_type>(str.length());
4378bf80f4bSopenharmony_ci        if (add < replace) {
4388bf80f4bSopenharmony_ci            CloneData(data() + pos, replace * sizeof(value_type), str.data(), add * sizeof(value_type));
4398bf80f4bSopenharmony_ci            erase(first + add, last);
4408bf80f4bSopenharmony_ci        } else if (add > replace) {
4418bf80f4bSopenharmony_ci            CloneData(data() + pos, replace * sizeof(value_type), str.data(), replace * sizeof(value_type));
4428bf80f4bSopenharmony_ci            insert(static_cast<size_type>(pos + replace), str.data() + replace, static_cast<size_type>(add - replace));
4438bf80f4bSopenharmony_ci        } else {
4448bf80f4bSopenharmony_ci            CloneData(data() + pos, replace * sizeof(value_type), str.data(), add * sizeof(value_type));
4458bf80f4bSopenharmony_ci        }
4468bf80f4bSopenharmony_ci        return *this;
4478bf80f4bSopenharmony_ci    }
4488bf80f4bSopenharmony_ci
4498bf80f4bSopenharmony_ci    string_view substr(size_type pos = 0, size_type count = npos) const
4508bf80f4bSopenharmony_ci    {
4518bf80f4bSopenharmony_ci        return string_view(*this).substr(pos, count);
4528bf80f4bSopenharmony_ci    }
4538bf80f4bSopenharmony_ci
4548bf80f4bSopenharmony_ci    basic_string& erase()
4558bf80f4bSopenharmony_ci    {
4568bf80f4bSopenharmony_ci        return erase(0, npos);
4578bf80f4bSopenharmony_ci    }
4588bf80f4bSopenharmony_ci
4598bf80f4bSopenharmony_ci    basic_string& erase(const size_type off)
4608bf80f4bSopenharmony_ci    {
4618bf80f4bSopenharmony_ci        return erase(off, npos);
4628bf80f4bSopenharmony_ci    }
4638bf80f4bSopenharmony_ci
4648bf80f4bSopenharmony_ci    basic_string& erase(const size_type off, size_type count)
4658bf80f4bSopenharmony_ci    {
4668bf80f4bSopenharmony_ci        const auto oldSize = size();
4678bf80f4bSopenharmony_ci        if (off > oldSize) {
4688bf80f4bSopenharmony_ci            return *this;
4698bf80f4bSopenharmony_ci        } else if (count == 0) {
4708bf80f4bSopenharmony_ci            return *this;
4718bf80f4bSopenharmony_ci        } else {
4728bf80f4bSopenharmony_ci            auto newSize = oldSize;
4738bf80f4bSopenharmony_ci            const auto dst = data() + off;
4748bf80f4bSopenharmony_ci            if (count < (oldSize - off)) {
4758bf80f4bSopenharmony_ci                const auto dstSize = capacity() - off;
4768bf80f4bSopenharmony_ci                const auto src = dst + count;
4778bf80f4bSopenharmony_ci                const auto srcSize = oldSize + 1 - off - count;
4788bf80f4bSopenharmony_ci                // dst and src are valid, dst < src, and srcSize doesn't exceed capacity.
4798bf80f4bSopenharmony_ci                MoveData(dst, dstSize * sizeof(value_type), src, srcSize * sizeof(value_type));
4808bf80f4bSopenharmony_ci                newSize -= count;
4818bf80f4bSopenharmony_ci            } else {
4828bf80f4bSopenharmony_ci                *dst = '\0';
4838bf80f4bSopenharmony_ci                newSize = off;
4848bf80f4bSopenharmony_ci            }
4858bf80f4bSopenharmony_ci
4868bf80f4bSopenharmony_ci            set_size(newSize);
4878bf80f4bSopenharmony_ci        }
4888bf80f4bSopenharmony_ci        return *this;
4898bf80f4bSopenharmony_ci    }
4908bf80f4bSopenharmony_ci
4918bf80f4bSopenharmony_ci    iterator erase(const_iterator pos)
4928bf80f4bSopenharmony_ci    {
4938bf80f4bSopenharmony_ci        const auto offset = pos - cbegin();
4948bf80f4bSopenharmony_ci        const auto count = 1U;
4958bf80f4bSopenharmony_ci        erase(static_cast<size_type>(offset), count);
4968bf80f4bSopenharmony_ci
4978bf80f4bSopenharmony_ci        return iterator(begin() + offset);
4988bf80f4bSopenharmony_ci    }
4998bf80f4bSopenharmony_ci
5008bf80f4bSopenharmony_ci    iterator erase(const_iterator first, const_iterator last)
5018bf80f4bSopenharmony_ci    {
5028bf80f4bSopenharmony_ci        const auto offset = first - cbegin();
5038bf80f4bSopenharmony_ci        const auto count = static_cast<size_type>(last - first);
5048bf80f4bSopenharmony_ci        erase(static_cast<size_type>(offset), count);
5058bf80f4bSopenharmony_ci
5068bf80f4bSopenharmony_ci        return iterator(begin() + offset);
5078bf80f4bSopenharmony_ci    }
5088bf80f4bSopenharmony_ci
5098bf80f4bSopenharmony_ci    basic_string& insert(size_type pos, const_pointer str)
5108bf80f4bSopenharmony_ci    {
5118bf80f4bSopenharmony_ci        const auto view = string_view(str);
5128bf80f4bSopenharmony_ci        return insert(pos, view.data(), view.length());
5138bf80f4bSopenharmony_ci    }
5148bf80f4bSopenharmony_ci
5158bf80f4bSopenharmony_ci    basic_string& insert(size_type pos, const_pointer str, size_type n)
5168bf80f4bSopenharmony_ci    {
5178bf80f4bSopenharmony_ci        const auto oldSize = size();
5188bf80f4bSopenharmony_ci        if (pos > oldSize) {
5198bf80f4bSopenharmony_ci            pos = oldSize;
5208bf80f4bSopenharmony_ci        }
5218bf80f4bSopenharmony_ci        const auto newSize = oldSize + n;
5228bf80f4bSopenharmony_ci        if (newSize > capacity()) {
5238bf80f4bSopenharmony_ci            const auto oldPtr = data();
5248bf80f4bSopenharmony_ci            const auto ptr = allocator_.alloc(newSize + 1);
5258bf80f4bSopenharmony_ci            CloneData(ptr, newSize * sizeof(value_type), oldPtr, pos * sizeof(value_type));
5268bf80f4bSopenharmony_ci            CloneData(ptr + pos + n, (newSize - pos - n) * sizeof(value_type), oldPtr + pos,
5278bf80f4bSopenharmony_ci                (oldSize - pos) * sizeof(value_type));
5288bf80f4bSopenharmony_ci            CloneData(ptr + pos, (newSize - pos) * sizeof(value_type), str, n * sizeof(value_type));
5298bf80f4bSopenharmony_ci            ptr[newSize] = '\0';
5308bf80f4bSopenharmony_ci
5318bf80f4bSopenharmony_ci            if (!is_short()) {
5328bf80f4bSopenharmony_ci                allocator_.free(oldPtr);
5338bf80f4bSopenharmony_ci            }
5348bf80f4bSopenharmony_ci
5358bf80f4bSopenharmony_ci            data_.longString.capacity = newSize;
5368bf80f4bSopenharmony_ci            data_.longString.size = newSize;
5378bf80f4bSopenharmony_ci            data_.longString.begin = ptr;
5388bf80f4bSopenharmony_ci            set_short(false);
5398bf80f4bSopenharmony_ci        } else {
5408bf80f4bSopenharmony_ci            auto ptr = data();
5418bf80f4bSopenharmony_ci            if (pos < oldSize) {
5428bf80f4bSopenharmony_ci                auto dst = ptr + newSize;
5438bf80f4bSopenharmony_ci                auto src = ptr + oldSize;
5448bf80f4bSopenharmony_ci                auto count = oldSize + 1 - pos;
5458bf80f4bSopenharmony_ci                while (count--) {
5468bf80f4bSopenharmony_ci                    *dst-- = *src--;
5478bf80f4bSopenharmony_ci                }
5488bf80f4bSopenharmony_ci            }
5498bf80f4bSopenharmony_ci            CloneData(ptr + pos, (newSize - pos) * sizeof(value_type), str, n * sizeof(value_type));
5508bf80f4bSopenharmony_ci            ptr[newSize] = '\0';
5518bf80f4bSopenharmony_ci
5528bf80f4bSopenharmony_ci            set_size(newSize);
5538bf80f4bSopenharmony_ci        }
5548bf80f4bSopenharmony_ci        return *this;
5558bf80f4bSopenharmony_ci    }
5568bf80f4bSopenharmony_ci
5578bf80f4bSopenharmony_ci    basic_string& push_back(value_type a)
5588bf80f4bSopenharmony_ci    {
5598bf80f4bSopenharmony_ci        const auto oldSize = size();
5608bf80f4bSopenharmony_ci        if (size_type cap = capacity(); oldSize == cap) {
5618bf80f4bSopenharmony_ci            if (!grow(1)) {
5628bf80f4bSopenharmony_ci                return *this;
5638bf80f4bSopenharmony_ci            }
5648bf80f4bSopenharmony_ci        }
5658bf80f4bSopenharmony_ci
5668bf80f4bSopenharmony_ci        const auto ptr = data();
5678bf80f4bSopenharmony_ci        ptr[oldSize] = a;
5688bf80f4bSopenharmony_ci        ptr[oldSize + 1] = '\0';
5698bf80f4bSopenharmony_ci        set_size(oldSize + 1);
5708bf80f4bSopenharmony_ci        return *this;
5718bf80f4bSopenharmony_ci    }
5728bf80f4bSopenharmony_ci
5738bf80f4bSopenharmony_ci    basic_string& append(size_type count, value_type a)
5748bf80f4bSopenharmony_ci    {
5758bf80f4bSopenharmony_ci        if (count) {
5768bf80f4bSopenharmony_ci            const auto oldSize = size();
5778bf80f4bSopenharmony_ci            const auto newSize = oldSize + count;
5788bf80f4bSopenharmony_ci            if (size_type cap = capacity(); cap < newSize) {
5798bf80f4bSopenharmony_ci                if (!grow(newSize)) {
5808bf80f4bSopenharmony_ci                    return *this;
5818bf80f4bSopenharmony_ci                }
5828bf80f4bSopenharmony_ci            }
5838bf80f4bSopenharmony_ci
5848bf80f4bSopenharmony_ci            const auto ptr = data();
5858bf80f4bSopenharmony_ci            for (auto i = ptr + oldSize; i != (ptr + newSize); ++i) {
5868bf80f4bSopenharmony_ci                *i = a;
5878bf80f4bSopenharmony_ci            }
5888bf80f4bSopenharmony_ci            ptr[newSize] = '\0';
5898bf80f4bSopenharmony_ci
5908bf80f4bSopenharmony_ci            set_size(newSize);
5918bf80f4bSopenharmony_ci        }
5928bf80f4bSopenharmony_ci        return *this;
5938bf80f4bSopenharmony_ci    }
5948bf80f4bSopenharmony_ci
5958bf80f4bSopenharmony_ci    basic_string& append(const_pointer const a)
5968bf80f4bSopenharmony_ci    {
5978bf80f4bSopenharmony_ci        return append(a, constexpr_strlen(a));
5988bf80f4bSopenharmony_ci    }
5998bf80f4bSopenharmony_ci
6008bf80f4bSopenharmony_ci    basic_string& append(const_pointer const str, size_type count)
6018bf80f4bSopenharmony_ci    {
6028bf80f4bSopenharmony_ci        if (str && count) {
6038bf80f4bSopenharmony_ci            size_type oldSize;
6048bf80f4bSopenharmony_ci            size_type oldCapacity;
6058bf80f4bSopenharmony_ci            pointer dst;
6068bf80f4bSopenharmony_ci            if (is_short()) {
6078bf80f4bSopenharmony_ci                oldSize = shortCapacity - data_.shortString.size;
6088bf80f4bSopenharmony_ci                oldCapacity = shortCapacity;
6098bf80f4bSopenharmony_ci                dst = data_.shortString.begin + 1;
6108bf80f4bSopenharmony_ci            } else {
6118bf80f4bSopenharmony_ci                oldSize = data_.longString.size;
6128bf80f4bSopenharmony_ci                oldCapacity = data_.longString.capacity;
6138bf80f4bSopenharmony_ci                dst = data_.longString.begin;
6148bf80f4bSopenharmony_ci            }
6158bf80f4bSopenharmony_ci
6168bf80f4bSopenharmony_ci            const auto newSize = oldSize + count;
6178bf80f4bSopenharmony_ci            if (oldCapacity < newSize) {
6188bf80f4bSopenharmony_ci                oldCapacity += oldCapacity / 2;
6198bf80f4bSopenharmony_ci                if (!allocate(newSize < oldCapacity ? oldCapacity : newSize)) {
6208bf80f4bSopenharmony_ci                    return *this;
6218bf80f4bSopenharmony_ci                }
6228bf80f4bSopenharmony_ci                dst = data_.longString.begin;
6238bf80f4bSopenharmony_ci                oldCapacity = data_.longString.capacity;
6248bf80f4bSopenharmony_ci            }
6258bf80f4bSopenharmony_ci
6268bf80f4bSopenharmony_ci            // dst and src are valid, oldSize + count is less than capacity.
6278bf80f4bSopenharmony_ci            CloneData(dst + oldSize, oldCapacity * sizeof(value_type), str, count * sizeof(value_type));
6288bf80f4bSopenharmony_ci            dst[newSize] = '\0';
6298bf80f4bSopenharmony_ci            set_size(newSize);
6308bf80f4bSopenharmony_ci        }
6318bf80f4bSopenharmony_ci        return *this;
6328bf80f4bSopenharmony_ci    }
6338bf80f4bSopenharmony_ci
6348bf80f4bSopenharmony_ci    basic_string& append(const string_view& b)
6358bf80f4bSopenharmony_ci    {
6368bf80f4bSopenharmony_ci        return append(b.data(), b.length());
6378bf80f4bSopenharmony_ci    }
6388bf80f4bSopenharmony_ci
6398bf80f4bSopenharmony_ci    basic_string& append(const string_view& b, size_type pos)
6408bf80f4bSopenharmony_ci    {
6418bf80f4bSopenharmony_ci        auto count = b.length();
6428bf80f4bSopenharmony_ci        count = (pos < count) ? (count - pos) : 0;
6438bf80f4bSopenharmony_ci        return append(b.data() + pos, count);
6448bf80f4bSopenharmony_ci    }
6458bf80f4bSopenharmony_ci
6468bf80f4bSopenharmony_ci    basic_string& append(const string_view& b, size_type pos, size_type count)
6478bf80f4bSopenharmony_ci    {
6488bf80f4bSopenharmony_ci        auto const strLen = b.length();
6498bf80f4bSopenharmony_ci        if (pos > strLen) {
6508bf80f4bSopenharmony_ci            count = 0;
6518bf80f4bSopenharmony_ci            pos = strLen ? (strLen - 1) : strLen;
6528bf80f4bSopenharmony_ci        } else if (count == npos) {
6538bf80f4bSopenharmony_ci            count = strLen - pos;
6548bf80f4bSopenharmony_ci        } else if (count > (strLen - pos)) {
6558bf80f4bSopenharmony_ci            count = strLen - pos;
6568bf80f4bSopenharmony_ci        }
6578bf80f4bSopenharmony_ci        return append(b.data() + pos, count);
6588bf80f4bSopenharmony_ci    }
6598bf80f4bSopenharmony_ci
6608bf80f4bSopenharmony_ci    /** compares two strings */
6618bf80f4bSopenharmony_ci    int compare(string_view v) const noexcept
6628bf80f4bSopenharmony_ci    {
6638bf80f4bSopenharmony_ci        return string_view(*this).compare(v);
6648bf80f4bSopenharmony_ci    }
6658bf80f4bSopenharmony_ci
6668bf80f4bSopenharmony_ci    int compare(size_type pos1, size_type count1, string_view v) const
6678bf80f4bSopenharmony_ci    {
6688bf80f4bSopenharmony_ci        return substr(pos1, count1).compare(v);
6698bf80f4bSopenharmony_ci    }
6708bf80f4bSopenharmony_ci
6718bf80f4bSopenharmony_ci    int compare(size_type pos1, size_type count1, string_view v, size_type pos2, size_type count2) const
6728bf80f4bSopenharmony_ci    {
6738bf80f4bSopenharmony_ci        return substr(pos1, count1).compare(v.substr(pos2, count2));
6748bf80f4bSopenharmony_ci    }
6758bf80f4bSopenharmony_ci
6768bf80f4bSopenharmony_ci    int compare(CharT const* const s) const
6778bf80f4bSopenharmony_ci    {
6788bf80f4bSopenharmony_ci        return string_view(*this).compare(s);
6798bf80f4bSopenharmony_ci    }
6808bf80f4bSopenharmony_ci
6818bf80f4bSopenharmony_ci    int compare(size_type pos1, size_type count1, CharT const* const s) const
6828bf80f4bSopenharmony_ci    {
6838bf80f4bSopenharmony_ci        return substr(pos1, count1).compare(s);
6848bf80f4bSopenharmony_ci    }
6858bf80f4bSopenharmony_ci
6868bf80f4bSopenharmony_ci    int compare(size_type pos1, size_type count1, CharT const* const s, size_type count2) const
6878bf80f4bSopenharmony_ci    {
6888bf80f4bSopenharmony_ci        return substr(pos1, count1).compare(basic_string_view(s, count2));
6898bf80f4bSopenharmony_ci    }
6908bf80f4bSopenharmony_ci
6918bf80f4bSopenharmony_ci    /** find substring in the view */
6928bf80f4bSopenharmony_ci    size_type find(const value_type str, size_type pos = 0) const noexcept
6938bf80f4bSopenharmony_ci    {
6948bf80f4bSopenharmony_ci        return string_view(*this).find(str, pos);
6958bf80f4bSopenharmony_ci    }
6968bf80f4bSopenharmony_ci
6978bf80f4bSopenharmony_ci    size_type find(const string_view& str, size_type pos = 0) const noexcept
6988bf80f4bSopenharmony_ci    {
6998bf80f4bSopenharmony_ci        return string_view(*this).find(str, pos);
7008bf80f4bSopenharmony_ci    }
7018bf80f4bSopenharmony_ci
7028bf80f4bSopenharmony_ci    /* find the last occurrence of a substring in the view */
7038bf80f4bSopenharmony_ci    size_type rfind(const value_type str, size_type pos = npos) const noexcept
7048bf80f4bSopenharmony_ci    {
7058bf80f4bSopenharmony_ci        return string_view(*this).rfind(str, pos);
7068bf80f4bSopenharmony_ci    }
7078bf80f4bSopenharmony_ci
7088bf80f4bSopenharmony_ci    size_type rfind(const string_view& str, size_type pos = npos) const noexcept
7098bf80f4bSopenharmony_ci    {
7108bf80f4bSopenharmony_ci        return string_view(*this).rfind(str, pos);
7118bf80f4bSopenharmony_ci    }
7128bf80f4bSopenharmony_ci
7138bf80f4bSopenharmony_ci    /* find first occurance of characters in the view */
7148bf80f4bSopenharmony_ci    size_type find_first_of(const string_view& str, size_type pos = 0) const noexcept
7158bf80f4bSopenharmony_ci    {
7168bf80f4bSopenharmony_ci        return string_view(*this).find_first_of(str, pos);
7178bf80f4bSopenharmony_ci    }
7188bf80f4bSopenharmony_ci
7198bf80f4bSopenharmony_ci    size_type find_first_of(value_type ch, size_type pos = 0) const noexcept
7208bf80f4bSopenharmony_ci    {
7218bf80f4bSopenharmony_ci        return string_view(*this).find_first_of(ch, pos);
7228bf80f4bSopenharmony_ci    }
7238bf80f4bSopenharmony_ci
7248bf80f4bSopenharmony_ci    /* find last occurrence of characters in the view */
7258bf80f4bSopenharmony_ci    size_type find_last_of(const string_view& str, size_type pos = npos) const noexcept
7268bf80f4bSopenharmony_ci    {
7278bf80f4bSopenharmony_ci        return string_view(*this).find_last_of(str, pos);
7288bf80f4bSopenharmony_ci    }
7298bf80f4bSopenharmony_ci
7308bf80f4bSopenharmony_ci    size_type find_last_of(value_type ch, size_type pos = npos) const noexcept
7318bf80f4bSopenharmony_ci    {
7328bf80f4bSopenharmony_ci        return string_view(*this).find_last_of(ch, pos);
7338bf80f4bSopenharmony_ci    }
7348bf80f4bSopenharmony_ci
7358bf80f4bSopenharmony_ci    /* checks if the string starts with the given prefix */
7368bf80f4bSopenharmony_ci    bool starts_with(basic_string_view<CharT> sv) const noexcept
7378bf80f4bSopenharmony_ci    {
7388bf80f4bSopenharmony_ci        return operator basic_string_view<CharT>().starts_with(sv);
7398bf80f4bSopenharmony_ci    }
7408bf80f4bSopenharmony_ci
7418bf80f4bSopenharmony_ci    bool starts_with(CharT ch) const noexcept
7428bf80f4bSopenharmony_ci    {
7438bf80f4bSopenharmony_ci        return operator basic_string_view<CharT>().starts_with(ch);
7448bf80f4bSopenharmony_ci    }
7458bf80f4bSopenharmony_ci
7468bf80f4bSopenharmony_ci    bool starts_with(const CharT* s) const
7478bf80f4bSopenharmony_ci    {
7488bf80f4bSopenharmony_ci        return operator basic_string_view<CharT>().starts_with(s);
7498bf80f4bSopenharmony_ci    }
7508bf80f4bSopenharmony_ci
7518bf80f4bSopenharmony_ci    /* checks if the string ends with the given suffix */
7528bf80f4bSopenharmony_ci    bool ends_with(basic_string_view<CharT> sv) const noexcept
7538bf80f4bSopenharmony_ci    {
7548bf80f4bSopenharmony_ci        return operator basic_string_view<CharT>().ends_with(sv);
7558bf80f4bSopenharmony_ci    }
7568bf80f4bSopenharmony_ci
7578bf80f4bSopenharmony_ci    bool ends_with(CharT ch) const noexcept
7588bf80f4bSopenharmony_ci    {
7598bf80f4bSopenharmony_ci        return operator basic_string_view<CharT>().ends_with(ch);
7608bf80f4bSopenharmony_ci    }
7618bf80f4bSopenharmony_ci
7628bf80f4bSopenharmony_ci    bool ends_with(const CharT* s) const
7638bf80f4bSopenharmony_ci    {
7648bf80f4bSopenharmony_ci        return operator basic_string_view<CharT>().ends_with(s);
7658bf80f4bSopenharmony_ci    }
7668bf80f4bSopenharmony_ci    /* find first absence of characters
7678bf80f4bSopenharmony_ci    find_first_not_of
7688bf80f4bSopenharmony_ci
7698bf80f4bSopenharmony_ci    find last absence of characters
7708bf80f4bSopenharmony_ci    find_last_not_of */
7718bf80f4bSopenharmony_ci
7728bf80f4bSopenharmony_ci    basic_string& upper()
7738bf80f4bSopenharmony_ci    {
7748bf80f4bSopenharmony_ci        for (size_type i = 0; i < length(); i++) {
7758bf80f4bSopenharmony_ci            if (data()[i] >= 'a' && data()[i] <= 'z') {
7768bf80f4bSopenharmony_ci                data()[i] = (data()[i] - 'a') + 'A';
7778bf80f4bSopenharmony_ci            }
7788bf80f4bSopenharmony_ci        }
7798bf80f4bSopenharmony_ci        return *this;
7808bf80f4bSopenharmony_ci    }
7818bf80f4bSopenharmony_ci
7828bf80f4bSopenharmony_ci    basic_string& lower()
7838bf80f4bSopenharmony_ci    {
7848bf80f4bSopenharmony_ci        for (size_type i = 0; i < length(); i++) {
7858bf80f4bSopenharmony_ci            if (data()[i] >= 'A' && data()[i] <= 'Z') {
7868bf80f4bSopenharmony_ci                data()[i] = (data()[i] - 'A') + 'a';
7878bf80f4bSopenharmony_ci            }
7888bf80f4bSopenharmony_ci        }
7898bf80f4bSopenharmony_ci        return *this;
7908bf80f4bSopenharmony_ci    }
7918bf80f4bSopenharmony_ci
7928bf80f4bSopenharmony_ci    basic_string toUpper() const
7938bf80f4bSopenharmony_ci    {
7948bf80f4bSopenharmony_ci        basic_string res;
7958bf80f4bSopenharmony_ci        res.resize(length());
7968bf80f4bSopenharmony_ci        for (size_type i = 0; i < length(); i++) {
7978bf80f4bSopenharmony_ci            if (data()[i] >= 'a' && data()[i] <= 'z') {
7988bf80f4bSopenharmony_ci                res[i] = (data()[i] - 'a') + 'A';
7998bf80f4bSopenharmony_ci            } else {
8008bf80f4bSopenharmony_ci                res[i] = data()[i];
8018bf80f4bSopenharmony_ci            }
8028bf80f4bSopenharmony_ci        }
8038bf80f4bSopenharmony_ci        return res;
8048bf80f4bSopenharmony_ci    }
8058bf80f4bSopenharmony_ci
8068bf80f4bSopenharmony_ci    basic_string toLower() const
8078bf80f4bSopenharmony_ci    {
8088bf80f4bSopenharmony_ci        basic_string res;
8098bf80f4bSopenharmony_ci        res.resize(length());
8108bf80f4bSopenharmony_ci        for (size_type i = 0; i < length(); i++) {
8118bf80f4bSopenharmony_ci            if (data()[i] >= 'A' && data()[i] <= 'Z') {
8128bf80f4bSopenharmony_ci                res[i] = (data()[i] - 'A') + 'a';
8138bf80f4bSopenharmony_ci            } else {
8148bf80f4bSopenharmony_ci                res[i] = data()[i];
8158bf80f4bSopenharmony_ci            }
8168bf80f4bSopenharmony_ci        }
8178bf80f4bSopenharmony_ci        return res;
8188bf80f4bSopenharmony_ci    }
8198bf80f4bSopenharmony_ci
8208bf80f4bSopenharmony_ciprotected:
8218bf80f4bSopenharmony_ci    inline bool is_short() const
8228bf80f4bSopenharmony_ci    {
8238bf80f4bSopenharmony_ci        return data_.longString.isShort;
8248bf80f4bSopenharmony_ci    }
8258bf80f4bSopenharmony_ci
8268bf80f4bSopenharmony_ci    inline void set_short(bool isShort)
8278bf80f4bSopenharmony_ci    {
8288bf80f4bSopenharmony_ci        data_.longString.isShort = isShort;
8298bf80f4bSopenharmony_ci    }
8308bf80f4bSopenharmony_ci
8318bf80f4bSopenharmony_ci    inline void set_size(size_type size)
8328bf80f4bSopenharmony_ci    {
8338bf80f4bSopenharmony_ci        if (is_short()) {
8348bf80f4bSopenharmony_ci            data_.shortString.size = static_cast<value_type>(shortCapacity - size);
8358bf80f4bSopenharmony_ci        } else {
8368bf80f4bSopenharmony_ci            data_.longString.size = size;
8378bf80f4bSopenharmony_ci        }
8388bf80f4bSopenharmony_ci    }
8398bf80f4bSopenharmony_ci
8408bf80f4bSopenharmony_ci    inline bool grow(const size_type minCapacity)
8418bf80f4bSopenharmony_ci    {
8428bf80f4bSopenharmony_ci        auto cap = capacity();
8438bf80f4bSopenharmony_ci        cap += cap / 2;
8448bf80f4bSopenharmony_ci        return allocate(minCapacity < cap ? cap : minCapacity);
8458bf80f4bSopenharmony_ci    }
8468bf80f4bSopenharmony_ci
8478bf80f4bSopenharmony_ci    bool allocate(size_type size)
8488bf80f4bSopenharmony_ci    {
8498bf80f4bSopenharmony_ci        // setup new storage with old data
8508bf80f4bSopenharmony_ci        if (auto ptr = allocator_.alloc(size + 1); ptr) {
8518bf80f4bSopenharmony_ci            const auto oldSize = length();
8528bf80f4bSopenharmony_ci            if (oldSize) {
8538bf80f4bSopenharmony_ci                CloneData(ptr, size * sizeof(value_type), data(), oldSize * sizeof(value_type));
8548bf80f4bSopenharmony_ci            }
8558bf80f4bSopenharmony_ci            ptr[oldSize] = '\0';
8568bf80f4bSopenharmony_ci
8578bf80f4bSopenharmony_ci            if (!is_short()) {
8588bf80f4bSopenharmony_ci                allocator_.free(data_.longString.begin);
8598bf80f4bSopenharmony_ci            }
8608bf80f4bSopenharmony_ci
8618bf80f4bSopenharmony_ci            set_short(false);
8628bf80f4bSopenharmony_ci            data_.longString.capacity = size;
8638bf80f4bSopenharmony_ci            data_.longString.size = oldSize;
8648bf80f4bSopenharmony_ci            data_.longString.begin = ptr;
8658bf80f4bSopenharmony_ci            return true;
8668bf80f4bSopenharmony_ci        }
8678bf80f4bSopenharmony_ci        return false;
8688bf80f4bSopenharmony_ci    }
8698bf80f4bSopenharmony_ci
8708bf80f4bSopenharmony_ci    void construct(const_pointer const str, size_type count)
8718bf80f4bSopenharmony_ci    {
8728bf80f4bSopenharmony_ci        if (!str || count == 0) {
8738bf80f4bSopenharmony_ci            set_short(true);
8748bf80f4bSopenharmony_ci            data_.shortString.begin[1] = '\0';
8758bf80f4bSopenharmony_ci            data_.shortString.size = static_cast<value_type>(shortCapacity);
8768bf80f4bSopenharmony_ci        } else {
8778bf80f4bSopenharmony_ci            pointer dst;
8788bf80f4bSopenharmony_ci            if (count <= shortCapacity) {
8798bf80f4bSopenharmony_ci                dst = data_.shortString.begin + 1;
8808bf80f4bSopenharmony_ci                set_short(true);
8818bf80f4bSopenharmony_ci                data_.shortString.size = static_cast<value_type>(shortCapacity - count);
8828bf80f4bSopenharmony_ci            } else {
8838bf80f4bSopenharmony_ci                dst = allocator_.alloc(count + 1);
8848bf80f4bSopenharmony_ci                if (!dst) {
8858bf80f4bSopenharmony_ci                    set_short(true);
8868bf80f4bSopenharmony_ci                    data_.shortString.begin[1] = '\0';
8878bf80f4bSopenharmony_ci                    data_.shortString.size = static_cast<value_type>(shortCapacity);
8888bf80f4bSopenharmony_ci                    return;
8898bf80f4bSopenharmony_ci                }
8908bf80f4bSopenharmony_ci                set_short(false);
8918bf80f4bSopenharmony_ci                data_.longString.capacity = count;
8928bf80f4bSopenharmony_ci                data_.longString.size = count;
8938bf80f4bSopenharmony_ci                data_.longString.begin = dst;
8948bf80f4bSopenharmony_ci            }
8958bf80f4bSopenharmony_ci            // destination and source are valid and the allocation sizes are for at least count characters.
8968bf80f4bSopenharmony_ci            CloneData(dst, count * sizeof(value_type), str, count * sizeof(value_type));
8978bf80f4bSopenharmony_ci            dst[count] = '\0';
8988bf80f4bSopenharmony_ci        }
8998bf80f4bSopenharmony_ci    }
9008bf80f4bSopenharmony_ci
9018bf80f4bSopenharmony_ci    struct LongString {
9028bf80f4bSopenharmony_ci        bool isShort;
9038bf80f4bSopenharmony_ci        size_type capacity;
9048bf80f4bSopenharmony_ci        size_type size;
9058bf80f4bSopenharmony_ci        pointer begin;
9068bf80f4bSopenharmony_ci    };
9078bf80f4bSopenharmony_ci
9088bf80f4bSopenharmony_ci    // short string capacity: one value_type for the size and another for isShort
9098bf80f4bSopenharmony_ci    static constexpr auto shortCapacity = (sizeof(LongString) - 2u * sizeof(value_type)) / sizeof(value_type);
9108bf80f4bSopenharmony_ci
9118bf80f4bSopenharmony_ci    struct ShortString {
9128bf80f4bSopenharmony_ci        // add one for isShort in the begining
9138bf80f4bSopenharmony_ci        value_type begin[shortCapacity + 1];
9148bf80f4bSopenharmony_ci        value_type size;
9158bf80f4bSopenharmony_ci    };
9168bf80f4bSopenharmony_ci
9178bf80f4bSopenharmony_ci    union Data {
9188bf80f4bSopenharmony_ci        LongString longString;
9198bf80f4bSopenharmony_ci        ShortString shortString;
9208bf80f4bSopenharmony_ci    };
9218bf80f4bSopenharmony_ci
9228bf80f4bSopenharmony_ci    // Wrapper to create a "re-seatable" reference.
9238bf80f4bSopenharmony_ci    class Wrapper {
9248bf80f4bSopenharmony_ci    public:
9258bf80f4bSopenharmony_ci        inline Wrapper(allocator& a) : allocator_(&a) {}
9268bf80f4bSopenharmony_ci        inline Wrapper& operator=(allocator& a)
9278bf80f4bSopenharmony_ci        {
9288bf80f4bSopenharmony_ci            allocator_ = &a;
9298bf80f4bSopenharmony_ci            return *this;
9308bf80f4bSopenharmony_ci        }
9318bf80f4bSopenharmony_ci        inline pointer alloc(size_type size)
9328bf80f4bSopenharmony_ci        {
9338bf80f4bSopenharmony_ci            if ((allocator_) && (allocator_->alloc)) {
9348bf80f4bSopenharmony_ci                return static_cast<pointer>(allocator_->alloc(allocator_->instance, sizeof(value_type) * size));
9358bf80f4bSopenharmony_ci            }
9368bf80f4bSopenharmony_ci            return nullptr;
9378bf80f4bSopenharmony_ci        }
9388bf80f4bSopenharmony_ci        inline void free(void* ptr)
9398bf80f4bSopenharmony_ci        {
9408bf80f4bSopenharmony_ci            if ((allocator_) && (allocator_->free)) {
9418bf80f4bSopenharmony_ci                allocator_->free(allocator_->instance, ptr);
9428bf80f4bSopenharmony_ci            }
9438bf80f4bSopenharmony_ci        }
9448bf80f4bSopenharmony_ci        allocator& get()
9458bf80f4bSopenharmony_ci        {
9468bf80f4bSopenharmony_ci            BASE_ASSERT(allocator_ != nullptr);
9478bf80f4bSopenharmony_ci            return *allocator_;
9488bf80f4bSopenharmony_ci        }
9498bf80f4bSopenharmony_ci        const allocator& get() const
9508bf80f4bSopenharmony_ci        {
9518bf80f4bSopenharmony_ci            BASE_ASSERT(allocator_ != nullptr);
9528bf80f4bSopenharmony_ci            return *allocator_;
9538bf80f4bSopenharmony_ci        }
9548bf80f4bSopenharmony_ci
9558bf80f4bSopenharmony_ci    private:
9568bf80f4bSopenharmony_ci        allocator* allocator_ { nullptr };
9578bf80f4bSopenharmony_ci    } allocator_;
9588bf80f4bSopenharmony_ci    Data data_;
9598bf80f4bSopenharmony_ci};
9608bf80f4bSopenharmony_ci
9618bf80f4bSopenharmony_ciinline string operator+(const string& a, const string& b)
9628bf80f4bSopenharmony_ci{
9638bf80f4bSopenharmony_ci    string res;
9648bf80f4bSopenharmony_ci    res.reserve(a.length() + b.length());
9658bf80f4bSopenharmony_ci    res = a;
9668bf80f4bSopenharmony_ci    res += b;
9678bf80f4bSopenharmony_ci    return res;
9688bf80f4bSopenharmony_ci}
9698bf80f4bSopenharmony_ci
9708bf80f4bSopenharmony_ciinline string operator+(const string& a, const char* b)
9718bf80f4bSopenharmony_ci{
9728bf80f4bSopenharmony_ci    string res;
9738bf80f4bSopenharmony_ci    const auto sv = string_view(b);
9748bf80f4bSopenharmony_ci    res.reserve(a.length() + sv.length());
9758bf80f4bSopenharmony_ci    res = a;
9768bf80f4bSopenharmony_ci    res += sv;
9778bf80f4bSopenharmony_ci    return res;
9788bf80f4bSopenharmony_ci}
9798bf80f4bSopenharmony_ci
9808bf80f4bSopenharmony_ciinline string operator+(const string& a, char b)
9818bf80f4bSopenharmony_ci{
9828bf80f4bSopenharmony_ci    string res;
9838bf80f4bSopenharmony_ci    res.reserve(a.length() + 1);
9848bf80f4bSopenharmony_ci    res = a;
9858bf80f4bSopenharmony_ci    res += b;
9868bf80f4bSopenharmony_ci    return res;
9878bf80f4bSopenharmony_ci}
9888bf80f4bSopenharmony_ci
9898bf80f4bSopenharmony_ciinline string operator+(const char* a, const string& b)
9908bf80f4bSopenharmony_ci{
9918bf80f4bSopenharmony_ci    string res;
9928bf80f4bSopenharmony_ci    const auto sv = string_view(a);
9938bf80f4bSopenharmony_ci    res.reserve(sv.length() + b.length());
9948bf80f4bSopenharmony_ci    res = sv;
9958bf80f4bSopenharmony_ci    res += b;
9968bf80f4bSopenharmony_ci    return res;
9978bf80f4bSopenharmony_ci}
9988bf80f4bSopenharmony_ci
9998bf80f4bSopenharmony_ciinline string operator+(char a, const string& b)
10008bf80f4bSopenharmony_ci{
10018bf80f4bSopenharmony_ci    string res;
10028bf80f4bSopenharmony_ci    res.reserve(1 + b.length());
10038bf80f4bSopenharmony_ci    res = a;
10048bf80f4bSopenharmony_ci    res += b;
10058bf80f4bSopenharmony_ci    return res;
10068bf80f4bSopenharmony_ci}
10078bf80f4bSopenharmony_ci
10088bf80f4bSopenharmony_ciinline string operator+(const string_view& a, const string_view& b)
10098bf80f4bSopenharmony_ci{
10108bf80f4bSopenharmony_ci    string res;
10118bf80f4bSopenharmony_ci    res.reserve(a.length() + b.length());
10128bf80f4bSopenharmony_ci    res = a;
10138bf80f4bSopenharmony_ci    res += b;
10148bf80f4bSopenharmony_ci    return res;
10158bf80f4bSopenharmony_ci}
10168bf80f4bSopenharmony_ci
10178bf80f4bSopenharmony_ciinline string operator+(const string_view& a, char b)
10188bf80f4bSopenharmony_ci{
10198bf80f4bSopenharmony_ci    string res;
10208bf80f4bSopenharmony_ci    res.reserve(a.length() + 1);
10218bf80f4bSopenharmony_ci    res = a;
10228bf80f4bSopenharmony_ci    res += b;
10238bf80f4bSopenharmony_ci    return res;
10248bf80f4bSopenharmony_ci}
10258bf80f4bSopenharmony_ci
10268bf80f4bSopenharmony_ciinline string operator+(const char a, string_view& b)
10278bf80f4bSopenharmony_ci{
10288bf80f4bSopenharmony_ci    string res;
10298bf80f4bSopenharmony_ci    res.reserve(b.length() + 1);
10308bf80f4bSopenharmony_ci    res = a;
10318bf80f4bSopenharmony_ci    res += b;
10328bf80f4bSopenharmony_ci    return res;
10338bf80f4bSopenharmony_ci}
10348bf80f4bSopenharmony_ci
10358bf80f4bSopenharmony_ciinline string operator+(string&& a, string&& b)
10368bf80f4bSopenharmony_ci{
10378bf80f4bSopenharmony_ci    if (a.capacity() >= b.capacity()) {
10388bf80f4bSopenharmony_ci        return move(a.append(b));
10398bf80f4bSopenharmony_ci    } else {
10408bf80f4bSopenharmony_ci        return move(b.insert(0, a.data(), a.size()));
10418bf80f4bSopenharmony_ci    }
10428bf80f4bSopenharmony_ci}
10438bf80f4bSopenharmony_ci
10448bf80f4bSopenharmony_ciinline string operator+(string&& a, const char* b)
10458bf80f4bSopenharmony_ci{
10468bf80f4bSopenharmony_ci    return move(a.append(b));
10478bf80f4bSopenharmony_ci}
10488bf80f4bSopenharmony_ci
10498bf80f4bSopenharmony_ciinline string operator+(string&& a, char b)
10508bf80f4bSopenharmony_ci{
10518bf80f4bSopenharmony_ci    return move(a.push_back(b));
10528bf80f4bSopenharmony_ci}
10538bf80f4bSopenharmony_ci
10548bf80f4bSopenharmony_ciinline string operator+(const char* a, string&& b)
10558bf80f4bSopenharmony_ci{
10568bf80f4bSopenharmony_ci    return move(b.insert(0, a));
10578bf80f4bSopenharmony_ci}
10588bf80f4bSopenharmony_ci
10598bf80f4bSopenharmony_ciinline string operator+(char a, string&& b)
10608bf80f4bSopenharmony_ci{
10618bf80f4bSopenharmony_ci    return move(b.insert(0, &a, 1));
10628bf80f4bSopenharmony_ci}
10638bf80f4bSopenharmony_ci
10648bf80f4bSopenharmony_citemplate<class CharT>
10658bf80f4bSopenharmony_ciinline bool operator==(const basic_string<CharT>& lhs, const basic_string<CharT>& rhs) noexcept
10668bf80f4bSopenharmony_ci{
10678bf80f4bSopenharmony_ci    return string_view(lhs) == string_view(rhs);
10688bf80f4bSopenharmony_ci}
10698bf80f4bSopenharmony_ci
10708bf80f4bSopenharmony_citemplate<class CharT>
10718bf80f4bSopenharmony_ciinline bool operator==(const basic_string<CharT>& lhs, const CharT* const rhs) noexcept
10728bf80f4bSopenharmony_ci{
10738bf80f4bSopenharmony_ci    return string_view(lhs) == rhs;
10748bf80f4bSopenharmony_ci}
10758bf80f4bSopenharmony_ci
10768bf80f4bSopenharmony_citemplate<class CharT>
10778bf80f4bSopenharmony_ciinline bool operator==(const CharT* const lhs, const basic_string<CharT>& rhs) noexcept
10788bf80f4bSopenharmony_ci{
10798bf80f4bSopenharmony_ci    return lhs == string_view(rhs);
10808bf80f4bSopenharmony_ci}
10818bf80f4bSopenharmony_ci
10828bf80f4bSopenharmony_citemplate<class CharT>
10838bf80f4bSopenharmony_ciinline bool operator!=(const basic_string<CharT>& lhs, const basic_string<CharT>& rhs) noexcept
10848bf80f4bSopenharmony_ci{
10858bf80f4bSopenharmony_ci    return string_view(lhs) != string_view(rhs);
10868bf80f4bSopenharmony_ci}
10878bf80f4bSopenharmony_ci
10888bf80f4bSopenharmony_citemplate<class CharT>
10898bf80f4bSopenharmony_ciinline bool operator!=(const basic_string<CharT>& lhs, const CharT* const rhs) noexcept
10908bf80f4bSopenharmony_ci{
10918bf80f4bSopenharmony_ci    return string_view(lhs) != rhs;
10928bf80f4bSopenharmony_ci}
10938bf80f4bSopenharmony_ci
10948bf80f4bSopenharmony_citemplate<class CharT>
10958bf80f4bSopenharmony_ciinline bool operator!=(const CharT* const lhs, const basic_string<CharT>& rhs) noexcept
10968bf80f4bSopenharmony_ci{
10978bf80f4bSopenharmony_ci    return lhs != string_view(rhs);
10988bf80f4bSopenharmony_ci}
10998bf80f4bSopenharmony_ci
11008bf80f4bSopenharmony_citemplate<class CharT>
11018bf80f4bSopenharmony_ciinline bool operator<(const basic_string<CharT>& lhs, const basic_string<CharT>& rhs) noexcept
11028bf80f4bSopenharmony_ci{
11038bf80f4bSopenharmony_ci    return string_view(lhs) < string_view(rhs);
11048bf80f4bSopenharmony_ci}
11058bf80f4bSopenharmony_ci
11068bf80f4bSopenharmony_citemplate<class CharT>
11078bf80f4bSopenharmony_ciinline bool operator<(const basic_string<CharT>& lhs, const CharT* const rhs) noexcept
11088bf80f4bSopenharmony_ci{
11098bf80f4bSopenharmony_ci    return string_view(lhs) < rhs;
11108bf80f4bSopenharmony_ci}
11118bf80f4bSopenharmony_ci
11128bf80f4bSopenharmony_citemplate<class CharT>
11138bf80f4bSopenharmony_ciinline bool operator<(const CharT* const lhs, const basic_string<CharT>& rhs) noexcept
11148bf80f4bSopenharmony_ci{
11158bf80f4bSopenharmony_ci    return lhs < string_view(rhs);
11168bf80f4bSopenharmony_ci}
11178bf80f4bSopenharmony_ci
11188bf80f4bSopenharmony_citemplate<class CharT>
11198bf80f4bSopenharmony_ciinline bool operator<=(const basic_string<CharT>& lhs, const basic_string<CharT>& rhs) noexcept
11208bf80f4bSopenharmony_ci{
11218bf80f4bSopenharmony_ci    return string_view(lhs) <= string_view(rhs);
11228bf80f4bSopenharmony_ci}
11238bf80f4bSopenharmony_ci
11248bf80f4bSopenharmony_citemplate<class CharT>
11258bf80f4bSopenharmony_ciinline bool operator<=(const basic_string<CharT>& lhs, const CharT* const rhs) noexcept
11268bf80f4bSopenharmony_ci{
11278bf80f4bSopenharmony_ci    return string_view(lhs) <= rhs;
11288bf80f4bSopenharmony_ci}
11298bf80f4bSopenharmony_ci
11308bf80f4bSopenharmony_citemplate<class CharT>
11318bf80f4bSopenharmony_ciinline bool operator<=(const CharT* const lhs, const basic_string<CharT>& rhs) noexcept
11328bf80f4bSopenharmony_ci{
11338bf80f4bSopenharmony_ci    return lhs <= string_view(rhs);
11348bf80f4bSopenharmony_ci}
11358bf80f4bSopenharmony_ci
11368bf80f4bSopenharmony_citemplate<class CharT>
11378bf80f4bSopenharmony_ciinline bool operator>(const basic_string<CharT>& lhs, const basic_string<CharT>& rhs) noexcept
11388bf80f4bSopenharmony_ci{
11398bf80f4bSopenharmony_ci    return string_view(lhs) > string_view(rhs);
11408bf80f4bSopenharmony_ci}
11418bf80f4bSopenharmony_ci
11428bf80f4bSopenharmony_citemplate<class CharT>
11438bf80f4bSopenharmony_ciinline bool operator>(const basic_string<CharT>& lhs, const CharT* const rhs) noexcept
11448bf80f4bSopenharmony_ci{
11458bf80f4bSopenharmony_ci    return string_view(lhs) > rhs;
11468bf80f4bSopenharmony_ci}
11478bf80f4bSopenharmony_ci
11488bf80f4bSopenharmony_citemplate<class CharT>
11498bf80f4bSopenharmony_ciinline bool operator>(const CharT* const lhs, const basic_string<CharT>& rhs) noexcept
11508bf80f4bSopenharmony_ci{
11518bf80f4bSopenharmony_ci    return lhs > string_view(rhs);
11528bf80f4bSopenharmony_ci}
11538bf80f4bSopenharmony_ci
11548bf80f4bSopenharmony_citemplate<class CharT>
11558bf80f4bSopenharmony_ciinline bool operator>=(const basic_string<CharT>& lhs, const basic_string<CharT>& rhs) noexcept
11568bf80f4bSopenharmony_ci{
11578bf80f4bSopenharmony_ci    return string_view(lhs) >= string_view(rhs);
11588bf80f4bSopenharmony_ci}
11598bf80f4bSopenharmony_ci
11608bf80f4bSopenharmony_citemplate<class CharT>
11618bf80f4bSopenharmony_ciinline bool operator>=(const basic_string<CharT>& lhs, const CharT* const rhs) noexcept
11628bf80f4bSopenharmony_ci{
11638bf80f4bSopenharmony_ci    return string_view(lhs) >= rhs;
11648bf80f4bSopenharmony_ci}
11658bf80f4bSopenharmony_ci
11668bf80f4bSopenharmony_citemplate<class CharT>
11678bf80f4bSopenharmony_ciinline bool operator>=(const CharT* const lhs, const basic_string<CharT>& rhs) noexcept
11688bf80f4bSopenharmony_ci{
11698bf80f4bSopenharmony_ci    return lhs >= string_view(rhs);
11708bf80f4bSopenharmony_ci}
11718bf80f4bSopenharmony_ci
11728bf80f4bSopenharmony_citemplate<typename T>
11738bf80f4bSopenharmony_ciuint64_t hash(const T&);
11748bf80f4bSopenharmony_ci
11758bf80f4bSopenharmony_citemplate<>
11768bf80f4bSopenharmony_ciinline uint64_t hash(const string& value)
11778bf80f4bSopenharmony_ci{
11788bf80f4bSopenharmony_ci    return BASE_NS::FNV1aHash(value.data(), value.size());
11798bf80f4bSopenharmony_ci}
11808bf80f4bSopenharmony_ciBASE_END_NAMESPACE()
11818bf80f4bSopenharmony_ci
11828bf80f4bSopenharmony_ci#endif // API_BASE_CONTAINERS_STRING_H
1183