Coverage Report

Created: 2026-09-19 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/boost/json/string.hpp
Line
Count
Source
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
    ~string() noexcept
148
337k
    {
149
337k
        impl_.destroy(sp_);
150
337k
    }
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
    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
    string(storage_ptr sp)
243
12.0k
        : sp_(std::move(sp))
244
12.0k
    {
245
12.0k
    }
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
    string(string&& other) noexcept
319
0
        : sp_(other.sp_)
320
0
        , impl_(other.impl_)
321
0
    {
322
0
        ::new(&other.impl_) string_impl();
323
0
    }
324
325
    /// Overload
326
    BOOST_JSON_DECL
327
    explicit
328
    string(
329
        string&& other,
330
        storage_ptr sp);
331
332
    /// Overload
333
    string(pilfered<string> other) noexcept
334
0
        : sp_(std::move(other.get().sp_))
335
0
        , impl_(other.get().impl_)
336
0
    {
337
0
        ::new(&other.get().impl_) string_impl();
338
0
    }
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
    assign(string_view s)
508
63.6k
    {
509
63.6k
        return assign(s.data(), s.size());
510
63.6k
    }
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
    storage() const noexcept
541
0
    {
542
0
        return sp_;
543
0
    }
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
    get_allocator() const noexcept
558
0
    {
559
0
        return sp_.get();
560
0
    }
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
    operator[](std::size_t pos)
642
0
    {
643
0
        return impl_.data()[pos];
644
0
    }
645
646
    const char&
647
    operator[](std::size_t pos) const
648
0
    {
649
0
        return impl_.data()[pos];
650
0
    }
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
    front()
672
0
    {
673
0
        return impl_.data()[0];
674
0
    }
675
676
    char const&
677
    front() const
678
0
    {
679
0
        return impl_.data()[0];
680
0
    }
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
    back()
699
0
    {
700
0
        return impl_.data()[impl_.size() - 1];
701
0
    }
702
703
    char const&
704
    back() const
705
0
    {
706
0
        return impl_.data()[impl_.size() - 1];
707
0
    }
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
    data() noexcept
729
24.1k
    {
730
24.1k
        return impl_.data();
731
24.1k
    }
732
733
    char const*
734
    data() const noexcept
735
38.9k
    {
736
38.9k
        return impl_.data();
737
38.9k
    }
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
    c_str() const noexcept
754
0
    {
755
0
        return impl_.data();
756
0
    }
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
    operator string_view() const noexcept
769
0
    {
770
0
        return {data(), size()};
771
0
    }
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
0
    {
788
0
        return {data(), size()};
789
0
    }
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
    begin() noexcept
812
0
    {
813
0
        return impl_.data();
814
0
    }
815
816
    const_iterator
817
    begin() const noexcept
818
0
    {
819
0
        return impl_.data();
820
0
    }
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
    cbegin() const noexcept
835
0
    {
836
0
        return impl_.data();
837
0
    }
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
    end() noexcept
854
0
    {
855
0
        return impl_.end();
856
0
    }
857
858
    const_iterator
859
    end() const noexcept
860
0
    {
861
0
        return impl_.end();
862
0
    }
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
    cend() const noexcept
878
0
    {
879
0
        return impl_.end();
880
0
    }
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
    rbegin() noexcept
895
0
    {
896
0
        return reverse_iterator(impl_.end());
897
0
    }
898
899
    const_reverse_iterator
900
    rbegin() const noexcept
901
0
    {
902
0
        return const_reverse_iterator(impl_.end());
903
0
    }
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
    crbegin() const noexcept
920
0
    {
921
0
        return const_reverse_iterator(impl_.end());
922
0
    }
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
    rend() noexcept
940
0
    {
941
0
        return reverse_iterator(begin());
942
0
    }
943
944
    const_reverse_iterator
945
    rend() const noexcept
946
0
    {
947
0
        return const_reverse_iterator(begin());
948
0
    }
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
    crend() const noexcept
966
0
    {
967
0
        return const_reverse_iterator(begin());
968
0
    }
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
    empty() const noexcept
989
0
    {
990
0
        return impl_.size() == 0;
991
0
    }
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
    size() const noexcept
1003
38.9k
    {
1004
38.9k
        return impl_.size();
1005
38.9k
    }
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
    max_size() noexcept
1020
0
    {
1021
0
        return string_impl::max_size();
1022
0
    }
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
    capacity() const noexcept
1038
12.0k
    {
1039
12.0k
        return impl_.capacity();
1040
12.0k
    }
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
    reserve(std::size_t new_capacity)
1066
12.0k
    {
1067
12.0k
        if(new_capacity <= capacity())
1068
7.39k
            return;
1069
4.66k
        reserve_impl(new_capacity);
1070
4.66k
    }
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
    insert(
1169
        size_type pos,
1170
        char ch)
1171
0
    {
1172
0
        return insert(pos, 1, ch);
1173
0
    }
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
    operator+=(string_view sv)
1367
0
    {
1368
0
        return append(sv);
1369
0
    }
1370
1371
    /** Overload
1372
        @param ch The character to append.
1373
    */
1374
    string&
1375
    operator+=(char ch)
1376
0
    {
1377
0
        push_back(ch);
1378
0
        return *this;
1379
0
    }
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
    compare(string_view sv) const noexcept
1401
0
    {
1402
0
        return subview().compare(sv);
1403
0
    }
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
    starts_with(string_view s) const noexcept
1422
0
    {
1423
0
        return subview(0, s.size()) == s;
1424
0
    }
1425
1426
    /** Overload
1427
1428
        @param ch The character to check for.
1429
    */
1430
    bool
1431
    starts_with(char ch) const noexcept
1432
0
    {
1433
0
        return ! empty() && front() == ch;
1434
0
    }
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
    ends_with(string_view s) const noexcept
1455
0
    {
1456
0
        return size() >= s.size() &&
1457
0
            subview(size() - s.size()) == s;
1458
0
    }
1459
1460
    /** Overload
1461
        @param ch The character to check for.
1462
    */
1463
    bool
1464
    ends_with(char ch) const noexcept
1465
0
    {
1466
0
        return ! empty() && back() == ch;
1467
0
    }
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
    replace(
1524
        const_iterator first,
1525
        const_iterator last,
1526
        string_view sv)
1527
0
    {
1528
0
        return replace(first - begin(), last - first, sv);
1529
0
    }
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
    replace(
1578
        const_iterator first,
1579
        const_iterator last,
1580
        std::size_t count2,
1581
        char ch)
1582
0
    {
1583
0
        return replace(first - begin(), last - first, count2, ch);
1584
0
    }
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
    subview(
1604
        std::size_t pos,
1605
        std::size_t count = npos) const
1606
0
    {
1607
0
        return subview().substr(pos, count);
1608
0
    }
1609
1610
    /// Overload
1611
    string_view
1612
    subview() const noexcept
1613
0
    {
1614
0
        return string_view( data(), size() );
1615
0
    }
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
    copy(
1639
        char* dest,
1640
        std::size_t count,
1641
        std::size_t pos = 0) const
1642
0
    {
1643
0
        return subview().copy(dest, count, pos);
1644
0
    }
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
    resize(std::size_t count)
1662
0
    {
1663
0
        resize(count, 0);
1664
0
    }
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
    grow(std::size_t n) noexcept
1693
12.0k
    {
1694
12.0k
        BOOST_ASSERT(
1695
12.0k
            n <= impl_.capacity() - impl_.size());
1696
12.0k
        impl_.term(impl_.size() + n);
1697
12.0k
    }
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
    swap(string& lhs, string& rhs)
1756
0
    {
1757
0
        lhs.swap(rhs);
1758
0
    }
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
    find(
1790
        string_view sv,
1791
        std::size_t pos = 0) const noexcept
1792
0
    {
1793
0
        return subview().find(sv, pos);
1794
0
    }
1795
1796
    /** Overload
1797
1798
        @param ch The character to search for.
1799
        @param pos
1800
    */
1801
    std::size_t
1802
    find(
1803
        char ch,
1804
        std::size_t pos = 0) const noexcept
1805
0
    {
1806
0
        return subview().find(ch, pos);
1807
0
    }
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
    rfind(
1832
        string_view sv,
1833
        std::size_t pos = npos) const noexcept
1834
0
    {
1835
0
        return subview().rfind(sv, pos);
1836
0
    }
1837
1838
    /** Overload
1839
1840
        @param ch The character to search for.
1841
        @param pos
1842
    */
1843
    std::size_t
1844
    rfind(
1845
        char ch,
1846
        std::size_t pos = npos) const noexcept
1847
0
    {
1848
0
        return subview().rfind(ch, pos);
1849
0
    }
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
    find_first_of(
1872
        string_view sv,
1873
        std::size_t pos = 0) const noexcept
1874
0
    {
1875
0
        return subview().find_first_of(sv, pos);
1876
0
    }
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
    find_first_not_of(
1903
        string_view sv,
1904
        std::size_t pos = 0) const noexcept
1905
0
    {
1906
0
        return subview().find_first_not_of(sv, pos);
1907
0
    }
1908
1909
    /** Overload
1910
        @param ch The character to compare with.
1911
        @param pos
1912
    */
1913
    std::size_t
1914
    find_first_not_of(
1915
        char ch,
1916
        std::size_t pos = 0) const noexcept
1917
0
    {
1918
0
        return subview().find_first_not_of(ch, pos);
1919
0
    }
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
    find_last_of(
1941
        string_view sv,
1942
        std::size_t pos = npos) const noexcept
1943
0
    {
1944
0
        return subview().find_last_of(sv, pos);
1945
0
    }
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
    find_last_not_of(
1974
        string_view sv,
1975
        std::size_t pos = npos) const noexcept
1976
0
    {
1977
0
        return subview().find_last_not_of(sv, pos);
1978
0
    }
1979
1980
    /** Overload
1981
        @param ch The character to compare with.
1982
        @param pos
1983
    */
1984
    std::size_t
1985
    find_last_not_of(
1986
        char ch,
1987
        std::size_t pos = npos) const noexcept
1988
0
    {
1989
0
        return subview().find_last_not_of(ch, pos);
1990
0
    }
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
to_string_view<string>(string const& s) noexcept
2056
0
{
2057
0
    return s.subview();
2058
0
}
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
operator==(T const& lhs, U const& rhs) noexcept
2082
#endif
2083
0
{
2084
0
    return detail::to_string_view(lhs) == detail::to_string_view(rhs);
2085
0
}
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
operator!=(T const& lhs, U const& rhs) noexcept
2106
#endif
2107
{
2108
    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
operator<(T const& lhs, U const& rhs) noexcept
2128
#endif
2129
{
2130
    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
operator<=(T const& lhs, U const& rhs) noexcept
2150
#endif
2151
{
2152
    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
operator>=(T const& lhs, U const& rhs) noexcept
2172
#endif
2173
{
2174
    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
operator>(T const& lhs, U const& rhs) noexcept
2194
#endif
2195
{
2196
    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