LCOV - code coverage report
Current view: top level - json - string.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 151 151
Test Date: 2025-12-23 16:57:37 Functions: 100.0 % 100 100

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/boostorg/json
       9              : //
      10              : 
      11              : #ifndef BOOST_JSON_STRING_HPP
      12              : #define BOOST_JSON_STRING_HPP
      13              : 
      14              : #include <boost/json/detail/config.hpp>
      15              : #include <boost/json/pilfer.hpp>
      16              : #include <boost/json/storage_ptr.hpp>
      17              : #include <boost/json/string_view.hpp>
      18              : #include <boost/json/detail/digest.hpp>
      19              : #include <boost/json/detail/except.hpp>
      20              : #include <boost/json/detail/string_impl.hpp>
      21              : #include <boost/json/detail/value.hpp>
      22              : #include <boost/system/result.hpp>
      23              : #include <cstring>
      24              : #include <iosfwd>
      25              : #include <iterator>
      26              : #include <new>
      27              : #include <type_traits>
      28              : #include <utility>
      29              : 
      30              : namespace boost {
      31              : namespace json {
      32              : 
      33              : class value;
      34              : 
      35              : /** The native type of string values.
      36              : 
      37              :     Instances of string store and manipulate sequences of `char` using the
      38              :     UTF-8 encoding. The elements of a string are stored contiguously. A pointer
      39              :     to any character in a string may be passed to functions that expect
      40              :     a pointer to the first element of a null-terminated `char` array. The type
      41              :     uses small buffer optimisation to avoid allocations for small strings.
      42              : 
      43              :     String iterators are regular `char` pointers.
      44              : 
      45              :     @attention `string` member functions do not validate any UTF-8 byte sequences
      46              :     passed to them.
      47              : 
      48              :     @par Thread Safety
      49              :     Non-const member functions may not be called concurrently with any other
      50              :     member functions.
      51              : 
      52              :     @par Satisfies
      53              :         [_ContiguousContainer_](https://en.cppreference.com/w/cpp/named_req/ContiguousContainer),
      54              :         [_ReversibleContainer_](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer),
      55              :         and {req_SequenceContainer}.
      56              : */
      57              : class string
      58              : {
      59              :     friend class value;
      60              : #ifndef BOOST_JSON_DOCS
      61              :     // VFALCO doc toolchain shouldn't show this but does
      62              :     friend struct detail::access;
      63              : #endif
      64              : 
      65              :     using string_impl = detail::string_impl;
      66              : 
      67              :     inline
      68              :     string(
      69              :         detail::key_t const&,
      70              :         string_view s,
      71              :         storage_ptr sp);
      72              : 
      73              :     inline
      74              :     string(
      75              :         detail::key_t const&,
      76              :         string_view s1,
      77              :         string_view s2,
      78              :         storage_ptr sp);
      79              : 
      80              : public:
      81              :     /// Associated [Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator)
      82              :     using allocator_type = container::pmr::polymorphic_allocator<value>;
      83              : 
      84              :     /// The type of a character
      85              :     using value_type        = char;
      86              : 
      87              :     /// The type used to represent unsigned integers
      88              :     using size_type         = std::size_t;
      89              : 
      90              :     /// The type used to represent signed integers
      91              :     using difference_type   = std::ptrdiff_t;
      92              : 
      93              :     /// A pointer to an element
      94              :     using pointer           = char*;
      95              : 
      96              :     /// A const pointer to an element
      97              :     using const_pointer     = char const*;
      98              : 
      99              :     /// A reference to an element
     100              :     using reference         = char&;
     101              : 
     102              :     /// A const reference to an element
     103              :     using const_reference   = const char&;
     104              : 
     105              :     /// A random access iterator to an element
     106              :     using iterator          = char*;
     107              : 
     108              :     /// A random access const iterator to an element
     109              :     using const_iterator    = char const*;
     110              : 
     111              :     /// A reverse random access iterator to an element
     112              :     using reverse_iterator =
     113              :         std::reverse_iterator<iterator>;
     114              : 
     115              :     /// A reverse random access const iterator to an element
     116              :     using const_reverse_iterator =
     117              :         std::reverse_iterator<const_iterator>;
     118              : 
     119              :     /** A special index
     120              : 
     121              :         Represents the end of the string.
     122              :     */
     123              :     static constexpr std::size_t npos =
     124              :         string_view::npos;
     125              : 
     126              : private:
     127              :     template<class T>
     128              :     using is_inputit = typename std::enable_if<
     129              :         std::is_convertible<typename
     130              :             std::iterator_traits<T>::reference,
     131              :             char>::value>::type;
     132              : 
     133              :     storage_ptr sp_; // must come first
     134              :     string_impl impl_;
     135              : 
     136              : public:
     137              :     /** Destructor.
     138              : 
     139              :         Any dynamically allocated internal storage is freed.
     140              : 
     141              :         @par Complexity
     142              :         Constant.
     143              : 
     144              :         @par Exception Safety
     145              :         No-throw guarantee.
     146              :     */
     147        30659 :     ~string() noexcept
     148              :     {
     149        30659 :         impl_.destroy(sp_);
     150        30659 :     }
     151              : 
     152              :     //------------------------------------------------------
     153              :     //
     154              :     // Construction
     155              :     //
     156              :     //------------------------------------------------------
     157              : 
     158              :     /** Constructors.
     159              : 
     160              :         Construct a string.
     161              : 
     162              :         @li **(1)**, **(2)** the string is empty with a non-zero,
     163              :             unspecified capacity.
     164              : 
     165              :         @li **(3)** the string is filled with `count` copies of character `ch`.
     166              : 
     167              :         @li **(4)** the string will contain a copy of the characters of `s`.
     168              : 
     169              :         @li **(5)** the string will contain a copy of the characters of the
     170              :             null-terminated string `s`.
     171              : 
     172              :         @li **(6)** the string will contain a copy of the characters in the
     173              :             range `[s, s + count)`.
     174              : 
     175              :         @li **(7)** the string will contain a copy of the characters in the
     176              :             range `[first, last)`.
     177              : 
     178              :         @li **(8)**, **(9)** the string contains a copy of the characters of
     179              :             `other`.
     180              : 
     181              :         @li **(10)** the string acquires ownership of the contents of `other`.
     182              : 
     183              :         @li **(11)** equivalent to **(10)** if `*sp == *other.storage()`;
     184              :             otherwise equivalent to **(9)**.
     185              : 
     186              :         @li **(12)** the string is acquires ownership of the contents of
     187              :             `other` using pilfer semantics. This is more efficient than move
     188              :             construction, when it is known that the moved-from object
     189              :             will be immediately destroyed afterwards.
     190              : 
     191              :         With **(2)**--**(7)**, **(9)**, **(11)** the constructed string uses
     192              :         memory resource of `sp`. With **(8)**, **(10)**, and **(12)** it uses
     193              :         `other`'s memory resource. In either case the string will share the
     194              :         ownership of the memory resource. With **(1)** it uses the
     195              :         \<\<default_memory_resource, default memory resource\>\>.
     196              : 
     197              :         After **(10)** `other` behaves as if newly constructed with its
     198              :         current storage pointer.
     199              : 
     200              :         After **(12)** `other` is not in a usable state and may only be
     201              :         destroyed.
     202              : 
     203              :         @par Constraints
     204              :         `InputIt` satisfies {req_InputIterator}.
     205              : 
     206              :         @par Complexity
     207              :         @li **(1)**, **(2)**, **(10)**, **(12)** constant.
     208              :         @li **(3)** linear in `count`.
     209              :         @li **(4)** linear in `s.size()`.
     210              :         @li **(5)** linear in `std::strlen(s)`.
     211              :         @li **(6)** linear in `count`.
     212              :         @li **(7)** linear in `std::distance(first, last)`.
     213              :         @li **(8)**, **(9)** linear in `other.size()`.
     214              :         @li **(11)** constant if `*sp == *other.storage()`; otherwise linear in
     215              :             `other.size()`.
     216              : 
     217              :         @par Exception Safety
     218              :         @li **(1)**, **(2)**, **(10)**, **(12)** no-throw guarantee.
     219              :         @li **(3)**--**(6)**, **(8)**, **(9)**, **(11)**  strong guarantee.
     220              :         @li **(7)** strong guarantee if `InputIt` satisfies
     221              :         {req_ForwardIterator}, basic guarantee otherwise.
     222              : 
     223              :         Calls to `memory_resource::allocate` may throw.
     224              : 
     225              :         @throw boost::system::system_error The constructed string's size would
     226              :                have exceeded @ref max_size().
     227              : 
     228              :         @see @ref pilfer,
     229              :             [Valueless Variants Considered Harmful](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html).
     230              : 
     231              :         @{
     232              :     */
     233         2456 :     string() = default;
     234              : 
     235              :     /** Overload
     236              : 
     237              :         @param sp A pointer to the @ref boost::container::pmr::memory_resource
     238              :         to use. The container will acquire shared ownership of the memory
     239              :         resource.
     240              :     */
     241              :     explicit
     242         9103 :     string(storage_ptr sp)
     243         9103 :         : sp_(std::move(sp))
     244              :     {
     245         9103 :     }
     246              : 
     247              :     /** Overload
     248              : 
     249              :         @param count The size of the resulting string.
     250              :         @param ch The value to initialize characters of the string with.
     251              :         @param sp
     252              :     */
     253              :     BOOST_JSON_DECL
     254              :     explicit
     255              :     string(
     256              :         std::size_t count,
     257              :         char ch,
     258              :         storage_ptr sp = {});
     259              : 
     260              :     /** Overload
     261              : 
     262              :         @param s The string to copy from.
     263              :         @param sp
     264              :     */
     265              :     BOOST_JSON_DECL
     266              :     string(
     267              :         string_view s,
     268              :         storage_ptr sp = {});
     269              : 
     270              :     /// Overload
     271              :     BOOST_JSON_DECL
     272              :     string(
     273              :         char const* s,
     274              :         storage_ptr sp = {});
     275              : 
     276              :     /// Overload
     277              :     BOOST_JSON_DECL
     278              :     explicit
     279              :     string(
     280              :         char const* s,
     281              :         std::size_t count,
     282              :         storage_ptr sp = {});
     283              : 
     284              :     /** Overload
     285              : 
     286              :         @tparam InputIt The type of the iterators.
     287              : 
     288              :         @param first An input iterator pointing to the first character to
     289              :                insert, or pointing to the end of the range.
     290              :         @param last An input iterator pointing to the end of the range.
     291              :         @param sp
     292              :     */
     293              :     template<class InputIt
     294              :     #ifndef BOOST_JSON_DOCS
     295              :         ,class = is_inputit<InputIt>
     296              :     #endif
     297              :     >
     298              :     explicit
     299              :     string(
     300              :         InputIt first,
     301              :         InputIt last,
     302              :         storage_ptr sp = {});
     303              : 
     304              :     /** Overload
     305              :         @param other The source string.
     306              :     */
     307              :     BOOST_JSON_DECL
     308              :     string(string const& other);
     309              : 
     310              :     /// Overload
     311              :     BOOST_JSON_DECL
     312              :     explicit
     313              :     string(
     314              :         string const& other,
     315              :         storage_ptr sp);
     316              : 
     317              :     /// Overload
     318          415 :     string(string&& other) noexcept
     319          415 :         : sp_(other.sp_)
     320          415 :         , impl_(other.impl_)
     321              :     {
     322          415 :         ::new(&other.impl_) string_impl();
     323          415 :     }
     324              : 
     325              :     /// Overload
     326              :     BOOST_JSON_DECL
     327              :     explicit
     328              :     string(
     329              :         string&& other,
     330              :         storage_ptr sp);
     331              : 
     332              :     /// Overload
     333            5 :     string(pilfered<string> other) noexcept
     334            5 :         : sp_(std::move(other.get().sp_))
     335            5 :         , impl_(other.get().impl_)
     336              :     {
     337            5 :         ::new(&other.get().impl_) string_impl();
     338            5 :     }
     339              :     /// @}
     340              : 
     341              :     //------------------------------------------------------
     342              :     //
     343              :     // Assignment
     344              :     //
     345              :     //------------------------------------------------------
     346              : 
     347              :     /** Assignment operators.
     348              : 
     349              :         @li **(1)**, **(4)** the contents are replaced with an element-wise
     350              :             copy of `other`.
     351              :         @li **(2)** takes ownership of `other`'s element storage if
     352              :             `*storage() == *other.storage()`; otherwise equivalent to **(1)**.
     353              :         @li **(3)** the contents are replaced with an element-wise copy of
     354              :             null-terminated string `s`.
     355              : 
     356              :         After **(2)**, the moved-from array behaves as if newly constructed
     357              :         with its current storage pointer.
     358              : 
     359              :         @par Complexity
     360              :         @li **(1)**, **(4)** linear in `other.size()`.
     361              :         @li **(2)** constant if `*storage() == *other.storage()`; otherwise
     362              :             linear in `other.size()`.
     363              :         @li **(3)** linear in `std::strlen(s)`.
     364              : 
     365              :         @par Exception Safety
     366              :         {sp} **(2)** provides strong guarantee if
     367              :         `*storage() != *other.storage()` and no-throw guarantee otherwise.
     368              :         Other overloads provide strong guarantee.
     369              :         Calls to `memory_resource::allocate` may throw.
     370              : 
     371              :         @param other The string to copy.
     372              : 
     373              :         @return `*this`
     374              : 
     375              :         @{
     376              :     */
     377              :     BOOST_JSON_DECL
     378              :     string&
     379              :     operator=(string const& other);
     380              : 
     381              :     BOOST_JSON_DECL
     382              :     string&
     383              :     operator=(string&& other);
     384              : 
     385              :     /** Overload
     386              : 
     387              :         @param s The null-terminated character string.
     388              : 
     389              :         @throw boost::system::system_error `std::strlen(s) >` @ref max_size().
     390              :     */
     391              :     BOOST_JSON_DECL
     392              :     string&
     393              :     operator=(char const* s);
     394              : 
     395              :     /** Overload
     396              : 
     397              :         @throw `boost::system::system_error` `other.size() >` @ref max_size().
     398              :     */
     399              :     BOOST_JSON_DECL
     400              :     string&
     401              :     operator=(string_view other);
     402              :     /// @}
     403              : 
     404              :     /** Assign characters to a string.
     405              : 
     406              :         @li **(1)** replaces the contents with `count` copies of character
     407              :         `ch`.
     408              : 
     409              :         @li **(2)** replaces the contents with copies of the characters in the
     410              :         range `[s, s + count)`. This range can contain null characters.
     411              : 
     412              :         @li **(3)** replaces the contents with those of the null terminated
     413              :         string `s`. The length of the string is determined by the first null
     414              :         character.
     415              : 
     416              :         @li **(4)** replaces the contents with copies of characters in the
     417              :         range `[first, last)`.
     418              : 
     419              :         @li **(5)** Replaces the contents with those of string view `s`. This
     420              :         view can contain null characters.
     421              : 
     422              :         @li **(6)** replaces the contents with a copy of the characters of
     423              :         `other`.
     424              : 
     425              :         @li **(7)** if `*storage() == *other.storage()` takes ownership of the
     426              :         element storage of `other`; otherwise equivalent to **(6)**.
     427              : 
     428              :         Self-assignment using **(7)** does nothing.
     429              : 
     430              :         After **(7)** `other` is left in valid but unspecified state.
     431              : 
     432              :         @par Constraints
     433              :         `InputIt` satisfies {req_InputIterator}.
     434              : 
     435              :         @par Complexity
     436              :         @li **(1)**, **(2)** linear in `count`.
     437              :         @li **(3)** linear in `std::strlen(s)`.
     438              :         @li **(4)** linear in `std::distance(first, last)`.
     439              :         @li **(5)** linear in `s.size()`.
     440              :         @li **(6)** linear in `other.size()`.
     441              :         @li **(7)** constant if `*storage() == *other.storage()`, otherwise
     442              :             linear in `other.size()`.
     443              : 
     444              :         @par Exception Safety
     445              :         {sp} **(7)** provides strong guarantee if
     446              :         `*storage() != *other.storage()` and no-throw guarantee otherwise.
     447              :         Other overloads provide strong guarantee. Calls to
     448              :         `memory_resource::allocate` may throw.
     449              : 
     450              :         @return `*this`.
     451              : 
     452              :         @param count The number of the characters to use.
     453              : 
     454              :         @param ch The character to fill the string with.
     455              : 
     456              :         @throw boost::system::system_error The size of the string after the
     457              :         operation would exceed @ref max_size().
     458              : 
     459              :         @{
     460              :     */
     461              :     BOOST_JSON_DECL
     462              :     string&
     463              :     assign(
     464              :         std::size_t count,
     465              :         char ch);
     466              : 
     467              :     /** Overload
     468              :         @param s A pointer to a character string used to copy from.
     469              :         @param count
     470              :     */
     471              :     BOOST_JSON_DECL
     472              :     string&
     473              :     assign(
     474              :         char const* s,
     475              :         std::size_t count);
     476              : 
     477              :     /** Overload
     478              :         @param s
     479              :     */
     480              :     BOOST_JSON_DECL
     481              :     string&
     482              :     assign(
     483              :         char const* s);
     484              : 
     485              :     /** Overload
     486              : 
     487              :         @tparam InputIt The type of the iterators.
     488              : 
     489              :         @param first An input iterator pointing to the first character to
     490              :         insert, or pointing to the end of the range.
     491              :         @param last An input iterator pointing to the end of the range.
     492              :     */
     493              :     template<class InputIt
     494              :     #ifndef BOOST_JSON_DOCS
     495              :         ,class = is_inputit<InputIt>
     496              :     #endif
     497              :     >
     498              :     string&
     499              :     assign(
     500              :         InputIt first,
     501              :         InputIt last);
     502              : 
     503              :     /** Overload
     504              :         @param s The string view to copy from.
     505              :     */
     506              :     string&
     507        17970 :     assign(string_view s)
     508              :     {
     509        17970 :         return assign(s.data(), s.size());
     510              :     }
     511              : 
     512              :     /** Overload
     513              :         @param other Another string.
     514              :     */
     515              :     BOOST_JSON_DECL
     516              :     string&
     517              :     assign(
     518              :         string const& other);
     519              : 
     520              :     /** Overload
     521              :         @param other
     522              :     */
     523              :     BOOST_JSON_DECL
     524              :     string&
     525              :     assign(string&& other);
     526              :     /// @}
     527              : 
     528              :     /** Return the associated memory resource.
     529              : 
     530              :         This function returns a smart pointer to the
     531              :         @ref boost::container::pmr::memory_resource used by the container.
     532              : 
     533              :         @par Complexity
     534              :         Constant.
     535              : 
     536              :         @par Exception Safety
     537              :         No-throw guarantee.
     538              :     */
     539              :     storage_ptr const&
     540          116 :     storage() const noexcept
     541              :     {
     542          116 :         return sp_;
     543              :     }
     544              : 
     545              :     /** Return the associated allocator.
     546              : 
     547              :         This function returns an instance of @ref allocator_type constructed
     548              :         from the associated @ref boost::container::pmr::memory_resource.
     549              : 
     550              :         @par Complexity
     551              :         Constant.
     552              : 
     553              :         @par Exception Safety
     554              :         No-throw guarantee.
     555              :     */
     556              :     allocator_type
     557            1 :     get_allocator() const noexcept
     558              :     {
     559            1 :         return sp_.get();
     560              :     }
     561              : 
     562              :     //------------------------------------------------------
     563              :     //
     564              :     // Element Access
     565              :     //
     566              :     //------------------------------------------------------
     567              : 
     568              :     /** Return a character with bounds checking.
     569              : 
     570              :         Returns @ref boost::system::result containing a reference to the
     571              :         character specified at location `pos`, if `pos` is within the range of
     572              :         the string. Otherwise the result contains an `error_code`.
     573              : 
     574              :         @par Exception Safety
     575              :         Strong guarantee.
     576              : 
     577              :         @param pos A zero-based index to access.
     578              : 
     579              :         @par Complexity
     580              :         Constant.
     581              : 
     582              :         @{
     583              :     */
     584              :     BOOST_JSON_DECL
     585              :     system::result<char&>
     586              :     try_at(std::size_t pos) noexcept;
     587              : 
     588              :     BOOST_JSON_DECL
     589              :     system::result<char const&>
     590              :     try_at(std::size_t pos) const noexcept;
     591              :     /// @}
     592              : 
     593              :     /** Return a character with bounds checking.
     594              : 
     595              :         Returns a reference to the character specified at location `pos`.
     596              : 
     597              :         @par Complexity
     598              :         Constant.
     599              : 
     600              :         @par Exception Safety
     601              :         Strong guarantee.
     602              : 
     603              :         @param pos A zero-based index to access.
     604              :         @param loc `source_location` to use in thrown exception; the source
     605              :                location of the call site by default.
     606              : 
     607              :         @throw boost::system::system_error `pos >=` @ref size().
     608              : 
     609              :         @{
     610              :     */
     611              :     inline
     612              :     char&
     613              :     at(
     614              :         std::size_t pos,
     615              :         source_location const& loc = BOOST_CURRENT_LOCATION);
     616              : 
     617              :     BOOST_JSON_DECL
     618              :     char const&
     619              :     at(
     620              :         std::size_t pos,
     621              :         source_location const& loc = BOOST_CURRENT_LOCATION) const;
     622              :     /// @}
     623              : 
     624              :     /** Return a character without bounds checking.
     625              : 
     626              :         Returns a reference to the character specified at location `pos`.
     627              : 
     628              :         @par Complexity
     629              :         Constant.
     630              : 
     631              :         @pre
     632              :         @code
     633              :         pos < size()
     634              :         @endcode
     635              : 
     636              :         @param pos A zero-based index to access.
     637              : 
     638              :         @{
     639              :     */
     640              :     char&
     641           18 :     operator[](std::size_t pos)
     642              :     {
     643           18 :         return impl_.data()[pos];
     644              :     }
     645              : 
     646              :     const char&
     647            2 :     operator[](std::size_t pos) const
     648              :     {
     649            2 :         return impl_.data()[pos];
     650              :     }
     651              :     /// @}
     652              : 
     653              :     /** Return the first character.
     654              : 
     655              :         Returns a reference to the first character.
     656              : 
     657              :         @pre
     658              :         @code
     659              :         ! empty()
     660              :         @endcode
     661              : 
     662              :         @par Complexity
     663              :         Constant.
     664              : 
     665              :         @par Exception Safety
     666              :         No-throw guarantee.
     667              : 
     668              :         @{
     669              :     */
     670              :     char&
     671           10 :     front()
     672              :     {
     673           10 :         return impl_.data()[0];
     674              :     }
     675              : 
     676              :     char const&
     677            6 :     front() const
     678              :     {
     679            6 :         return impl_.data()[0];
     680              :     }
     681              :     /// @}
     682              : 
     683              :     /** Return the last character.
     684              : 
     685              :         Returns a reference to the last character.
     686              : 
     687              :         @pre
     688              :         @code
     689              :         ! empty()
     690              :         @endcode
     691              : 
     692              :         @par Complexity
     693              :         Constant.
     694              : 
     695              :         @{
     696              :     */
     697              :     char&
     698           39 :     back()
     699              :     {
     700           39 :         return impl_.data()[impl_.size() - 1];
     701              :     }
     702              : 
     703              :     char const&
     704            6 :     back() const
     705              :     {
     706            6 :         return impl_.data()[impl_.size() - 1];
     707              :     }
     708              :     /// @}
     709              : 
     710              :     /** Return the underlying character array directly.
     711              : 
     712              :         Returns a pointer to the underlying array serving as storage. The value
     713              :         returned is such that the range `[data(), data() + size())` is always
     714              :         a valid range, even if the container is empty.
     715              : 
     716              :         @note The value returned from this function is never equal to
     717              :         `nullptr`.
     718              : 
     719              :         @par Complexity
     720              :         Constant.
     721              : 
     722              :         @par Exception Safety
     723              :         No-throw guarantee.
     724              : 
     725              :         @{
     726              :     */
     727              :     char*
     728        24103 :     data() noexcept
     729              :     {
     730        24103 :         return impl_.data();
     731              :     }
     732              : 
     733              :     char const*
     734        43980 :     data() const noexcept
     735              :     {
     736        43980 :         return impl_.data();
     737              :     }
     738              :     /// @@}
     739              : 
     740              :     /** Return the underlying character array directly.
     741              : 
     742              :         Returns a pointer to the underlying array serving as storage. The value
     743              :         returned is such that the range `[c_str(), c_str() + size())` is always
     744              :         a valid range, even if the container is empty.
     745              : 
     746              :         @note The value returned from this function is never equal to
     747              :         `nullptr`.
     748              : 
     749              :         @par Complexity
     750              :         Constant.
     751              :     */
     752              :     char const*
     753            4 :     c_str() const noexcept
     754              :     {
     755            4 :         return impl_.data();
     756              :     }
     757              : 
     758              :     /** Convert to a @ref string_view referring to the string.
     759              : 
     760              :         Returns a string view to the
     761              :         underlying character string. The size of the view
     762              :         does not include the null terminator.
     763              : 
     764              :         @par Complexity
     765              : 
     766              :         Constant.
     767              :     */
     768           57 :     operator string_view() const noexcept
     769              :     {
     770           57 :         return {data(), size()};
     771              :     }
     772              : 
     773              : #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
     774              :     /** Convert to @ref std::string_view referring to the string.
     775              : 
     776              :         Returns a string view to the underlying character string. The size of
     777              :         the view does not include the null terminator.
     778              : 
     779              :         This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW` is
     780              :         defined.
     781              : 
     782              :         @par Complexity
     783              : 
     784              :         Constant.
     785              :     */
     786              :     operator std::string_view() const noexcept
     787              :     {
     788              :         return {data(), size()};
     789              :     }
     790              : #endif
     791              : 
     792              :     //------------------------------------------------------
     793              :     //
     794              :     // Iterators
     795              :     //
     796              :     //------------------------------------------------------
     797              : 
     798              :     /** Return an iterator to the beginning.
     799              : 
     800              :         If the container is empty, @ref end() is returned.
     801              : 
     802              :         @par Complexity
     803              :         Constant.
     804              : 
     805              :         @par Exception Safety
     806              :         No-throw guarantee.
     807              : 
     808              :         @{
     809              :     */
     810              :     iterator
     811           34 :     begin() noexcept
     812              :     {
     813           34 :         return impl_.data();
     814              :     }
     815              : 
     816              :     const_iterator
     817            8 :     begin() const noexcept
     818              :     {
     819            8 :         return impl_.data();
     820              :     }
     821              :     /// @}
     822              : 
     823              :     /** Return a const iterator to the first element.
     824              : 
     825              :         If the container is empty, @ref cend() is returned.
     826              : 
     827              :         @par Complexity
     828              :         Constant.
     829              : 
     830              :         @par Exception Safety
     831              :         No-throw guarantee.
     832              :     */
     833              :     const_iterator
     834            2 :     cbegin() const noexcept
     835              :     {
     836            2 :         return impl_.data();
     837              :     }
     838              : 
     839              :     /** Return an iterator to the end.
     840              : 
     841              :         The returned iterator only acts as a sentinel. Dereferencing it results
     842              :         in undefined behavior.
     843              : 
     844              :         @par Complexity
     845              :         Constant.
     846              : 
     847              :         @par Exception Safety
     848              :         No-throw guarantee.
     849              : 
     850              :         @{
     851              :     */
     852              :     iterator
     853            3 :     end() noexcept
     854              :     {
     855            3 :         return impl_.end();
     856              :     }
     857              : 
     858              :     const_iterator
     859            3 :     end() const noexcept
     860              :     {
     861            3 :         return impl_.end();
     862              :     }
     863              :     /// @}
     864              : 
     865              :     /** Return a const iterator past the last element.
     866              : 
     867              :         The returned iterator only acts as a sentinel. Dereferencing it results
     868              :         in undefined behavior.
     869              : 
     870              :         @par Complexity
     871              :         Constant.
     872              : 
     873              :         @par Exception Safety
     874              :         No-throw guarantee.
     875              :     */
     876              :     const_iterator
     877            2 :     cend() const noexcept
     878              :     {
     879            2 :         return impl_.end();
     880              :     }
     881              : 
     882              :     /** Return a reverse iterator to the first character of the reversed container.
     883              : 
     884              :         Returns the pointed-to character that corresponds to the last character
     885              :         of the non-reversed container. If the container is empty, @ref rend()
     886              :         is returned.
     887              : 
     888              :         @par Complexity
     889              :         Constant.
     890              : 
     891              :         @{
     892              :     */
     893              :     reverse_iterator
     894            3 :     rbegin() noexcept
     895              :     {
     896            3 :         return reverse_iterator(impl_.end());
     897              :     }
     898              : 
     899              :     const_reverse_iterator
     900            3 :     rbegin() const noexcept
     901              :     {
     902            3 :         return const_reverse_iterator(impl_.end());
     903              :     }
     904              :     /// @}
     905              : 
     906              :     /** Return a const reverse iterator to the first element of the reversed container.
     907              : 
     908              :         Returns the pointed-to character that corresponds to the last character
     909              :         of the non-reversed container. If the container is empty, @ref crend()
     910              :         is returned.
     911              : 
     912              :         @par Complexity
     913              :         Constant.
     914              : 
     915              :         @par Exception Safety
     916              :         No-throw guarantee.
     917              :     */
     918              :     const_reverse_iterator
     919            2 :     crbegin() const noexcept
     920              :     {
     921            2 :         return const_reverse_iterator(impl_.end());
     922              :     }
     923              : 
     924              :     /** Return a reverse iterator to the character following the last character of the reversed container.
     925              : 
     926              :         The pointed-to element corresponds to the element preceding the first
     927              :         element of the non-reversed container. The returned iterator only acts
     928              :         as a sentinel. Dereferencing it results in undefined behavior.
     929              : 
     930              :         @par Complexity
     931              :         Constant.
     932              : 
     933              :         @par Exception Safety
     934              :         No-throw guarantee.
     935              : 
     936              :         @{
     937              :     */
     938              :     reverse_iterator
     939            3 :     rend() noexcept
     940              :     {
     941            3 :         return reverse_iterator(begin());
     942              :     }
     943              : 
     944              :     const_reverse_iterator
     945            3 :     rend() const noexcept
     946              :     {
     947            3 :         return const_reverse_iterator(begin());
     948              :     }
     949              :     /// @}
     950              : 
     951              :     /** Return a const reverse iterator to the character following the last character of the reversed container.
     952              : 
     953              :         The pointed-to character corresponds to the character preceding the
     954              :         first character of the non-reversed container. The returned iterator
     955              :         only acts as a sentinel. Dereferencing it results in undefined
     956              :         behavior.
     957              : 
     958              :         @par Complexity
     959              :         Constant.
     960              : 
     961              :         @par Exception Safety
     962              :         No-throw guarantee.
     963              :     */
     964              :     const_reverse_iterator
     965            2 :     crend() const noexcept
     966              :     {
     967            2 :         return const_reverse_iterator(begin());
     968              :     }
     969              : 
     970              :     //------------------------------------------------------
     971              :     //
     972              :     // Capacity
     973              :     //
     974              :     //------------------------------------------------------
     975              : 
     976              :     /** Check if the string has no characters.
     977              : 
     978              :         Returns `true` if there are no characters in the string, i.e. @ref
     979              :         size() returns 0.
     980              : 
     981              :         @par Complexity
     982              :         Constant.
     983              : 
     984              :         @par Exception Safety
     985              :         No-throw guarantee.
     986              :     */
     987              :     bool
     988           69 :     empty() const noexcept
     989              :     {
     990           69 :         return impl_.size() == 0;
     991              :     }
     992              : 
     993              :     /** Return the number of characters in the string.
     994              : 
     995              :         The value returned does not include the null terminator, which is
     996              :         always present.
     997              : 
     998              :         @par Complexity
     999              :         Constant.
    1000              :     */
    1001              :     std::size_t
    1002        47864 :     size() const noexcept
    1003              :     {
    1004        47864 :         return impl_.size();
    1005              :     }
    1006              : 
    1007              :     /** Return the maximum number of characters any string can hold.
    1008              : 
    1009              :         The maximum is an implementation-defined number. This value is
    1010              :         a theoretical limit; at runtime, the actual maximum size may be less
    1011              :         due to resource limits.
    1012              : 
    1013              :         @par Complexity
    1014              :         Constant.
    1015              :     */
    1016              :     static
    1017              :     constexpr
    1018              :     std::size_t
    1019         7895 :     max_size() noexcept
    1020              :     {
    1021         7895 :         return string_impl::max_size();
    1022              :     }
    1023              : 
    1024              :     /** Return the number of characters that can be held in currently allocated memory.
    1025              : 
    1026              :         Returns the number of characters that the container has currently
    1027              :         allocated space for. This number is never smaller than the value
    1028              :         returned by @ref size().
    1029              : 
    1030              :         @par Complexity
    1031              :         Constant.
    1032              : 
    1033              :         @par Exception Safety
    1034              :         No-throw guarantee.
    1035              :     */
    1036              :     std::size_t
    1037        11691 :     capacity() const noexcept
    1038              :     {
    1039        11691 :         return impl_.capacity();
    1040              :     }
    1041              : 
    1042              :     /** Increase the capacity to at least a certain amount.
    1043              : 
    1044              :         This increases the capacity of the array to a value that is greater
    1045              :         than or equal to `new_capacity`. If `new_capacity > `@ref capacity(),
    1046              :         new memory is allocated. Otherwise, the call has no effect. The number
    1047              :         of elements and therefore the @ref size() of the container is not
    1048              :         changed.
    1049              : 
    1050              :         If new memory is allocated, all iterators including any past-the-end
    1051              :         iterators, and all references to the elements are invalidated.
    1052              :         Otherwise, no iterators or references are invalidated.
    1053              : 
    1054              :         @par Complexity
    1055              :         At most, linear in @ref size().
    1056              : 
    1057              :         @par Exception Safety
    1058              :         Strong guarantee. Calls to `memory_resource::allocate` may throw.
    1059              : 
    1060              :         @param new_capacity The new capacity of the array.
    1061              : 
    1062              :         @throw boost::system::system_error `new_capacity > `@ref max_size().
    1063              :     */
    1064              :     void
    1065        11381 :     reserve(std::size_t new_capacity)
    1066              :     {
    1067        11381 :         if(new_capacity <= capacity())
    1068         1695 :             return;
    1069         9686 :         reserve_impl(new_capacity);
    1070              :     }
    1071              : 
    1072              :     /** Request the removal of unused capacity.
    1073              : 
    1074              :         This performs a non-binding request to reduce @ref capacity() to
    1075              :         @ref size(). The request may or may not be fulfilled.
    1076              : 
    1077              :         @note If reallocation occurs, all iterators including  any past-the-end
    1078              :         iterators, and all references to characters are invalidated. Otherwise,
    1079              :         no iterators or references are invalidated.
    1080              : 
    1081              :         @par Complexity
    1082              :         At most, linear in @ref size().
    1083              :     */
    1084              :     BOOST_JSON_DECL
    1085              :     void
    1086              :     shrink_to_fit();
    1087              : 
    1088              :     //------------------------------------------------------
    1089              :     //
    1090              :     // Operations
    1091              :     //
    1092              :     //------------------------------------------------------
    1093              : 
    1094              :     /** Clear the contents.
    1095              : 
    1096              :         Erases all characters from the string. After this call, @ref size()
    1097              :         returns zero but @ref capacity() is unchanged. All references,
    1098              :         pointers, or iterators referring to contained elements are invalidated.
    1099              :         Any past-the-end iterators are also invalidated.
    1100              : 
    1101              :         @par Complexity
    1102              :         Linear in @ref size().
    1103              : 
    1104              :         @par Exception Safety
    1105              :         No-throw guarantee.
    1106              :     */
    1107              :     BOOST_JSON_DECL
    1108              :     void
    1109              :     clear() noexcept;
    1110              : 
    1111              :     /** Insert characters at the specified index.
    1112              : 
    1113              :         @li **(1)** inserts `sv`.
    1114              :         @li **(2)** inserts `count` copies of `ch`.
    1115              :         @li **(3)** inserts the character `ch`.
    1116              :         @li **(4)** inserts characters from the range `[first, last)`.
    1117              : 
    1118              :         The first character is inserted at the index `pos`. All references,
    1119              :         pointers, or iterators referring to contained elements are invalidated.
    1120              :         Any past-the-end iterators are also invalidated.
    1121              : 
    1122              :         @par Constraints
    1123              :         `InputIt` satisfies {req_InputIterator}.
    1124              : 
    1125              :         @pre
    1126              :         `[first, last)` is a valid range.
    1127              : 
    1128              :         @par Exception Safety
    1129              :         @li **(1)**--*(3)* strong guarantee.
    1130              :         @li **(4)** strong guarantee if `InputIt` satisfies
    1131              :             {req_ForwardIterator}, basic guarantee otherwise.
    1132              : 
    1133              :         @return `*this`
    1134              : 
    1135              :         @param pos The index to insert at.
    1136              :         @param sv The `string_view` to insert.
    1137              : 
    1138              :         @throw boost::system::system_error The size of the string would exceed
    1139              :                @ref max_size().
    1140              : 
    1141              :         @throw boost::system::system_error `pos > `@ref size().
    1142              : 
    1143              :         @{
    1144              :     */
    1145              :     BOOST_JSON_DECL
    1146              :     string&
    1147              :     insert(
    1148              :         std::size_t pos,
    1149              :         string_view sv);
    1150              : 
    1151              :     /** Overload
    1152              :         @param count The number of characters to insert.
    1153              :         @param ch The character to insert.
    1154              :         @param pos
    1155              :     */
    1156              :     BOOST_JSON_DECL
    1157              :     string&
    1158              :     insert(
    1159              :         std::size_t pos,
    1160              :         std::size_t count,
    1161              :         char ch);
    1162              : 
    1163              :     /** Overload
    1164              :         @param pos
    1165              :         @param ch
    1166              :     */
    1167              :     string&
    1168            3 :     insert(
    1169              :         size_type pos,
    1170              :         char ch)
    1171              :     {
    1172            3 :         return insert(pos, 1, ch);
    1173              :     }
    1174              : 
    1175              :     /** Overload
    1176              : 
    1177              :         @tparam InputIt The type of the iterators.
    1178              : 
    1179              :         @param first The beginning of the character range.
    1180              :         @param last The end of the character range.
    1181              :         @param pos
    1182              :     */
    1183              :     template<class InputIt
    1184              :     #ifndef BOOST_JSON_DOCS
    1185              :         ,class = is_inputit<InputIt>
    1186              :     #endif
    1187              :     >
    1188              :     string&
    1189              :     insert(
    1190              :         size_type pos,
    1191              :         InputIt first,
    1192              :         InputIt last);
    1193              :     /// @}
    1194              : 
    1195              :     /** Remove characters from the string.
    1196              : 
    1197              :         @li **(1)** removes at most `count` but not more than `size() - pos`
    1198              :             characters starting at `index`.
    1199              :         @li **(2)** removes the character at `pos`.
    1200              :         @li **(3)** removes characters in the range `[first, last)`.
    1201              : 
    1202              :         All references, pointers, or iterators referring to contained elements
    1203              :         are invalidated. Any past-the-end iterators are also invalidated.
    1204              : 
    1205              :         @pre
    1206              :         `pos`, `first`, and `last` are iterators into this string. `first` and
    1207              :         `last` form a valid range.
    1208              : 
    1209              :         @par Complexity
    1210              :         @li **(1)** linear in `count`.
    1211              :         @li **(2)** constant.
    1212              :         @li **(3)** linear in `std::distance(first, last)`.
    1213              : 
    1214              :         @par Exception Safety
    1215              :         Strong guarantee.
    1216              : 
    1217              :         @return
    1218              :         @li **(1)** `*this`.
    1219              : 
    1220              :         @li **(2)** An iterator referring to the character immediately
    1221              :         following the removed character, or @ref end() if one does not exist.
    1222              : 
    1223              :         @li **(3)** An iterator referring to the character `last` previously
    1224              :         referred to, or @ref end() if one does not exist.
    1225              : 
    1226              :         @param index The index of the first character to remove.
    1227              : 
    1228              :         @param count The number of characters to remove. By default remove
    1229              :         until the end of the string.
    1230              : 
    1231              :         @throw boost::system::system_error `pos >` @ref size().
    1232              : 
    1233              :         @{
    1234              :     */
    1235              :     BOOST_JSON_DECL
    1236              :     string&
    1237              :     erase(
    1238              :         std::size_t index = 0,
    1239              :         std::size_t count = npos);
    1240              : 
    1241              :     /** Overload
    1242              :         @param pos An iterator referring to the character to erase.
    1243              :     */
    1244              :     BOOST_JSON_DECL
    1245              :     iterator
    1246              :     erase(const_iterator pos);
    1247              : 
    1248              :     /** Overload
    1249              :         @param first An iterator representing the first character to erase.
    1250              :         @param last An iterator one past the last character to erase.
    1251              :     */
    1252              :     BOOST_JSON_DECL
    1253              :     iterator
    1254              :     erase(
    1255              :         const_iterator first,
    1256              :         const_iterator last);
    1257              :     /// @}
    1258              : 
    1259              :     //------------------------------------------------------
    1260              : 
    1261              :     /** Append a character.
    1262              : 
    1263              :         Appends a character to the end of the string.
    1264              : 
    1265              :         @par Exception Safety
    1266              :         Strong guarantee.
    1267              : 
    1268              :         @param ch The character to append.
    1269              : 
    1270              :         @throw boost::system::system_error @ref size() `+ 1 > `@ref max_size().
    1271              :     */
    1272              :     BOOST_JSON_DECL
    1273              :     void
    1274              :     push_back(char ch);
    1275              : 
    1276              :     /** Remove the last character.
    1277              : 
    1278              :         Removes a character from the end of the string.
    1279              : 
    1280              :         @pre
    1281              :         @code
    1282              :         ! empty()
    1283              :         @endcode
    1284              :     */
    1285              :     BOOST_JSON_DECL
    1286              :     void
    1287              :     pop_back();
    1288              : 
    1289              :     //------------------------------------------------------
    1290              : 
    1291              :     /** Append characters to the string.
    1292              : 
    1293              :         @li **(1)** appends `count` copies of `ch`.
    1294              : 
    1295              :         @li **(2)** appends copies of characters of `sv`, preserving order.
    1296              : 
    1297              :         @li **(3)** appends characters from the range `[first, last)`,
    1298              :         preserving order.
    1299              : 
    1300              :         @pre
    1301              :         `[first, last)` shall be a valid range.
    1302              : 
    1303              :         @par Constraints
    1304              :         `InputIt` satisfies {req_InputIterator}.
    1305              : 
    1306              :         @par Exception Safety
    1307              :         Strong guarantee.
    1308              : 
    1309              :         @return `*this`.
    1310              : 
    1311              :         @param count The number of characters to append.
    1312              :         @param ch The character to append.
    1313              : 
    1314              :         @throw boost::system::system_error The size of the string after the
    1315              :         operation would exceed @ref max_size().
    1316              : 
    1317              :         @{
    1318              :     */
    1319              :     BOOST_JSON_DECL
    1320              :     string&
    1321              :     append(
    1322              :         std::size_t count,
    1323              :         char ch);
    1324              : 
    1325              :     /** Overload
    1326              :         @param sv The `string_view` to append.
    1327              :     */
    1328              :     BOOST_JSON_DECL
    1329              :     string&
    1330              :     append(string_view sv);
    1331              : 
    1332              :     /** Overload
    1333              : 
    1334              :         @tparam InputIt The type of the iterators.
    1335              : 
    1336              :         @param first An iterator representing the first character to append.
    1337              :         @param last An iterator one past the last character to append.
    1338              :     */
    1339              :     template<class InputIt
    1340              :     #ifndef BOOST_JSON_DOCS
    1341              :         ,class = is_inputit<InputIt>
    1342              :     #endif
    1343              :     >
    1344              :     string&
    1345              :     append(InputIt first, InputIt last);
    1346              :     /// @}
    1347              : 
    1348              :     /** Append characters to the string.
    1349              : 
    1350              :         @li **(1)** appends `[sv.begin(), sv.end())`.
    1351              :         @li **(2)** appends `ch`.
    1352              : 
    1353              :         @par Exception Safety
    1354              :         Strong guarantee.
    1355              : 
    1356              :         @return `*this`
    1357              : 
    1358              :         @param sv The `string_view` to append.
    1359              : 
    1360              :         @throw boost::system::system_error The size of the string after the
    1361              :         operation would exceed @ref max_size().
    1362              : 
    1363              :         @{
    1364              :     */
    1365              :     string&
    1366           11 :     operator+=(string_view sv)
    1367              :     {
    1368           11 :         return append(sv);
    1369              :     }
    1370              : 
    1371              :     /** Overload
    1372              :         @param ch The character to append.
    1373              :     */
    1374              :     string&
    1375           44 :     operator+=(char ch)
    1376              :     {
    1377           44 :         push_back(ch);
    1378           43 :         return *this;
    1379              :     }
    1380              :     /// @}
    1381              : 
    1382              :     //------------------------------------------------------
    1383              : 
    1384              :     /** Compare a string with the string.
    1385              : 
    1386              :         Let `comp` be `std::char_traits<char>::compare(data(), sv.data(),
    1387              :         std::min(size(), sv.size())`. If `comp != 0`, then the result is
    1388              :         `comp`. Otherwise, the result is `0` if `size() == sv.size()`, `-1` if
    1389              :         `size() < sv.size()`, and `1` otherwise.
    1390              : 
    1391              :         @par Complexity
    1392              :         Linear.
    1393              : 
    1394              :         @return The result of lexicographically comparing the characters of
    1395              :         `sv` and the string.
    1396              : 
    1397              :         @param sv The `string_view` to compare.
    1398              :     */
    1399              :     int
    1400           13 :     compare(string_view sv) const noexcept
    1401              :     {
    1402           13 :         return subview().compare(sv);
    1403              :     }
    1404              : 
    1405              :     //------------------------------------------------------
    1406              : 
    1407              :     /** Return whether the string begins with another string.
    1408              : 
    1409              :         @li **(1)** checks if the string begins with `s`.
    1410              :         @li **(2)** checks if the string begins with `ch`.
    1411              : 
    1412              :         @par Complexity
    1413              :         @li **(1)** linear in `s.size()`.
    1414              :         @li **(2)** constant.
    1415              : 
    1416              :         @param s The string to check for.
    1417              : 
    1418              :         @{
    1419              :     */
    1420              :     bool
    1421            8 :     starts_with(string_view s) const noexcept
    1422              :     {
    1423            8 :         return subview(0, s.size()) == s;
    1424              :     }
    1425              : 
    1426              :     /** Overload
    1427              : 
    1428              :         @param ch The character to check for.
    1429              :     */
    1430              :     bool
    1431            4 :     starts_with(char ch) const noexcept
    1432              :     {
    1433            4 :         return ! empty() && front() == ch;
    1434              :     }
    1435              :     /// @}
    1436              : 
    1437              :     /** Check if the string ends with given suffix.
    1438              : 
    1439              :         @li **(1)** returns `true` if the string ends with `s`.
    1440              :         @li **(2)** returns `true` if the string ends with the character `ch`.
    1441              : 
    1442              :         @par Complexity
    1443              :         @li **(1)** linear in `s`.
    1444              :         @li **(2)** constant.
    1445              : 
    1446              :         @par Exception Safety
    1447              :         No-throw guarantee.
    1448              : 
    1449              :         @param s The string to check for.
    1450              : 
    1451              :         @{
    1452              :     */
    1453              :     bool
    1454            8 :     ends_with(string_view s) const noexcept
    1455              :     {
    1456           16 :         return size() >= s.size() &&
    1457           16 :             subview(size() - s.size()) == s;
    1458              :     }
    1459              : 
    1460              :     /** Overload
    1461              :         @param ch The character to check for.
    1462              :     */
    1463              :     bool
    1464            4 :     ends_with(char ch) const noexcept
    1465              :     {
    1466            4 :         return ! empty() && back() == ch;
    1467              :     }
    1468              :     /// @}
    1469              : 
    1470              :     /** Replace a substring with another string.
    1471              : 
    1472              :         @li **(1)** replaces `std::min(count, size() - pos)` characters
    1473              :             starting at index `pos` with those of `sv`.
    1474              :         @li **(2)** replaces the characters in the range `[first, last)` with
    1475              :             those of `sv`.
    1476              :         @li **(3)** replaces the characters in the range `[first, last)` with
    1477              :             those of `[first2, last2)`.
    1478              :         @li **(4)** replaces `std::min(count, size() - pos)` characters
    1479              :             starting at index `pos` with `count2` copies of `ch`.
    1480              :         @li **(5)** replaces the characters in the range `[first, last)` with
    1481              :             `count2` copies of `ch`.
    1482              : 
    1483              :         All references, pointers, or iterators referring to contained elements
    1484              :         are invalidated. Any past-the-end iterators are also invalidated.
    1485              : 
    1486              :         @pre
    1487              :         `[first, last)` is a valid range. `[first2, last2)` is a valid range.
    1488              : 
    1489              :         @par Constraints
    1490              :         `InputIt` satisfies {req_InputIterator}.
    1491              : 
    1492              :         @par Exception Safety
    1493              :         Strong guarantee.
    1494              : 
    1495              :         @return `*this`
    1496              : 
    1497              :         @param pos The index to replace at.
    1498              : 
    1499              :         @param count The number of characters to replace.
    1500              : 
    1501              :         @param sv The `string_view` to replace with.
    1502              : 
    1503              :         @throw boost::system::system_error The resulting string's size would
    1504              :                have exceeded @ref max_size().
    1505              : 
    1506              :         @{
    1507              :     */
    1508              :     BOOST_JSON_DECL
    1509              :     string&
    1510              :     replace(
    1511              :         std::size_t pos,
    1512              :         std::size_t count,
    1513              :         string_view sv);
    1514              : 
    1515              :     /** Overload
    1516              : 
    1517              :         @param first An iterator referring to the first character to replace.
    1518              :         @param last An iterator one past the end of the last character to
    1519              :                replace.
    1520              :         @param sv
    1521              :     */
    1522              :     string&
    1523            6 :     replace(
    1524              :         const_iterator first,
    1525              :         const_iterator last,
    1526              :         string_view sv)
    1527              :     {
    1528            6 :         return replace(first - begin(), last - first, sv);
    1529              :     }
    1530              : 
    1531              :     /** Overload
    1532              : 
    1533              :         @tparam InputIt The type of the iterators.
    1534              : 
    1535              :         @param first2 An iterator referring to the first character to replace
    1536              :                with.
    1537              :         @param last2 An iterator one past the end of the last character to
    1538              :                replace with.
    1539              :         @param first
    1540              :         @param last
    1541              :     */
    1542              :     template<class InputIt
    1543              :     #ifndef BOOST_JSON_DOCS
    1544              :         ,class = is_inputit<InputIt>
    1545              :     #endif
    1546              :     >
    1547              :     string&
    1548              :     replace(
    1549              :         const_iterator first,
    1550              :         const_iterator last,
    1551              :         InputIt first2,
    1552              :         InputIt last2);
    1553              : 
    1554              :     /** Overload
    1555              : 
    1556              :         @param count2 The number of characters to replace with.
    1557              :         @param ch The character to replace with.
    1558              :         @param pos
    1559              :         @param count
    1560              :     */
    1561              :     BOOST_JSON_DECL
    1562              :     string&
    1563              :     replace(
    1564              :         std::size_t pos,
    1565              :         std::size_t count,
    1566              :         std::size_t count2,
    1567              :         char ch);
    1568              : 
    1569              :     /** Overload
    1570              : 
    1571              :         @param first
    1572              :         @param last
    1573              :         @param count2
    1574              :         @param ch
    1575              :     */
    1576              :     string&
    1577            1 :     replace(
    1578              :         const_iterator first,
    1579              :         const_iterator last,
    1580              :         std::size_t count2,
    1581              :         char ch)
    1582              :     {
    1583            1 :         return replace(first - begin(), last - first, count2, ch);
    1584              :     }
    1585              :     /// @}
    1586              : 
    1587              :     //------------------------------------------------------
    1588              : 
    1589              :     /** Return a view.
    1590              : 
    1591              :         @li **(1)** equivalent to `subview().substr(pos, count)`.
    1592              :         @li **(2)** equivalent to `string_view(data(), size())`.
    1593              : 
    1594              :         @par Exception Safety
    1595              :         Strong guarantee.
    1596              : 
    1597              :         @param pos The index of the first character of the substring.
    1598              :         @param count The length of the substring.
    1599              : 
    1600              :         @throw boost::system::system_error `pos > ` @ref size().
    1601              :     */
    1602              :     string_view
    1603           41 :     subview(
    1604              :         std::size_t pos,
    1605              :         std::size_t count = npos) const
    1606              :     {
    1607           41 :         return subview().substr(pos, count);
    1608              :     }
    1609              : 
    1610              :     /// Overload
    1611              :     string_view
    1612        28988 :     subview() const noexcept
    1613              :     {
    1614        28988 :         return string_view( data(), size() );
    1615              :     }
    1616              : 
    1617              :     //------------------------------------------------------
    1618              : 
    1619              :     /** Copy a substring to another string.
    1620              : 
    1621              :         Copies `std::min(count, size() - pos)` characters starting at index
    1622              :         `pos` to the string pointed to by `dest`.
    1623              : 
    1624              :         @attention This function doesn't put the null terminator after the
    1625              :         copied characters.
    1626              : 
    1627              :         @return The number of characters copied.
    1628              : 
    1629              :         @param count The number of characters to copy.
    1630              : 
    1631              :         @param dest The string to copy to.
    1632              : 
    1633              :         @param pos The index to begin copying from.
    1634              : 
    1635              :         @throw boost::system::system_error `pos >` @ref max_size().
    1636              :     */
    1637              :     std::size_t
    1638            2 :     copy(
    1639              :         char* dest,
    1640              :         std::size_t count,
    1641              :         std::size_t pos = 0) const
    1642              :     {
    1643            2 :         return subview().copy(dest, count, pos);
    1644              :     }
    1645              : 
    1646              :     //------------------------------------------------------
    1647              : 
    1648              :     /** Change the size of the string.
    1649              : 
    1650              :         Resizes the string to contain `count` characters. If
    1651              :         `count > `@ref size(), **(2)** appends copies of `ch` and **(1)**
    1652              :         appends ``'\0'``. Otherwise, `size()` is reduced to `count`.
    1653              : 
    1654              :         @param count The size to resize the string to.
    1655              : 
    1656              :         @throw boost::system::system_error `count > `@ref max_size().
    1657              : 
    1658              :         @{
    1659              :     */
    1660              :     void
    1661           57 :     resize(std::size_t count)
    1662              :     {
    1663           57 :         resize(count, 0);
    1664           54 :     }
    1665              : 
    1666              :     /** Overload
    1667              : 
    1668              :         @param count
    1669              :         @param ch The characters to append if the size increases.
    1670              :     */
    1671              :     BOOST_JSON_DECL
    1672              :     void
    1673              :     resize(std::size_t count, char ch);
    1674              :     /// @}
    1675              : 
    1676              :     /** Increase size without changing capacity.
    1677              : 
    1678              :         This increases the size of the string by `n` characters, adjusting the
    1679              :         position of the terminating null character for the new size. The new
    1680              :         characters remain uninitialized. This function may be used to append
    1681              :         characters directly into the storage between @ref end() and @ref data()
    1682              :         ` + ` @ref capacity().
    1683              : 
    1684              :         @pre
    1685              :         @code
    1686              :         count <= capacity() - size()
    1687              :         @endcode
    1688              : 
    1689              :         @param n The amount to increase the size by.
    1690              :     */
    1691              :     void
    1692        15153 :     grow(std::size_t n) noexcept
    1693              :     {
    1694        15153 :         BOOST_ASSERT(
    1695              :             n <= impl_.capacity() - impl_.size());
    1696        15153 :         impl_.term(impl_.size() + n);
    1697        15153 :     }
    1698              : 
    1699              :     /** Swap the contents.
    1700              : 
    1701              :         Exchanges the contents of this string with another string. Ownership of
    1702              :         the respective @ref boost::container::pmr::memory_resource objects is
    1703              :         not transferred.
    1704              : 
    1705              :         @li If `&other == this`, do nothing. Otherwise,
    1706              :         @li if `*other.storage() == *this->storage()`, ownership of the
    1707              :             underlying memory is swapped in constant time, with no possibility
    1708              :             of exceptions. All iterators and references remain valid.
    1709              :             Otherwise,
    1710              :         @li the contents are logically swapped by making copies, which can
    1711              :             throw. In this case all iterators and references are invalidated.
    1712              : 
    1713              :         @par Complexity
    1714              :         Constant or linear in @ref size() `+ other.size()`.
    1715              : 
    1716              :         @par Exception Safety
    1717              :         Strong guarantee. Calls to `memory_resource::allocate` may throw.
    1718              :     */
    1719              :     BOOST_JSON_DECL
    1720              :     void
    1721              :     swap(string& other);
    1722              : 
    1723              :     /** Exchange the given values.
    1724              : 
    1725              :         Exchanges the contents of the string `lhs` with another string `rhs`.
    1726              :         Ownership of the respective @ref boost::container::pmr::memory_resource
    1727              :         objects is not transferred.
    1728              : 
    1729              :         @li If `&lhs == &rhs`, do nothing. Otherwise,
    1730              :         @li if `*lhs.storage() == *rhs.storage()`, ownership of the underlying
    1731              :             memory is swapped in constant time, with no possibility of
    1732              :             exceptions. All iterators and references remain valid. Otherwise,
    1733              :         @li the contents are logically swapped by making a copy, which can
    1734              :             throw. In this case all iterators and references are invalidated.
    1735              : 
    1736              :         @par Effects
    1737              :         @code
    1738              :         lhs.swap( rhs );
    1739              :         @endcode
    1740              : 
    1741              :         @par Complexity
    1742              :         Constant or linear in `lhs.size() + rhs.size()`.
    1743              : 
    1744              :         @par Exception Safety
    1745              :         Strong guarantee.
    1746              :         Calls to `memory_resource::allocate` may throw.
    1747              : 
    1748              :         @param lhs The string to exchange.
    1749              :         @param rhs The string to exchange.
    1750              : 
    1751              :         @see @ref string::swap
    1752              :     */
    1753              :     friend
    1754              :     void
    1755            2 :     swap(string& lhs, string& rhs)
    1756              :     {
    1757            2 :         lhs.swap(rhs);
    1758            2 :     }
    1759              :     //------------------------------------------------------
    1760              :     //
    1761              :     // Search
    1762              :     //
    1763              :     //------------------------------------------------------
    1764              : 
    1765              :     /** Find the first occurrence of characters within the string.
    1766              : 
    1767              :         Search from `pos` onward for the first substring that is equal to the
    1768              :         first argument.
    1769              : 
    1770              :         @li **(1)** searches for the presense of the substring equal to `sv`.
    1771              :         @li **(2)** searches for the presense of the substring consisting of
    1772              :             the character `ch`.
    1773              : 
    1774              :         @par Complexity
    1775              :         Linear in @ref size().
    1776              : 
    1777              :         @par Exception Safety
    1778              :         No-throw guarantee.
    1779              : 
    1780              :         @return The index of the first character of the found substring, or
    1781              :         @ref npos if none was found.
    1782              : 
    1783              :         @param sv The `string_view` to search for.
    1784              :         @param pos The index to start searching at.
    1785              : 
    1786              :         @{
    1787              :     */
    1788              :     std::size_t
    1789            5 :     find(
    1790              :         string_view sv,
    1791              :         std::size_t pos = 0) const noexcept
    1792              :     {
    1793            5 :         return subview().find(sv, pos);
    1794              :     }
    1795              : 
    1796              :     /** Overload
    1797              : 
    1798              :         @param ch The character to search for.
    1799              :         @param pos
    1800              :     */
    1801              :     std::size_t
    1802            3 :     find(
    1803              :         char ch,
    1804              :         std::size_t pos = 0) const noexcept
    1805              :     {
    1806            3 :         return subview().find(ch, pos);
    1807              :     }
    1808              :     /// @}
    1809              : 
    1810              :     /** Find the last occurrence of a string within the string.
    1811              : 
    1812              :         @li **(1)** searches for the last substring equal to `sv`.
    1813              :         @li **(2)** searches for the last occurrence of `ch`.
    1814              : 
    1815              :         Both functions search for substrings fully contained within `[begin(),
    1816              :         begin() + pos)`.
    1817              : 
    1818              :         @par Complexity
    1819              :         Linear.
    1820              : 
    1821              :         @return Index of the first character of the found substring or
    1822              :                 @ref npos if none was found.
    1823              : 
    1824              :         @param sv The string to search for.
    1825              :         @param pos The index to start searching at. By default searches from
    1826              :                the end of the string.
    1827              : 
    1828              :         @{
    1829              :     */
    1830              :     std::size_t
    1831            5 :     rfind(
    1832              :         string_view sv,
    1833              :         std::size_t pos = npos) const noexcept
    1834              :     {
    1835            5 :         return subview().rfind(sv, pos);
    1836              :     }
    1837              : 
    1838              :     /** Overload
    1839              : 
    1840              :         @param ch The character to search for.
    1841              :         @param pos
    1842              :     */
    1843              :     std::size_t
    1844            3 :     rfind(
    1845              :         char ch,
    1846              :         std::size_t pos = npos) const noexcept
    1847              :     {
    1848            3 :         return subview().rfind(ch, pos);
    1849              :     }
    1850              :     /// @}
    1851              : 
    1852              :     //------------------------------------------------------
    1853              : 
    1854              :     /** Find the first character present in the specified string.
    1855              : 
    1856              :         Search from `pos` onward for the first character in this string that is
    1857              :         equal to any of the characters of `sv`.
    1858              : 
    1859              :         @par Complexity
    1860              :         Linear in @ref size() `+ sv.size()`.
    1861              : 
    1862              :         @par Exception Safety
    1863              :         No-throw guarantee.
    1864              : 
    1865              :         @return The index of the found character, or @ref npos if none exists.
    1866              : 
    1867              :         @param sv The characters to search for.
    1868              :         @param pos The index to start searching at.
    1869              :     */
    1870              :     std::size_t
    1871            5 :     find_first_of(
    1872              :         string_view sv,
    1873              :         std::size_t pos = 0) const noexcept
    1874              :     {
    1875            5 :         return subview().find_first_of(sv, pos);
    1876              :     }
    1877              : 
    1878              :     /** Find the first character missing from the specified string.
    1879              : 
    1880              :         Search from `pos` onward for the first character in this string that is
    1881              :         not equal to any of the characters in the string provided as the first
    1882              :         argument.
    1883              : 
    1884              :         @li **(1)** compares with the characters in `sv`.
    1885              :         @li **(2)** compares with the character `ch`.
    1886              : 
    1887              :         @par Complexity
    1888              :         @li **(1)** linear in @ref size() `+ sv.size()`.
    1889              :         @li **(2)** linear in @ref size().
    1890              : 
    1891              :         @par Exception Safety
    1892              :         No-throw guarantee.
    1893              : 
    1894              :         @return The index of the found character, or @ref npos if none exists.
    1895              : 
    1896              :         @param sv The characters to compare with.
    1897              :         @param pos The index to start searching at.
    1898              : 
    1899              :         @{
    1900              :     */
    1901              :     std::size_t
    1902            4 :     find_first_not_of(
    1903              :         string_view sv,
    1904              :         std::size_t pos = 0) const noexcept
    1905              :     {
    1906            4 :         return subview().find_first_not_of(sv, pos);
    1907              :     }
    1908              : 
    1909              :     /** Overload
    1910              :         @param ch The character to compare with.
    1911              :         @param pos
    1912              :     */
    1913              :     std::size_t
    1914            3 :     find_first_not_of(
    1915              :         char ch,
    1916              :         std::size_t pos = 0) const noexcept
    1917              :     {
    1918            3 :         return subview().find_first_not_of(ch, pos);
    1919              :     }
    1920              :     /// @}
    1921              : 
    1922              :     /** Find the last character present in the specified string.
    1923              : 
    1924              :         Search from `pos` backwards for the first character in this string that
    1925              :         is equal to any of the characters of `sv`. If `pos` is equal to @ref
    1926              :         npos (the default), search from the last character.
    1927              : 
    1928              :         @par Complexity
    1929              :         Linear in @ref size() `+ sv.size()`.
    1930              : 
    1931              :         @par Exception Safety
    1932              :         No-throw guarantee.
    1933              : 
    1934              :         @return The index of the found character, or @ref npos if none exists.
    1935              : 
    1936              :         @param sv The characters to search for.
    1937              :         @param pos The index to start searching at.
    1938              :     */
    1939              :     std::size_t
    1940            5 :     find_last_of(
    1941              :         string_view sv,
    1942              :         std::size_t pos = npos) const noexcept
    1943              :     {
    1944            5 :         return subview().find_last_of(sv, pos);
    1945              :     }
    1946              : 
    1947              :     /** Find the last character missing from the specified string.
    1948              : 
    1949              : 
    1950              :         Search from `pos` backwards for the first character in this string that
    1951              :         is not equal to any of the characters in the string provided as the
    1952              :         first argument. If `pos` is equal to @ref npos (the default), search
    1953              :         from the last character.
    1954              : 
    1955              :         @li **(1)** compares with the characters in `sv`.
    1956              :         @li **(2)** compares with the character `ch`.
    1957              : 
    1958              :         @par Complexity
    1959              :         @li **(1)** linear in @ref size() `+ sv.size()`.
    1960              :         @li **(2)** linear in @ref size().
    1961              : 
    1962              :         @par Exception Safety
    1963              :         No-throw guarantee.
    1964              : 
    1965              :         @return The index of the found character, or @ref npos if none exists.
    1966              : 
    1967              :         @param sv The characters to compare with.
    1968              :         @param pos The index to start searching at.
    1969              : 
    1970              :         @{
    1971              :     */
    1972              :     std::size_t
    1973            4 :     find_last_not_of(
    1974              :         string_view sv,
    1975              :         std::size_t pos = npos) const noexcept
    1976              :     {
    1977            4 :         return subview().find_last_not_of(sv, pos);
    1978              :     }
    1979              : 
    1980              :     /** Overload
    1981              :         @param ch The character to compare with.
    1982              :         @param pos
    1983              :     */
    1984              :     std::size_t
    1985            3 :     find_last_not_of(
    1986              :         char ch,
    1987              :         std::size_t pos = npos) const noexcept
    1988              :     {
    1989            3 :         return subview().find_last_not_of(ch, pos);
    1990              :     }
    1991              :     /// @}
    1992              : 
    1993              :     /** Serialize a @ref string to an output stream.
    1994              : 
    1995              :         This function serializes a `string` as JSON into the output stream.
    1996              : 
    1997              :         @return Reference to `os`.
    1998              : 
    1999              :         @par Complexity
    2000              :         Linear in the `str.size()`.
    2001              : 
    2002              :         @par Exception Safety
    2003              :         Strong guarantee. Calls to `memory_resource::allocate` may throw.
    2004              : 
    2005              :         @param os The output stream to serialize to.
    2006              :         @param str The value to serialize.
    2007              :     */
    2008              :     BOOST_JSON_DECL
    2009              :     friend
    2010              :     std::ostream&
    2011              :     operator<<(
    2012              :         std::ostream& os,
    2013              :         string const& str);
    2014              : 
    2015              : private:
    2016              :     class undo;
    2017              : 
    2018              :     template<class It>
    2019              :     using iter_cat = typename
    2020              :         std::iterator_traits<It>::iterator_category;
    2021              : 
    2022              :     template<class InputIt>
    2023              :     void
    2024              :     assign(InputIt first, InputIt last,
    2025              :         std::random_access_iterator_tag);
    2026              : 
    2027              :     template<class InputIt>
    2028              :     void
    2029              :     assign(InputIt first, InputIt last,
    2030              :         std::input_iterator_tag);
    2031              : 
    2032              :     template<class InputIt>
    2033              :     void
    2034              :     append(InputIt first, InputIt last,
    2035              :         std::random_access_iterator_tag);
    2036              : 
    2037              :     template<class InputIt>
    2038              :     void
    2039              :     append(InputIt first, InputIt last,
    2040              :         std::input_iterator_tag);
    2041              : 
    2042              :     BOOST_JSON_DECL
    2043              :     void
    2044              :     reserve_impl(std::size_t new_capacity);
    2045              : };
    2046              : 
    2047              : //----------------------------------------------------------
    2048              : 
    2049              : namespace detail
    2050              : {
    2051              : 
    2052              : template <>
    2053              : inline
    2054              : string_view
    2055        28820 : to_string_view<string>(string const& s) noexcept
    2056              : {
    2057        28820 :     return s.subview();
    2058              : }
    2059              : 
    2060              : } // namespace detail
    2061              : 
    2062              : 
    2063              : /** Checks if lhs equals rhs.
    2064              : 
    2065              :     @li **(1)** A lexicographical comparison is used.
    2066              :     @li **(2)** equivalent to `lhs.get() == rhs.get()`.
    2067              : 
    2068              :     @par Complexity
    2069              :     @li **(1)** linear in `lhs.size() + rhs.size()`.
    2070              :     @li **(2)** constant.
    2071              : 
    2072              :     @par Exception Safety
    2073              :     No-throw guarantee.
    2074              : */
    2075              : #ifdef BOOST_JSON_DOCS
    2076              : bool
    2077              : operator==(string const& lhs, string const& rhs) noexcept
    2078              : #else
    2079              : template<class T, class U>
    2080              : detail::string_comp_op_requirement<T, U>
    2081        15595 : operator==(T const& lhs, U const& rhs) noexcept
    2082              : #endif
    2083              : {
    2084        15595 :     return detail::to_string_view(lhs) == detail::to_string_view(rhs);
    2085              : }
    2086              : 
    2087              : /** Checks if lhs does not equal rhs.
    2088              : 
    2089              :     @li **(1)** A lexicographical comparison is used.
    2090              :     @li **(2)** equivalent to `lhs.get() != rhs.get()`.
    2091              : 
    2092              :     @par Complexity
    2093              :     @li **(1)** linear in `lhs.size() + rhs.size()`.
    2094              :     @li **(2)** constant.
    2095              : 
    2096              :     @par Exception Safety
    2097              :     No-throw guarantee.
    2098              : */
    2099              : #ifdef BOOST_JSON_DOCS
    2100              : bool
    2101              : operator!=(string const& lhs, string const& rhs) noexcept
    2102              : #else
    2103              : template<class T, class U>
    2104              : detail::string_comp_op_requirement<T, U>
    2105           24 : operator!=(T const& lhs, U const& rhs) noexcept
    2106              : #endif
    2107              : {
    2108           24 :     return detail::to_string_view(lhs) != detail::to_string_view(rhs);
    2109              : }
    2110              : 
    2111              : /** Check if lhs is less than rhs.
    2112              : 
    2113              :     A lexicographical comparison is used.
    2114              : 
    2115              :     @par Complexity
    2116              :     Linear in `lhs.size() + rhs.size()`.
    2117              : 
    2118              :     @par Exception Safety
    2119              :     No-throw guarantee.
    2120              : */
    2121              : #ifdef BOOST_JSON_DOCS
    2122              : bool
    2123              : operator<(string const& lhs, string const& rhs) noexcept
    2124              : #else
    2125              : template<class T, class U>
    2126              : detail::string_comp_op_requirement<T, U>
    2127           12 : operator<(T const& lhs, U const& rhs) noexcept
    2128              : #endif
    2129              : {
    2130           12 :     return detail::to_string_view(lhs) < detail::to_string_view(rhs);
    2131              : }
    2132              : 
    2133              : /** Check if lhs is less than or equal to rhs.
    2134              : 
    2135              :     A lexicographical comparison is used.
    2136              : 
    2137              :     @par Complexity
    2138              :     Linear in `lhs.size() + rhs.size()`.
    2139              : 
    2140              :     @par Exception Safety
    2141              :     No-throw guarantee.
    2142              : */
    2143              : #ifdef BOOST_JSON_DOCS
    2144              : bool
    2145              : operator<=(string const& lhs, string const& rhs) noexcept
    2146              : #else
    2147              : template<class T, class U>
    2148              : detail::string_comp_op_requirement<T, U>
    2149           12 : operator<=(T const& lhs, U const& rhs) noexcept
    2150              : #endif
    2151              : {
    2152           12 :     return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
    2153              : }
    2154              : 
    2155              : /** Check if lhs is more than or equal to rhs.
    2156              : 
    2157              :     A lexicographical comparison is used.
    2158              : 
    2159              :     @par Complexity
    2160              :     Linear in `lhs.size() + rhs.size()`.
    2161              : 
    2162              :     @par Exception Safety
    2163              :     No-throw guarantee.
    2164              : */
    2165              : #ifdef BOOST_JSON_DOCS
    2166              : bool
    2167              : operator>=(string const& lhs, string const& rhs) noexcept
    2168              : #else
    2169              : template<class T, class U>
    2170              : detail::string_comp_op_requirement<T, U>
    2171           12 : operator>=(T const& lhs, U const& rhs) noexcept
    2172              : #endif
    2173              : {
    2174           12 :     return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
    2175              : }
    2176              : 
    2177              : /** Check if lhs is greater than rhs.
    2178              : 
    2179              :     A lexicographical comparison is used.
    2180              : 
    2181              :     @par Complexity
    2182              :     Linear in `lhs.size() + rhs.size()`.
    2183              : 
    2184              :     @par Exception Safety
    2185              :     No-throw guarantee.
    2186              : */
    2187              : #ifdef BOOST_JSON_DOCS
    2188              : bool
    2189              : operator>(string const& lhs, string const& rhs) noexcept
    2190              : #else
    2191              : template<class T, class U>
    2192              : detail::string_comp_op_requirement<T, U>
    2193           12 : operator>(T const& lhs, U const& rhs) noexcept
    2194              : #endif
    2195              : {
    2196           12 :     return detail::to_string_view(lhs) > detail::to_string_view(rhs);
    2197              : }
    2198              : 
    2199              : } // namespace json
    2200              : } // namespace boost
    2201              : 
    2202              : // std::hash specialization
    2203              : #ifndef BOOST_JSON_DOCS
    2204              : namespace std {
    2205              : template<>
    2206              : struct hash< ::boost::json::string >
    2207              : {
    2208              :     BOOST_JSON_DECL
    2209              :     std::size_t
    2210              :     operator()( ::boost::json::string const& js ) const noexcept;
    2211              : };
    2212              : } // std
    2213              : #endif
    2214              : 
    2215              : #include <boost/json/impl/string.hpp>
    2216              : 
    2217              : #endif
        

Generated by: LCOV version 2.1