LCOV - code coverage report
Current view: top level - core/core/memory - SPMemString.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 260 282 92.2 %
Date: 2024-05-12 00:16:13 Functions: 123 128 96.1 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_CORE_MEMORY_SPMEMSTRING_H_
      25             : #define STAPPLER_CORE_MEMORY_SPMEMSTRING_H_
      26             : 
      27             : #include "SPMemStorageMem.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler::memory {
      30             : 
      31             : struct char_pointer_test;
      32             : template<typename T> struct is_char_pointer {};
      33             : template<> struct is_char_pointer<const char *> { using Type = char_pointer_test*; };
      34             : template<> struct is_char_pointer<char *> { using Type = char_pointer_test; };
      35             : template<> struct is_char_pointer<const char16_t *> { using Type = char_pointer_test; };
      36             : template<> struct is_char_pointer<char16_t *> { using Type = char_pointer_test; };
      37             : template<> struct is_char_pointer<const char32_t *> { using Type = char_pointer_test; };
      38             : template<> struct is_char_pointer<char32_t *> { using Type = char_pointer_test; };
      39             : 
      40             : template <typename CharType, typename InputIterator, bool IsIntegral>
      41             : struct __basic_string_fill;
      42             : 
      43             : template <typename CharType>
      44             : class basic_string : public AllocPool {
      45             : public:
      46             :         using allocator_type = Allocator<CharType>;
      47             : 
      48             :         using pointer = CharType *;
      49             :         using const_pointer = const CharType *;
      50             :         using reference = CharType &;
      51             :         using const_reference = const CharType &;
      52             : 
      53             :         using traits_type = std::char_traits<CharType>;
      54             : 
      55             :         using size_type = size_t;
      56             :         using charT = CharType;
      57             :         using value_type = CharType;
      58             :         using mem_type = storage_mem<CharType, size_t(1)>;
      59             :         using self = basic_string<CharType>;
      60             : 
      61             :         using iterator = typename mem_type::iterator;
      62             :         using const_iterator = typename mem_type::const_iterator;
      63             :         using reverse_iterator = typename mem_type::reverse_iterator;
      64             :         using const_reverse_iterator = typename mem_type::const_reverse_iterator;
      65             : 
      66             :         static const size_type npos;
      67             : 
      68     2989531 :         basic_string() noexcept : _mem() { }
      69       48550 :         explicit basic_string (const allocator_type& alloc) noexcept : _mem(alloc) { }
      70             : 
      71     9439396 :         basic_string (const self& str) noexcept : _mem(str._mem) { }
      72             :         basic_string (const self& str, const allocator_type& alloc) noexcept : _mem(str._mem, alloc) { }
      73             : 
      74         125 :         basic_string (const self& str, size_type pos, size_type len = npos, const allocator_type& alloc = allocator_type()) noexcept
      75         125 :         : _mem(str._mem, pos, len, alloc) { }
      76             : 
      77      108841 :         basic_string(const charT* s, const allocator_type& alloc = allocator_type()) noexcept
      78      108841 :         : _mem(s, (s?traits_type::length(s):0), alloc) { }
      79             : 
      80     4406065 :         basic_string (const charT* s, size_type n, const allocator_type& alloc = allocator_type()) noexcept
      81     4406065 :         : _mem(s, n, alloc) { }
      82             : 
      83          25 :         basic_string (size_type n, charT c, const allocator_type& alloc = allocator_type()) noexcept : _mem(alloc) {
      84          25 :                 _mem.fill(n, c);
      85          25 :         }
      86             : 
      87             :         template <class InputIterator>
      88             :         basic_string (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) noexcept;
      89             : 
      90          25 :         basic_string (InitializerList<charT> il, const allocator_type& alloc = allocator_type()) noexcept : _mem(alloc) {
      91          25 :                 _mem.reserve(il.size());
      92         200 :                 for (auto it = il.begin(); it != il.end(); it ++) {
      93         175 :                         _mem.emplace_back_unsafe(*it);
      94             :                 }
      95          25 :         }
      96             : 
      97     8146151 :         basic_string (basic_string&& str) noexcept : _mem(std::move(str._mem)) { }
      98             :         basic_string (basic_string&& str, const allocator_type& alloc) noexcept : _mem(std::move(str._mem), alloc) { }
      99             : 
     100        5300 :         basic_string& operator=( const basic_string& str ) noexcept {
     101        5300 :                 _mem = str._mem;
     102        5300 :                 return *this;
     103             :         }
     104             : 
     105       14020 :         basic_string& operator=( basic_string&& str ) noexcept {
     106       14020 :                 _mem = std::move(str._mem);
     107       14020 :                 return *this;
     108             :         }
     109             : 
     110        1075 :         basic_string& operator=( const charT* s ) noexcept {
     111        1075 :                 _mem.assign(s, traits_type::length(s));
     112        1075 :                 return *this;
     113             :         }
     114             : 
     115             :         basic_string& operator=( charT ch ) noexcept {
     116             :                 _mem.assign(&ch, 1);
     117             :                 return *this;
     118             :         }
     119             : 
     120             :         basic_string& operator=( InitializerList<charT> ilist ) noexcept {
     121             :                 _mem.clear();
     122             :                 _mem.reserve(ilist.size());
     123             :                 for (auto &it : ilist) {
     124             :                         _mem.emplace_back_unsafe(it);
     125             :                 }
     126             :                 return *this;
     127             :         }
     128             : 
     129         175 :         allocator_type get_allocator() const noexcept { return _mem.get_allocator(); }
     130             : 
     131      152525 :         iterator begin() noexcept { return _mem.begin(); }
     132      164650 :         iterator end() noexcept { return _mem.end(); }
     133             : 
     134     8118325 :         const_iterator begin() const noexcept { return _mem.begin(); }
     135     8118300 :         const_iterator end() const noexcept { return _mem.end(); }
     136             : 
     137         200 :         const_iterator cbegin() const noexcept { return _mem.cbegin(); }
     138          75 :         const_iterator cend() const noexcept { return _mem.cend(); }
     139             : 
     140          50 :     reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
     141          25 :     reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
     142             : 
     143             :     const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
     144             :     const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
     145             : 
     146          50 :     const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
     147          50 :     const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
     148             : 
     149    42081667 :         size_type size() const noexcept { return _mem.size(); }
     150       30750 :         size_type length() const noexcept { return _mem.size(); }
     151         625 :         size_type capacity() const noexcept { return _mem.capacity(); }
     152             : 
     153      242902 :         void reserve (size_type n = 0) { _mem.reserve(n); }
     154             : 
     155      314319 :         void resize (size_type n) { _mem.resize(n); }
     156          25 :         void resize (size_type n, charT c) { _mem.resize(n, c); }
     157             : 
     158       11100 :         void clear() { _mem.clear(); }
     159       90019 :         bool empty() const noexcept { return _mem.empty(); }
     160             : 
     161          25 :         void shrink_to_fit() noexcept { _mem.shrink_to_fit(); }
     162             : 
     163       29125 :         reference operator[] (size_type pos) noexcept { return _mem.at(pos); }
     164         125 :         const_reference operator[] (size_type pos) const noexcept { return _mem.at(pos); }
     165             : 
     166        3100 :         reference at (size_type pos) noexcept { return _mem.at(pos); }
     167             :         const_reference at (size_type pos) const noexcept { return _mem.at(pos); }
     168             : 
     169       22075 :         charT& back() noexcept { return _mem.back(); }
     170          25 :         const charT& back() const noexcept { return _mem.back(); }
     171             : 
     172          25 :         charT& front() noexcept { return _mem.front(); }
     173        2100 :         const charT& front() const noexcept { return _mem.front(); }
     174             : 
     175       19675 :         basic_string& append (const basic_string& str) {
     176       19675 :                 _mem.insert_back(str._mem);
     177       19675 :                 return *this;
     178             :         }
     179          25 :         basic_string& append (const basic_string& str, size_type subpos, size_type sublen = npos) {
     180          25 :                 _mem.insert_back(str._mem, subpos, sublen);
     181          25 :                 return *this;
     182             :         }
     183       15725 :         basic_string& append (const charT* s) {
     184       15725 :                 _mem.insert_back(s, traits_type::length(s));
     185       15725 :                 return *this;
     186             :         }
     187   494101925 :         basic_string& append (const charT* s, size_type n) {
     188   494101925 :                 _mem.insert_back(s, n);
     189   494101925 :                 return *this;
     190             :         }
     191          50 :         basic_string& append (size_type n, charT c) {
     192          50 :                 _mem.resize(_mem.size() + n, c);
     193          50 :                 return *this;
     194             :         }
     195             :         template <class InputIterator>
     196          25 :         basic_string& append (InputIterator first, InputIterator last) {
     197          25 :                 auto diff = std::distance(first, last);
     198          25 :                 _mem.reserve(_mem.size() + diff, true);
     199         225 :                 for (auto it = first; it != last; ++ it) {
     200         225 :                         if (*it != value_type(0)) {
     201         200 :                                 _mem.emplace_back_unsafe(*it);
     202             :                         } else {
     203          25 :                                 break;
     204             :                         }
     205             :                 }
     206          25 :                 return *this;
     207             :         }
     208          50 :         basic_string& append (InitializerList<charT> il) {
     209          50 :                 _mem.reserve(il.size() + _mem.size(), true);
     210         375 :                 for (auto it = il.begin(); it != il.end(); it ++) {
     211         325 :                         _mem.emplace_back_unsafe(*it);
     212             :                 }
     213          50 :                 return *this;
     214             :         }
     215             : 
     216          25 :         basic_string& operator+= (const basic_string& str) { return append(str); }
     217          50 :         basic_string& operator+= (const charT* s) { return append(s); }
     218          50 :         basic_string& operator+= (charT c) { _mem.emplace_back(c); return *this; }
     219          25 :         basic_string& operator+= (InitializerList<charT> il) { return append(il); }
     220             : 
     221        1925 :         basic_string& assign (const basic_string& str) {
     222        1925 :                 _mem.assign(str._mem);
     223        1925 :                 return *this;
     224             :         }
     225          25 :         basic_string& assign (const basic_string& str, size_type subpos, size_type sublen = npos) {
     226          25 :                 _mem.assign(str._mem, subpos, sublen);
     227          25 :                 return *this;
     228             :         }
     229          25 :         basic_string& assign (const charT* s) {
     230          25 :                 _mem.assign(s, traits_type::length(s));
     231          25 :                 return *this;
     232             :         }
     233     5506650 :         basic_string& assign (const charT* s, size_type n) {
     234     5506650 :                 _mem.assign(s, n);
     235     5506650 :                 return *this;
     236             :         }
     237          25 :         basic_string& assign (size_type n, charT c) {
     238          25 :                 _mem.fill(n, c);
     239          25 :                 return *this;
     240             :         }
     241             : 
     242             :         template <class InputIterator>
     243             :         basic_string& assign (InputIterator first, InputIterator last) {
     244             :                 _mem.clear();
     245             :                 auto diff = last - first;
     246             :                 _mem.reserve(diff);
     247             :                 for (auto it = first; it != last; it ++) {
     248             :                         _mem.emplace_back_unsafe(*it);
     249             :                 }
     250             :                 return *this;
     251             :         }
     252             : 
     253          25 :         basic_string& assign (InitializerList<charT> il) {
     254          25 :                 _mem.clear();
     255          25 :                 _mem.reserve(il.size());
     256         200 :                 for (auto it = il.begin(); it != il.end(); it ++) {
     257         175 :                         _mem.emplace_back_unsafe(*it);
     258             :                 }
     259          25 :                 return *this;
     260             :         }
     261          25 :         basic_string& assign (basic_string&& str) noexcept {
     262          25 :                 _mem = std::move(str._mem);
     263          25 :                 return *this;
     264             :         }
     265             : 
     266     2046814 :         void push_back(CharType c) noexcept {
     267     2046814 :                 _mem.emplace_back(c);
     268     2046814 :         }
     269             : 
     270      663575 :         void emplace_back(CharType c) noexcept {
     271      663575 :                 _mem.emplace_back(c);
     272      663575 :         }
     273             : 
     274        1375 :         void pop_back() noexcept {
     275        1375 :                 _mem.pop_back();
     276        1375 :         }
     277             : 
     278          25 :         basic_string& insert (size_type pos, const basic_string& str) {
     279          25 :                 _mem.insert(pos, str._mem);
     280          25 :                 return *this;
     281             :         }
     282          25 :         basic_string& insert (size_type pos, const basic_string& str, size_type subpos, size_type sublen = npos) {
     283          25 :                 _mem.insert(pos, str._mem, subpos, sublen);
     284          25 :                 return *this;
     285             :         }
     286             : 
     287         150 :         basic_string& insert (size_type pos, const charT* s) {
     288         150 :                 _mem.insert(pos, s, traits_type::length(s));
     289         150 :                 return *this;
     290             :         }
     291             : 
     292             :         basic_string& insert (size_type pos, const charT* s, size_type n) {
     293             :                 _mem.insert(pos, s, n);
     294             :                 return *this;
     295             :         }
     296             : 
     297          25 :         basic_string& insert (size_type pos, size_type n, charT c) {
     298          25 :                 _mem.insert(pos, n, c);
     299          25 :                 return *this;
     300             :         }
     301          25 :         iterator insert (const_iterator p, size_type n, charT c) {
     302          25 :                 return _mem.insert(p, n, c);
     303             :         }
     304             : 
     305          25 :         iterator insert (const_iterator p, charT c) {
     306          25 :                 return _mem.insert(p, 1, c);
     307             :         }
     308             : 
     309             :         template< class InputIt >
     310       11125 :         iterator insert( const_iterator pos, InputIt first, InputIt last ) {
     311       11125 :                 return _mem.insert(pos, first, last);
     312             :         }
     313             : 
     314          25 :         iterator insert( const_iterator pos, std::initializer_list<charT> init ) {
     315          25 :                 return _mem.insert(pos, init.begin(), init.end());
     316             :         }
     317             : 
     318          50 :         basic_string& erase (size_type pos = 0, size_type len = npos) {
     319          50 :                 _mem.erase(pos, len);
     320          50 :                 return *this;
     321             :         }
     322             : 
     323          25 :         iterator erase (const_iterator p) {
     324          25 :                 return _mem.erase(p);
     325             :         }
     326             : 
     327             :         iterator erase (const_iterator first, const_iterator last) {
     328             :                 return _mem.erase(first, last);
     329             :         }
     330             : 
     331             :         basic_string& replace (size_type pos, size_type len, const basic_string& str) {
     332             :                 _mem.replace(pos, len, str._mem);
     333             :                 return *this;
     334             :         }
     335             :         basic_string& replace (const_iterator i1, const_iterator i2, const basic_string& str) {
     336             :                 _mem.replace(i1 - _mem.data(), i2 - i1, str._mem);
     337             :                 return *this;
     338             :         }
     339             : 
     340             :         basic_string& replace (size_type pos, size_type len, const basic_string& str,
     341             :                         size_type subpos, size_type sublen = npos) {
     342             :                 _mem.replace(pos, len, str._mem, subpos, sublen);
     343             :                 return *this;
     344             :         }
     345             : 
     346          25 :         basic_string& replace (size_type pos, size_type len, const charT* s) {
     347          25 :                 _mem.replace(pos, len, s, traits_type::length(s));
     348          25 :                 return *this;
     349             :         }
     350             :         basic_string& replace (const_iterator i1, const_iterator i2, const charT* s) {
     351             :                 _mem.replace(i1 - _mem.data(), i2 - i1, s, traits_type::length(s));
     352             :                 return *this;
     353             :         }
     354             : 
     355             :         basic_string& replace (size_type pos, size_type len, const charT* s, size_type n) {
     356             :                 _mem.replace(pos, len, s, n);
     357             :                 return *this;
     358             :         }
     359             :         basic_string& replace (const_iterator i1, const_iterator i2, const charT* s, size_type n) {
     360             :                 _mem.replace(i1 - _mem.data(), i2 - i1, s, n);
     361             :                 return *this;
     362             :         }
     363             : 
     364             :         basic_string& replace (size_type pos, size_type len, size_type n, charT c) {
     365             :                 _mem.replace(pos, len, n, c);
     366             :                 return *this;
     367             :         }
     368          25 :         basic_string& replace (const_iterator i1, const_iterator i2, size_type n, charT c) {
     369          25 :                 _mem.replace(i1 - _mem.data(), i2 - i1, n, c);
     370          25 :                 return *this;
     371             :         }
     372             : 
     373             :         template< class InputIt >
     374             :         basic_string& replace( const_iterator first, const_iterator last, InputIt first2, InputIt last2 ) {
     375             :                 _mem.replace(first, last, first2, last2);
     376             :                 return *this;
     377             :         }
     378             : 
     379             :         basic_string& replace( const_iterator first, const_iterator last, InitializerList<charT> init ) {
     380             :                 _mem.replace(first, last, init.begin(), init.end());
     381             :                 return *this;
     382             :         }
     383             : 
     384         125 :         const charT* c_str() const noexcept { return _mem.data(); }
     385    41898791 :         const charT* data() const noexcept { return _mem.data(); }
     386      200485 :         charT* data() noexcept { return _mem.data(); }
     387             : 
     388          25 :         size_type copy (charT* s, size_type len, size_type pos = 0) const {
     389          25 :                 len = std::min(len, _mem.size() - pos);
     390          25 :                 memcpy(s, _mem.data() + pos, len * sizeof(charT));
     391          25 :                 return len;
     392             :         }
     393             : 
     394         100 :         basic_string substr (size_type pos = 0, size_type len = npos) const {
     395         100 :                 return basic_string(*this, pos, len);
     396             :         }
     397             : 
     398             : 
     399             :     size_type find(const charT* __s, size_type __pos, size_type __n) const;
     400             :     size_type find(charT __c, size_type __pos = 0) const;
     401             :     size_type rfind(const charT* __s, size_type __pos, size_type __n) const;
     402             :     size_type rfind(charT __c, size_type __pos = npos) const;
     403             :     size_type find_first_of(const charT* __s, size_type __pos, size_type __n) const;
     404             :     size_type find_last_of(const charT* __s, size_type __pos, size_type __n) const;
     405             :     size_type find_first_not_of(const charT* __s, size_type __pos, size_type __n) const;
     406             :     size_type find_first_not_of(charT __c, size_type __pos = 0) const;
     407             :     size_type find_last_not_of(const charT* __s, size_type __pos, size_type __n) const;
     408             :     size_type find_last_not_of(charT __c, size_type __pos = npos) const;
     409             : 
     410             :     size_type find(const basic_string& __str, size_type __pos = 0) const {
     411             :         return this->find(__str.data(), __pos, __str.size());
     412             :     }
     413             : 
     414           0 :     size_type find(const charT* __s, size_type __pos = 0) const {
     415           0 :         return this->find(__s, __pos, traits_type::length(__s));
     416             :     }
     417             : 
     418             :     size_type rfind(const basic_string& __str, size_type __pos = npos) const {
     419             :         return this->rfind(__str.data(), __pos, __str.size());
     420             :     }
     421             : 
     422             :     size_type rfind(const charT* __s, size_type __pos = npos) const {
     423             :         return this->rfind(__s, __pos, traits_type::length(__s));
     424             :     }
     425             : 
     426             :     size_type find_first_of(const basic_string& __str, size_type __pos = 0) const {
     427             :         return this->find_first_of(__str.data(), __pos, __str.size());
     428             :     }
     429             : 
     430             :     size_type find_first_of(const charT* __s, size_type __pos = 0) const {
     431             :         return this->find_first_of(__s, __pos, traits_type::length(__s));
     432             :     }
     433             : 
     434          75 :     size_type find_first_of(charT __c, size_type __pos = 0) const {
     435          75 :         return this->find(__c, __pos);
     436             :     }
     437             : 
     438             :     size_type find_last_of(const basic_string& __str, size_type __pos = npos) const {
     439             :         return this->find_last_of(__str.data(), __pos, __str.size());
     440             :     }
     441             : 
     442             :     size_type find_last_of(const charT* __s, size_type __pos = npos) const {
     443             :         return this->find_last_of(__s, __pos, traits_type::length(__s));
     444             :     }
     445             : 
     446         200 :     size_type find_last_of(charT __c, size_type __pos = npos) const {
     447         200 :         return this->rfind(__c, __pos);
     448             :     }
     449             : 
     450             :     size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const {
     451             :         return this->find_first_not_of(__str.data(), __pos, __str.size());
     452             :     }
     453             : 
     454             :     size_type find_first_not_of(const charT* __s, size_type __pos = 0) const {
     455             :         return this->find_first_not_of(__s, __pos, traits_type::length(__s));
     456             :     }
     457             : 
     458             :     size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const {
     459             :         return this->find_last_not_of(__str.data(), __pos, __str.size());
     460             :     }
     461             : 
     462             :     size_type find_last_not_of(const charT* __s, size_type __pos = npos) const {
     463             :         return this->find_last_not_of(__s, __pos, traits_type::length(__s));
     464             :     }
     465             : 
     466    15498721 :         int compare (const basic_string& str) const noexcept {
     467    15498721 :             size_type lhs_sz = size();
     468    15498707 :             size_type rhs_sz = str.size();
     469    15498708 :             return compare(data(), lhs_sz, str.data(), rhs_sz);
     470             :         }
     471             : 
     472             :         int compare (size_type pos, size_type len, const basic_string& str) const {
     473             :             size_type lhs_sz = min(size() - pos, len);
     474             :             size_type rhs_sz = str.size();
     475             :             return compare(data() + pos, lhs_sz, str.data(), rhs_sz);
     476             :         }
     477             :         int compare (size_type pos, size_type len, const basic_string& str,
     478             :                      size_type subpos, size_type sublen = npos) const {
     479             :             size_type lhs_sz = min(size() - pos, len);
     480             :             size_type rhs_sz = min(str.size() - subpos, sublen);
     481             :             return compare(data() + pos, lhs_sz, str.data() + subpos, rhs_sz);
     482             :         }
     483             : 
     484      459952 :         int compare (const charT* s) const {
     485      459952 :             size_type lhs_sz = size();
     486      459953 :             size_type rhs_sz = traits_type::length(s);
     487      459952 :             return compare(data(), lhs_sz, s, rhs_sz);
     488             :         }
     489           0 :         int compare (size_type pos, size_type len, const charT* s) const {
     490           0 :             size_type lhs_sz = min(size() - pos, len);
     491           0 :             size_type rhs_sz = traits_type::length(s);
     492           0 :             return compare(data() + pos, lhs_sz, s, rhs_sz);
     493             :         }
     494             : 
     495             :         int compare (size_type pos, size_type len, const charT* s, size_type n) const {
     496             :             size_type lhs_sz = min(size() - pos, len);
     497             :             size_type rhs_sz = n;
     498             :             return compare(data() + pos, lhs_sz, s, rhs_sz);
     499             :         }
     500             : 
     501             : public: /* APR extensions */
     502             : 
     503             :         /* Weak strings - strings, that do not own their memory
     504             :          * It's behave like normal strings, and copy it's data into
     505             :          * new allocated memory block on first mutate call
     506             :          *
     507             :          * Weak string usually used with const qualifier.
     508             :          * Weak strings do not require any dynamic memory for creation
     509             :          *
     510             :          * Weak strings designed as bridge between APR C-like API (const char *)
     511             :          * and Stappler/Serenity C++-like api (const String &)
     512             :          */
     513          25 :         static const basic_string make_weak(const CharType *str, const allocator_type& alloc = allocator_type()) {
     514          25 :                 basic_string ret(alloc);
     515          25 :                 if (str) {
     516          25 :                         ret.assign_weak(str, traits_type::length(str));
     517             :                 }
     518          25 :                 return ret;
     519           0 :         }
     520             : 
     521       48525 :         static const basic_string make_weak(const CharType *str, size_type l, const allocator_type& alloc = allocator_type()) {
     522       48525 :                 basic_string ret(alloc);
     523       48524 :                 if (str) {
     524       48524 :                         ret.assign_weak(str, l);
     525             :                 }
     526       48524 :                 return ret;
     527           0 :         }
     528             : 
     529       61822 :         basic_string& assign_weak(const CharType *str, size_type l) {
     530       61822 :                 _mem.assign_weak(str, l);
     531       61818 :                 return *this;
     532             :         }
     533             : 
     534             :         basic_string& assign_weak(const CharType *str) {
     535             :                 _mem.assign_weak(str, traits_type::length(str));
     536             :                 return *this;
     537             :         }
     538             : 
     539             :         bool is_weak() const noexcept {
     540             :                 return _mem.is_weak();
     541             :         }
     542             : 
     543             :         template<int N>
     544             :         basic_string(const charT (&s)[N], const allocator_type& alloc = allocator_type())
     545             :         : _mem(alloc) {
     546             :                 _mem.assign_weak(s, N);
     547             :         }
     548             : 
     549             :         template<int N>
     550             :         basic_string(charT (&s)[N], const allocator_type& alloc = allocator_type())
     551             :         : _mem(alloc) {
     552             :                 _mem.assign_weak(s, N);
     553             :         }
     554             : 
     555             : 
     556             :         /* Wrap function used to assign preallocated c-string to apr::string
     557             :          * string will use provided memory for mutate operations, and return it to manager when destroyed
     558             :          */
     559             : 
     560             :         static basic_string wrap(CharType *str, const allocator_type& alloc = allocator_type()) {
     561             :                 basic_string ret(alloc);
     562             :                 ret.assign_wrap(str, traits_type::length(str));
     563             :                 return ret;
     564             :         }
     565             : 
     566             :         static basic_string wrap(CharType *str, size_type l, const allocator_type& alloc = allocator_type()) {
     567             :                 basic_string ret(alloc);
     568             :                 ret.assign_wrap(str, l);
     569             :                 return ret;
     570             :         }
     571             : 
     572             :         static basic_string wrap(CharType *str, size_type l, size_type nalloc, const allocator_type& alloc = allocator_type()) {
     573             :                 basic_string ret(alloc);
     574             :                 ret.assign_wrap(str, l, nalloc);
     575             :                 return ret;
     576             :         }
     577             : 
     578             :         basic_string& assign_wrap(CharType *str, size_type l) {
     579             :                 _mem.assign_mem(str, l, l + 1);
     580             :                 return *this;
     581             :         }
     582             : 
     583             :         basic_string& assign_wrap(CharType *str, size_type l, size_type nalloc) {
     584             :                 _mem.assign_mem(str, l, nalloc);
     585             :                 return *this;
     586             :         }
     587             : 
     588             :         // Extract should be used to capture string memory for non-STL-like container, e.g. apr::table.
     589             :         CharType *extract() {
     590             :                 return _mem.extract();
     591             :         }
     592             : 
     593             : protected:
     594    15958657 :         static int compare(const charT* s1, size_type len1, const charT* s2, size_type len2) {
     595    15958657 :             int result = (s1 && s2) ? traits_type::compare(s1, s2, min(len1, len2)) : 0;
     596    15958670 :             if (result != 0)
     597    15513306 :                 return result;
     598      445364 :             if (len1 < len2)
     599       23472 :                 return -1;
     600      421892 :             if (len1 > len2)
     601        4900 :                 return 1;
     602      416992 :             return 0;
     603             :         }
     604             : 
     605             :         template <typename C, typename I, bool B>
     606             :         friend struct __basic_string_fill;
     607             : 
     608             :         mem_type _mem;
     609             : };
     610             : 
     611             : template <typename CharType, typename InputIterator>
     612             : struct __basic_string_fill<CharType, InputIterator, true> {
     613          25 :         static void fill(basic_string<CharType> &str, InputIterator first, InputIterator last) noexcept {
     614          25 :                 str._mem.fill(size_t(first), CharType(last));
     615          25 :         }
     616             : };
     617             : 
     618             : template <typename CharType, typename InputIterator>
     619             : struct __basic_string_fill<CharType, InputIterator, false> {
     620          25 :         static void fill(basic_string<CharType> &str, InputIterator first, InputIterator last) noexcept {
     621          25 :                 auto size = std::distance(first, last);
     622          25 :                 str.reserve(size);
     623         375 :                 for (auto it = first; it != last; it ++) {
     624         350 :                         str._mem.emplace_back_unsafe(*it);
     625             :                 }
     626          25 :         }
     627             : };
     628             : 
     629             : template< class CharT >
     630             : template <class InputIterator>
     631          50 : basic_string<CharT>::basic_string (InputIterator first, InputIterator last, const allocator_type& alloc) noexcept : _mem(alloc) {
     632          50 :         __basic_string_fill<CharT, InputIterator, std::is_integral<InputIterator>::value>::fill(*this, first, last);
     633          50 : }
     634             : 
     635             : template< class CharT > basic_string<CharT>
     636             : operator+( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     637             :         basic_string<CharT> ret;
     638             :         ret.reserve(lhs.size() + rhs.size());
     639             :         ret.assign(lhs);
     640             :         ret.append(rhs);
     641             :         return ret;
     642             : }
     643             : 
     644             : template< class CharT > basic_string<CharT>
     645             : operator+( const CharT* lhs, const basic_string<CharT> & rhs ) {
     646             :         basic_string<CharT> ret;
     647             :         ret.reserve(std::char_traits<CharT>::length(lhs) + rhs.size());
     648             :         ret.assign(lhs);
     649             :         ret.append(rhs);
     650             :         return ret;
     651             : }
     652             : 
     653             : template< class CharT > basic_string<CharT>
     654             : operator+( CharT lhs, const basic_string<CharT>& rhs ) {
     655             :         basic_string<CharT> ret;
     656             :         ret.reserve(rhs.size() + 1);
     657             :         ret.assign(1, lhs);
     658             :         ret.append(rhs);
     659             :         return ret;
     660             : }
     661             : 
     662             : template< class CharT > basic_string<CharT>
     663        1900 : operator+( const basic_string<CharT>& lhs, const CharT* rhs ) {
     664        1900 :         basic_string<CharT> ret;
     665        1900 :         ret.reserve(lhs.size() + std::char_traits<CharT>::length(rhs));
     666        1900 :         ret.assign(lhs);
     667        1900 :         ret.append(rhs);
     668        1900 :         return ret;
     669           0 : }
     670             : 
     671             : template< class CharT > basic_string<CharT>
     672             : operator+( const basic_string<CharT>& lhs, CharT rhs ) {
     673             :         basic_string<CharT> ret;
     674             :         ret.reserve(rhs.size() + 1);
     675             :         ret.assign(lhs);
     676             :         ret.append(1, rhs);
     677             :         return ret;
     678             : }
     679             : 
     680             : template< class CharT > basic_string<CharT>
     681             : operator+( basic_string<CharT>&& lhs, const basic_string<CharT>& rhs ) {
     682             :         return std::move(lhs.append(rhs));
     683             : }
     684             : 
     685             : template< class CharT > basic_string<CharT>
     686             : operator+( const basic_string<CharT>& lhs, basic_string<CharT>&& rhs ) {
     687             :         return std::move(rhs.insert(0, lhs));
     688             : }
     689             : 
     690             : template< class CharT > basic_string<CharT>
     691        5400 : operator+( basic_string<CharT>&& lhs, basic_string<CharT>&& rhs ) {
     692        5400 :         return std::move(lhs.append(rhs));
     693             : }
     694             : 
     695             : template< class CharT > basic_string<CharT>
     696         125 : operator+(const CharT* lhs, basic_string<CharT>&& rhs ) {
     697         125 :         return std::move(rhs.insert(0, lhs));
     698             : }
     699             : 
     700             : template< class CharT > basic_string<CharT>
     701             : operator+( CharT lhs, basic_string<CharT>&& rhs ) {
     702             :         return std::move(rhs.insert(0, 1, lhs));
     703             : }
     704             : 
     705             : template< class CharT > basic_string<CharT>
     706          25 : operator+( basic_string<CharT>&& lhs, const CharT* rhs ) {
     707          25 :         return std::move(lhs.append(rhs));
     708             : }
     709             : 
     710             : template< class CharT > basic_string<CharT>
     711             : operator+( basic_string<CharT>&& lhs, CharT rhs ) {
     712             :         return std::move(lhs.append(1, rhs));
     713             : }
     714             : 
     715        9650 : template< class CharT > bool operator== ( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     716        9650 :         return lhs.compare(rhs) == 0;
     717             : }
     718             : 
     719        1279 : template< class CharT > bool operator!= ( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     720        1279 :         return lhs.compare(rhs) != 0;
     721             : }
     722             : 
     723    15487770 : template< class CharT > bool operator< ( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     724    15487770 :         return lhs.compare(rhs) < 0;
     725             : }
     726             : 
     727             : template< class CharT > bool operator<= ( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     728             :         return lhs.compare(rhs) <= 0;
     729             : }
     730             : 
     731             : template< class CharT > bool operator> ( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     732             :         return lhs.compare(rhs) > 0;
     733             : }
     734             : 
     735             : template< class CharT > bool operator>= ( const basic_string<CharT>& lhs, const basic_string<CharT>& rhs ) {
     736             :         return lhs.compare(rhs) >= 0;
     737             : }
     738             : 
     739      258097 : template< class CharT > bool operator== ( const basic_string<CharT>& lhs, const CharT* rhs ) {
     740      258097 :         return lhs.compare(rhs) == 0;
     741             : }
     742             : 
     743        2400 : template< class CharT > bool operator!= ( const basic_string<CharT>& lhs, const CharT* rhs ) {
     744        2400 :         return lhs.compare(rhs) != 0;
     745             : }
     746             : 
     747       66766 : template< class CharT > bool operator<( const basic_string<CharT>& lhs,  const CharT* rhs ) {
     748       66766 :         return lhs.compare(rhs) < 0;
     749             : }
     750             : 
     751             : template< class CharT > bool operator<= ( const basic_string<CharT>& lhs, const CharT* rhs ) {
     752             :         return lhs.compare(rhs) <= 0;
     753             : }
     754             : 
     755             : template< class CharT > bool operator>( const basic_string<CharT>& lhs, const CharT* rhs ) {
     756             :         return lhs.compare(rhs) > 0;
     757             : }
     758             : 
     759             : template< class CharT > bool operator>=( const basic_string<CharT>& lhs, const CharT* rhs ) {
     760             :         return lhs.compare(rhs) >= 0;
     761             : }
     762             : 
     763             : 
     764         475 : template< class CharT > bool operator== ( const CharT* lhs, const basic_string<CharT>& rhs ) {
     765         475 :         return rhs.compare(lhs) == 0;
     766             : }
     767             : 
     768             : template< class CharT > bool operator!= ( const CharT* lhs, const basic_string<CharT>& rhs ) {
     769             :         return rhs.compare(lhs) != 0;
     770             : }
     771             : 
     772      132216 : template< class CharT > bool operator< ( const CharT* lhs, const basic_string<CharT>& rhs ) {
     773      132216 :         return rhs.compare(lhs) > 0;
     774             : }
     775             : 
     776             : template< class CharT > bool operator<= ( const CharT* lhs, const basic_string<CharT>& rhs ) {
     777             :         return rhs.compare(lhs) >= 0;
     778             : }
     779             : 
     780             : template< class CharT > bool operator>( const CharT* lhs, const basic_string<CharT>& rhs ) {
     781             :         return rhs.compare(lhs) < 0;
     782             : }
     783             : 
     784             : template< class CharT > bool operator>=( const CharT* lhs, const basic_string<CharT>& rhs ) {
     785             :         return rhs.compare(lhs) <= 0;
     786             : }
     787             : 
     788             : template<typename _CharT> typename basic_string<_CharT>::size_type
     789           0 : basic_string<_CharT>:: find(const charT* __s, size_type __pos, size_type __n) const {
     790           0 :         const size_type __size = this->size();
     791           0 :         const _CharT* __data = _mem.data();
     792             : 
     793           0 :         if (__n == 0) {
     794           0 :                 return __pos <= __size ? __pos : npos;
     795           0 :         } else if (__n <= __size) {
     796           0 :                 for (; __pos <= __size - __n; ++__pos)
     797           0 :                 if (traits_type::eq(__data[__pos], __s[0])
     798           0 :                                 && traits_type::compare(__data + __pos + 1,
     799             :                                                 __s + 1, __n - 1) == 0)
     800           0 :                 return __pos;
     801             :         }
     802           0 :         return npos;
     803             : }
     804             : 
     805             : template<typename _CharT> typename basic_string<_CharT>::size_type
     806         100 : basic_string<_CharT>::find(charT __c, size_type __pos) const {
     807         100 :         size_type __ret = npos;
     808         100 :         const size_type __size = this->size();
     809         100 :         if (__pos < __size) {
     810         100 :                 const _CharT* __data = _mem.data();
     811         100 :                 const size_type __n = __size - __pos;
     812         100 :                 const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
     813         100 :                 if (__p)
     814         100 :                         __ret = __p - __data;
     815             :         }
     816         100 :         return __ret;
     817             : }
     818             : 
     819             : template<typename _CharT> typename basic_string<_CharT>::size_type
     820             : basic_string<_CharT>::rfind(const charT* __s, size_type __pos, size_type __n) const {
     821             :         const size_type __size = this->size();
     822             :         if (__n <= __size) {
     823             :                 __pos = min(size_type(__size - __n), __pos);
     824             :                 const _CharT* __data = _mem.data();
     825             :                 do {
     826             :                         if (traits_type::compare(__data + __pos, __s, __n) == 0)
     827             :                                 return __pos;
     828             :                 }
     829             :                 while (__pos-- > 0);
     830             :         }
     831             :         return npos;
     832             : }
     833             : 
     834             : template<typename _CharT> typename basic_string<_CharT>::size_type
     835         200 : basic_string<_CharT>::rfind(charT __c, size_type __pos) const {
     836         200 :         size_type __size = this->size();
     837         200 :         if (__size) {
     838         200 :                 if (--__size > __pos)
     839           0 :                         __size = __pos;
     840        2350 :                 for (++__size; __size-- > 0; )
     841        2300 :                         if (traits_type::eq(_mem.data()[__size], __c))
     842         150 :                 return __size;
     843             :         }
     844          50 :         return npos;
     845             : }
     846             : 
     847             : template<typename _CharT> typename basic_string<_CharT>::size_type
     848             : basic_string<_CharT>::find_first_of(const charT* __s, size_type __pos, size_type __n) const {
     849             :         for (; __n && __pos < this->size(); ++__pos) {
     850             :                 const _CharT* __p = traits_type::find(__s, __n, _mem.data()[__pos]);
     851             :                 if (__p)
     852             :                         return __pos;
     853             :         }
     854             :         return npos;
     855             : }
     856             : 
     857             : template<typename _CharT> typename basic_string<_CharT>::size_type
     858             : basic_string<_CharT>:: find_last_of(const charT* __s, size_type __pos, size_type __n) const {
     859             :         size_type __size = this->size();
     860             :         if (__size && __n) {
     861             :                 if (--__size > __pos)
     862             :                         __size = __pos;
     863             :                 do {
     864             :                         if (traits_type::find(__s, __n, _mem.data()[__size]))
     865             :                         return __size;
     866             :                 } while (__size-- != 0);
     867             :         }
     868             :         return npos;
     869             : }
     870             : 
     871             : template<typename _CharT> typename basic_string<_CharT>::size_type
     872             : basic_string<_CharT>::find_first_not_of(const charT* __s, size_type __pos, size_type __n) const  {
     873             :         for (; __pos < this->size(); ++__pos)
     874             :                 if (!traits_type::find(__s, __n, _mem.data()[__pos]))
     875             :                         return __pos;
     876             :         return npos;
     877             : }
     878             : 
     879             : template<typename _CharT> typename basic_string<_CharT>::size_type
     880             : basic_string<_CharT>::find_first_not_of(charT __c, size_type __pos) const {
     881             :         for (; __pos < this->size(); ++__pos)
     882             :                 if (!traits_type::eq(_mem.data()[__pos], __c))
     883             :                         return __pos;
     884             :         return npos;
     885             : }
     886             : 
     887             : template<typename _CharT> typename basic_string<_CharT>::size_type
     888             : basic_string<_CharT>:: find_last_not_of(const charT* __s, size_type __pos, size_type __n) const {
     889             :         size_type __size = this->size();
     890             :         if (__size)     {
     891             :                 if (--__size > __pos)
     892             :                         __size = __pos;
     893             :                 do {
     894             :                         if (!traits_type::find(__s, __n, _mem.data()[__size]))
     895             :                         return __size;
     896             :                 } while (__size--);
     897             :         }
     898             :         return npos;
     899             : }
     900             : 
     901             : template<typename _CharT> typename basic_string<_CharT>::size_type
     902             : basic_string<_CharT>::find_last_not_of(charT __c, size_type __pos) const {
     903             :         size_type __size = this->size();
     904             :         if (__size)     {
     905             :                 if (--__size > __pos)
     906             :                         __size = __pos;
     907             :                 do {
     908             :                         if (!traits_type::eq(_mem.data()[__size], __c))
     909             :                         return __size;
     910             :                 } while (__size--);
     911             :         }
     912             :         return npos;
     913             : }
     914             : 
     915             : template<typename CharType> inline std::basic_ostream<CharType> &
     916       54325 : operator << (std::basic_ostream<CharType> & os, const basic_string<CharType> & str) {
     917       54325 :         return os.write(str.data(), str.size());
     918             : }
     919             : 
     920             : template<typename CharType> const typename basic_string<CharType>::size_type
     921             :     basic_string<CharType>::npos = maxOf<typename basic_string<CharType>::size_type>();
     922             : 
     923             : using string = basic_string<char>;
     924             : using u16string = basic_string<char16_t>;
     925             : using u32string = basic_string<char32_t>;
     926             : 
     927             : using weak_string = const string;
     928             : 
     929             : }
     930             : 
     931             : namespace STAPPLER_VERSIONIZED stappler {
     932             : 
     933       13274 : inline stappler::memory::basic_string<char> operator"" _weak ( const char* str, size_t len) {
     934       13274 :         stappler::memory::basic_string<char> ret;
     935       13274 :         if (str) {
     936       13274 :                 ret.assign_weak(str, len);
     937             :         }
     938       13270 :         return ret;
     939           0 : }
     940             : 
     941             : }
     942             : 
     943             : namespace std {
     944             : 
     945             : template<>
     946             : struct hash<STAPPLER_VERSIONIZED_NAMESPACE::memory::basic_string<char>> {
     947         175 :         size_t operator() (const STAPPLER_VERSIONIZED_NAMESPACE::memory::basic_string<char> & s) const noexcept {
     948             :                 if (sizeof(size_t) == 8) {
     949         175 :                         return STAPPLER_VERSIONIZED_NAMESPACE::hash::hash64(s.data(), s.size());
     950             :                 } else {
     951             :                         return STAPPLER_VERSIONIZED_NAMESPACE::hash::hash32(s.data(), s.size());
     952             :                 }
     953             :         }
     954             : };
     955             : 
     956             : template<>
     957             : struct hash<STAPPLER_VERSIONIZED_NAMESPACE::memory::basic_string<char16_t>> {
     958             :         size_t operator() (const STAPPLER_VERSIONIZED_NAMESPACE::memory::basic_string<char16_t> & s) const noexcept {
     959             :                 if (sizeof(size_t) == 8) {
     960             :                         return STAPPLER_VERSIONIZED_NAMESPACE::hash::hash64((char *)s.data(), s.size() * sizeof(char16_t));
     961             :                 } else {
     962             :                         return STAPPLER_VERSIONIZED_NAMESPACE::hash::hash32((char *)s.data(), s.size() * sizeof(char16_t));
     963             :                 }
     964             :         }
     965             : };
     966             : 
     967             : }
     968             : 
     969             : #endif /* STAPPLER_CORE_MEMORY_SPMEMSTRING_H_ */

Generated by: LCOV version 1.14