TLA 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 HIT 30737 : ~string() noexcept
148 : {
149 30737 : impl_.destroy(sp_);
150 30737 : }
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 2471 : 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 9110 : string(storage_ptr sp)
243 9110 : : sp_(std::move(sp))
244 : {
245 9110 : }
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 425 : string(string&& other) noexcept
319 425 : : sp_(other.sp_)
320 425 : , impl_(other.impl_)
321 : {
322 425 : ::new(&other.impl_) string_impl();
323 425 : }
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 17995 : assign(string_view s)
508 : {
509 17995 : 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 118 : storage() const noexcept
541 : {
542 118 : 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 : constexpr
563 : bool
564 14751 : is_seamless() const noexcept
565 : {
566 14751 : return impl_.is_seamless();
567 : }
568 :
569 : void
570 4 : set_seamless(bool on) noexcept
571 : {
572 4 : impl_.set_seamless(on);
573 4 : }
574 :
575 : //------------------------------------------------------
576 : //
577 : // Element Access
578 : //
579 : //------------------------------------------------------
580 :
581 : /** Return a character with bounds checking.
582 :
583 : Returns @ref boost::system::result containing a reference to the
584 : character specified at location `pos`, if `pos` is within the range of
585 : the string. Otherwise the result contains an `error_code`.
586 :
587 : @par Exception Safety
588 : Strong guarantee.
589 :
590 : @param pos A zero-based index to access.
591 :
592 : @par Complexity
593 : Constant.
594 :
595 : @{
596 : */
597 : BOOST_JSON_DECL
598 : system::result<char&>
599 : try_at(std::size_t pos) noexcept;
600 :
601 : BOOST_JSON_DECL
602 : system::result<char const&>
603 : try_at(std::size_t pos) const noexcept;
604 : /// @}
605 :
606 : /** Return a character with bounds checking.
607 :
608 : Returns a reference to the character specified at location `pos`.
609 :
610 : @par Complexity
611 : Constant.
612 :
613 : @par Exception Safety
614 : Strong guarantee.
615 :
616 : @param pos A zero-based index to access.
617 : @param loc `source_location` to use in thrown exception; the source
618 : location of the call site by default.
619 :
620 : @throw boost::system::system_error `pos >=` @ref size().
621 :
622 : @{
623 : */
624 : inline
625 : char&
626 : at(
627 : std::size_t pos,
628 : source_location const& loc = BOOST_CURRENT_LOCATION);
629 :
630 : BOOST_JSON_DECL
631 : char const&
632 : at(
633 : std::size_t pos,
634 : source_location const& loc = BOOST_CURRENT_LOCATION) const;
635 : /// @}
636 :
637 : /** Return a character without bounds checking.
638 :
639 : Returns a reference to the character specified at location `pos`.
640 :
641 : @par Complexity
642 : Constant.
643 :
644 : @pre
645 : @code
646 : pos < size()
647 : @endcode
648 :
649 : @param pos A zero-based index to access.
650 :
651 : @{
652 : */
653 : char&
654 18 : operator[](std::size_t pos)
655 : {
656 18 : return impl_.data()[pos];
657 : }
658 :
659 : const char&
660 2 : operator[](std::size_t pos) const
661 : {
662 2 : return impl_.data()[pos];
663 : }
664 : /// @}
665 :
666 : /** Return the first character.
667 :
668 : Returns a reference to the first character.
669 :
670 : @pre
671 : @code
672 : ! empty()
673 : @endcode
674 :
675 : @par Complexity
676 : Constant.
677 :
678 : @par Exception Safety
679 : No-throw guarantee.
680 :
681 : @{
682 : */
683 : char&
684 10 : front()
685 : {
686 10 : return impl_.data()[0];
687 : }
688 :
689 : char const&
690 6 : front() const
691 : {
692 6 : return impl_.data()[0];
693 : }
694 : /// @}
695 :
696 : /** Return the last character.
697 :
698 : Returns a reference to the last character.
699 :
700 : @pre
701 : @code
702 : ! empty()
703 : @endcode
704 :
705 : @par Complexity
706 : Constant.
707 :
708 : @{
709 : */
710 : char&
711 39 : back()
712 : {
713 39 : return impl_.data()[impl_.size() - 1];
714 : }
715 :
716 : char const&
717 6 : back() const
718 : {
719 6 : return impl_.data()[impl_.size() - 1];
720 : }
721 : /// @}
722 :
723 : /** Return the underlying character array directly.
724 :
725 : Returns a pointer to the underlying array serving as storage. The value
726 : returned is such that the range `[data(), data() + size())` is always
727 : a valid range, even if the container is empty.
728 :
729 : @note The value returned from this function is never equal to
730 : `nullptr`.
731 :
732 : @par Complexity
733 : Constant.
734 :
735 : @par Exception Safety
736 : No-throw guarantee.
737 :
738 : @{
739 : */
740 : char*
741 24137 : data() noexcept
742 : {
743 24137 : return impl_.data();
744 : }
745 :
746 : char const*
747 44146 : data() const noexcept
748 : {
749 44146 : return impl_.data();
750 : }
751 : /// @@}
752 :
753 : /** Return the underlying character array directly.
754 :
755 : Returns a pointer to the underlying array serving as storage. The value
756 : returned is such that the range `[c_str(), c_str() + size())` is always
757 : a valid range, even if the container is empty.
758 :
759 : @note The value returned from this function is never equal to
760 : `nullptr`.
761 :
762 : @par Complexity
763 : Constant.
764 : */
765 : char const*
766 4 : c_str() const noexcept
767 : {
768 4 : return impl_.data();
769 : }
770 :
771 : /** Convert to a @ref string_view referring to the string.
772 :
773 : Returns a string view to the
774 : underlying character string. The size of the view
775 : does not include the null terminator.
776 :
777 : @par Complexity
778 :
779 : Constant.
780 : */
781 61 : operator string_view() const noexcept
782 : {
783 61 : return {data(), size()};
784 : }
785 :
786 : #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
787 : /** Convert to @ref std::string_view referring to the string.
788 :
789 : Returns a string view to the underlying character string. The size of
790 : the view does not include the null terminator.
791 :
792 : This overload is not defined when `BOOST_NO_CXX17_HDR_STRING_VIEW` is
793 : defined.
794 :
795 : @par Complexity
796 :
797 : Constant.
798 : */
799 : operator std::string_view() const noexcept
800 : {
801 : return {data(), size()};
802 : }
803 : #endif
804 :
805 : //------------------------------------------------------
806 : //
807 : // Iterators
808 : //
809 : //------------------------------------------------------
810 :
811 : /** Return an iterator to the beginning.
812 :
813 : If the container is empty, @ref end() is returned.
814 :
815 : @par Complexity
816 : Constant.
817 :
818 : @par Exception Safety
819 : No-throw guarantee.
820 :
821 : @{
822 : */
823 : iterator
824 34 : begin() noexcept
825 : {
826 34 : return impl_.data();
827 : }
828 :
829 : const_iterator
830 8 : begin() const noexcept
831 : {
832 8 : return impl_.data();
833 : }
834 : /// @}
835 :
836 : /** Return a const iterator to the first element.
837 :
838 : If the container is empty, @ref cend() is returned.
839 :
840 : @par Complexity
841 : Constant.
842 :
843 : @par Exception Safety
844 : No-throw guarantee.
845 : */
846 : const_iterator
847 2 : cbegin() const noexcept
848 : {
849 2 : return impl_.data();
850 : }
851 :
852 : /** Return an iterator to the end.
853 :
854 : The returned iterator only acts as a sentinel. Dereferencing it results
855 : in undefined behavior.
856 :
857 : @par Complexity
858 : Constant.
859 :
860 : @par Exception Safety
861 : No-throw guarantee.
862 :
863 : @{
864 : */
865 : iterator
866 3 : end() noexcept
867 : {
868 3 : return impl_.end();
869 : }
870 :
871 : const_iterator
872 3 : end() const noexcept
873 : {
874 3 : return impl_.end();
875 : }
876 : /// @}
877 :
878 : /** Return a const iterator past the last element.
879 :
880 : The returned iterator only acts as a sentinel. Dereferencing it results
881 : in undefined behavior.
882 :
883 : @par Complexity
884 : Constant.
885 :
886 : @par Exception Safety
887 : No-throw guarantee.
888 : */
889 : const_iterator
890 2 : cend() const noexcept
891 : {
892 2 : return impl_.end();
893 : }
894 :
895 : /** Return a reverse iterator to the first character of the reversed container.
896 :
897 : Returns the pointed-to character that corresponds to the last character
898 : of the non-reversed container. If the container is empty, @ref rend()
899 : is returned.
900 :
901 : @par Complexity
902 : Constant.
903 :
904 : @{
905 : */
906 : reverse_iterator
907 3 : rbegin() noexcept
908 : {
909 3 : return reverse_iterator(impl_.end());
910 : }
911 :
912 : const_reverse_iterator
913 3 : rbegin() const noexcept
914 : {
915 3 : return const_reverse_iterator(impl_.end());
916 : }
917 : /// @}
918 :
919 : /** Return a const reverse iterator to the first element of the reversed container.
920 :
921 : Returns the pointed-to character that corresponds to the last character
922 : of the non-reversed container. If the container is empty, @ref crend()
923 : is returned.
924 :
925 : @par Complexity
926 : Constant.
927 :
928 : @par Exception Safety
929 : No-throw guarantee.
930 : */
931 : const_reverse_iterator
932 2 : crbegin() const noexcept
933 : {
934 2 : return const_reverse_iterator(impl_.end());
935 : }
936 :
937 : /** Return a reverse iterator to the character following the last character of the reversed container.
938 :
939 : The pointed-to element corresponds to the element preceding the first
940 : element of the non-reversed container. The returned iterator only acts
941 : as a sentinel. Dereferencing it results in undefined behavior.
942 :
943 : @par Complexity
944 : Constant.
945 :
946 : @par Exception Safety
947 : No-throw guarantee.
948 :
949 : @{
950 : */
951 : reverse_iterator
952 3 : rend() noexcept
953 : {
954 3 : return reverse_iterator(begin());
955 : }
956 :
957 : const_reverse_iterator
958 3 : rend() const noexcept
959 : {
960 3 : return const_reverse_iterator(begin());
961 : }
962 : /// @}
963 :
964 : /** Return a const reverse iterator to the character following the last character of the reversed container.
965 :
966 : The pointed-to character corresponds to the character preceding the
967 : first character of the non-reversed container. The returned iterator
968 : only acts as a sentinel. Dereferencing it results in undefined
969 : behavior.
970 :
971 : @par Complexity
972 : Constant.
973 :
974 : @par Exception Safety
975 : No-throw guarantee.
976 : */
977 : const_reverse_iterator
978 2 : crend() const noexcept
979 : {
980 2 : return const_reverse_iterator(begin());
981 : }
982 :
983 : //------------------------------------------------------
984 : //
985 : // Capacity
986 : //
987 : //------------------------------------------------------
988 :
989 : /** Check if the string has no characters.
990 :
991 : Returns `true` if there are no characters in the string, i.e. @ref
992 : size() returns 0.
993 :
994 : @par Complexity
995 : Constant.
996 :
997 : @par Exception Safety
998 : No-throw guarantee.
999 : */
1000 : bool
1001 69 : empty() const noexcept
1002 : {
1003 69 : return impl_.size() == 0;
1004 : }
1005 :
1006 : /** Return the number of characters in the string.
1007 :
1008 : The value returned does not include the null terminator, which is
1009 : always present.
1010 :
1011 : @par Complexity
1012 : Constant.
1013 : */
1014 : std::size_t
1015 48118 : size() const noexcept
1016 : {
1017 48118 : return impl_.size();
1018 : }
1019 :
1020 : /** Return the maximum number of characters any string can hold.
1021 :
1022 : The maximum is an implementation-defined number. This value is
1023 : a theoretical limit; at runtime, the actual maximum size may be less
1024 : due to resource limits.
1025 :
1026 : @par Complexity
1027 : Constant.
1028 : */
1029 : static
1030 : constexpr
1031 : std::size_t
1032 7900 : max_size() noexcept
1033 : {
1034 7900 : return string_impl::max_size();
1035 : }
1036 :
1037 : /** Return the number of characters that can be held in currently allocated memory.
1038 :
1039 : Returns the number of characters that the container has currently
1040 : allocated space for. This number is never smaller than the value
1041 : returned by @ref size().
1042 :
1043 : @par Complexity
1044 : Constant.
1045 :
1046 : @par Exception Safety
1047 : No-throw guarantee.
1048 : */
1049 : std::size_t
1050 11774 : capacity() const noexcept
1051 : {
1052 11774 : return impl_.capacity();
1053 : }
1054 :
1055 : /** Increase the capacity to at least a certain amount.
1056 :
1057 : This increases the capacity of the array to a value that is greater
1058 : than or equal to `new_capacity`. If `new_capacity > `@ref capacity(),
1059 : new memory is allocated. Otherwise, the call has no effect. The number
1060 : of elements and therefore the @ref size() of the container is not
1061 : changed.
1062 :
1063 : If new memory is allocated, all iterators including any past-the-end
1064 : iterators, and all references to the elements are invalidated.
1065 : Otherwise, no iterators or references are invalidated.
1066 :
1067 : @par Complexity
1068 : At most, linear in @ref size().
1069 :
1070 : @par Exception Safety
1071 : Strong guarantee. Calls to `memory_resource::allocate` may throw.
1072 :
1073 : @param new_capacity The new capacity of the array.
1074 :
1075 : @throw boost::system::system_error `new_capacity > `@ref max_size().
1076 : */
1077 : void
1078 11395 : reserve(std::size_t new_capacity)
1079 : {
1080 11395 : if(new_capacity <= capacity())
1081 1668 : return;
1082 9727 : reserve_impl(new_capacity);
1083 : }
1084 :
1085 : /** Request the removal of unused capacity.
1086 :
1087 : This performs a non-binding request to reduce @ref capacity() to
1088 : @ref size(). The request may or may not be fulfilled.
1089 :
1090 : @note If reallocation occurs, all iterators including any past-the-end
1091 : iterators, and all references to characters are invalidated. Otherwise,
1092 : no iterators or references are invalidated.
1093 :
1094 : @par Complexity
1095 : At most, linear in @ref size().
1096 : */
1097 : BOOST_JSON_DECL
1098 : void
1099 : shrink_to_fit();
1100 :
1101 : //------------------------------------------------------
1102 : //
1103 : // Operations
1104 : //
1105 : //------------------------------------------------------
1106 :
1107 : /** Clear the contents.
1108 :
1109 : Erases all characters from the string. After this call, @ref size()
1110 : returns zero but @ref capacity() is unchanged. All references,
1111 : pointers, or iterators referring to contained elements are invalidated.
1112 : Any past-the-end iterators are also invalidated.
1113 :
1114 : @par Complexity
1115 : Linear in @ref size().
1116 :
1117 : @par Exception Safety
1118 : No-throw guarantee.
1119 : */
1120 : BOOST_JSON_DECL
1121 : void
1122 : clear() noexcept;
1123 :
1124 : /** Insert characters at the specified index.
1125 :
1126 : @li **(1)** inserts `sv`.
1127 : @li **(2)** inserts `count` copies of `ch`.
1128 : @li **(3)** inserts the character `ch`.
1129 : @li **(4)** inserts characters from the range `[first, last)`.
1130 :
1131 : The first character is inserted at the index `pos`. All references,
1132 : pointers, or iterators referring to contained elements are invalidated.
1133 : Any past-the-end iterators are also invalidated.
1134 :
1135 : @par Constraints
1136 : `InputIt` satisfies {req_InputIterator}.
1137 :
1138 : @pre
1139 : `[first, last)` is a valid range.
1140 :
1141 : @par Exception Safety
1142 : @li **(1)**--*(3)* strong guarantee.
1143 : @li **(4)** strong guarantee if `InputIt` satisfies
1144 : {req_ForwardIterator}, basic guarantee otherwise.
1145 :
1146 : @return `*this`
1147 :
1148 : @param pos The index to insert at.
1149 : @param sv The `string_view` to insert.
1150 :
1151 : @throw boost::system::system_error The size of the string would exceed
1152 : @ref max_size().
1153 :
1154 : @throw boost::system::system_error `pos > `@ref size().
1155 :
1156 : @{
1157 : */
1158 : BOOST_JSON_DECL
1159 : string&
1160 : insert(
1161 : std::size_t pos,
1162 : string_view sv);
1163 :
1164 : /** Overload
1165 : @param count The number of characters to insert.
1166 : @param ch The character to insert.
1167 : @param pos
1168 : */
1169 : BOOST_JSON_DECL
1170 : string&
1171 : insert(
1172 : std::size_t pos,
1173 : std::size_t count,
1174 : char ch);
1175 :
1176 : /** Overload
1177 : @param pos
1178 : @param ch
1179 : */
1180 : string&
1181 3 : insert(
1182 : size_type pos,
1183 : char ch)
1184 : {
1185 3 : return insert(pos, 1, ch);
1186 : }
1187 :
1188 : /** Overload
1189 :
1190 : @tparam InputIt The type of the iterators.
1191 :
1192 : @param first The beginning of the character range.
1193 : @param last The end of the character range.
1194 : @param pos
1195 : */
1196 : template<class InputIt
1197 : #ifndef BOOST_JSON_DOCS
1198 : ,class = is_inputit<InputIt>
1199 : #endif
1200 : >
1201 : string&
1202 : insert(
1203 : size_type pos,
1204 : InputIt first,
1205 : InputIt last);
1206 : /// @}
1207 :
1208 : /** Remove characters from the string.
1209 :
1210 : @li **(1)** removes at most `count` but not more than `size() - pos`
1211 : characters starting at `index`.
1212 : @li **(2)** removes the character at `pos`.
1213 : @li **(3)** removes characters in the range `[first, last)`.
1214 :
1215 : All references, pointers, or iterators referring to contained elements
1216 : are invalidated. Any past-the-end iterators are also invalidated.
1217 :
1218 : @pre
1219 : `pos`, `first`, and `last` are iterators into this string. `first` and
1220 : `last` form a valid range.
1221 :
1222 : @par Complexity
1223 : @li **(1)** linear in `count`.
1224 : @li **(2)** constant.
1225 : @li **(3)** linear in `std::distance(first, last)`.
1226 :
1227 : @par Exception Safety
1228 : Strong guarantee.
1229 :
1230 : @return
1231 : @li **(1)** `*this`.
1232 :
1233 : @li **(2)** An iterator referring to the character immediately
1234 : following the removed character, or @ref end() if one does not exist.
1235 :
1236 : @li **(3)** An iterator referring to the character `last` previously
1237 : referred to, or @ref end() if one does not exist.
1238 :
1239 : @param index The index of the first character to remove.
1240 :
1241 : @param count The number of characters to remove. By default remove
1242 : until the end of the string.
1243 :
1244 : @throw boost::system::system_error `pos >` @ref size().
1245 :
1246 : @{
1247 : */
1248 : BOOST_JSON_DECL
1249 : string&
1250 : erase(
1251 : std::size_t index = 0,
1252 : std::size_t count = npos);
1253 :
1254 : /** Overload
1255 : @param pos An iterator referring to the character to erase.
1256 : */
1257 : BOOST_JSON_DECL
1258 : iterator
1259 : erase(const_iterator pos);
1260 :
1261 : /** Overload
1262 : @param first An iterator representing the first character to erase.
1263 : @param last An iterator one past the last character to erase.
1264 : */
1265 : BOOST_JSON_DECL
1266 : iterator
1267 : erase(
1268 : const_iterator first,
1269 : const_iterator last);
1270 : /// @}
1271 :
1272 : //------------------------------------------------------
1273 :
1274 : /** Append a character.
1275 :
1276 : Appends a character to the end of the string.
1277 :
1278 : @par Exception Safety
1279 : Strong guarantee.
1280 :
1281 : @param ch The character to append.
1282 :
1283 : @throw boost::system::system_error @ref size() `+ 1 > `@ref max_size().
1284 : */
1285 : BOOST_JSON_DECL
1286 : void
1287 : push_back(char ch);
1288 :
1289 : /** Remove the last character.
1290 :
1291 : Removes a character from the end of the string.
1292 :
1293 : @pre
1294 : @code
1295 : ! empty()
1296 : @endcode
1297 : */
1298 : BOOST_JSON_DECL
1299 : void
1300 : pop_back();
1301 :
1302 : //------------------------------------------------------
1303 :
1304 : /** Append characters to the string.
1305 :
1306 : @li **(1)** appends `count` copies of `ch`.
1307 :
1308 : @li **(2)** appends copies of characters of `sv`, preserving order.
1309 :
1310 : @li **(3)** appends characters from the range `[first, last)`,
1311 : preserving order.
1312 :
1313 : @pre
1314 : `[first, last)` shall be a valid range.
1315 :
1316 : @par Constraints
1317 : `InputIt` satisfies {req_InputIterator}.
1318 :
1319 : @par Exception Safety
1320 : Strong guarantee.
1321 :
1322 : @return `*this`.
1323 :
1324 : @param count The number of characters to append.
1325 : @param ch The character to append.
1326 :
1327 : @throw boost::system::system_error The size of the string after the
1328 : operation would exceed @ref max_size().
1329 :
1330 : @{
1331 : */
1332 : BOOST_JSON_DECL
1333 : string&
1334 : append(
1335 : std::size_t count,
1336 : char ch);
1337 :
1338 : /** Overload
1339 : @param sv The `string_view` to append.
1340 : */
1341 : BOOST_JSON_DECL
1342 : string&
1343 : append(string_view sv);
1344 :
1345 : /** Overload
1346 :
1347 : @tparam InputIt The type of the iterators.
1348 :
1349 : @param first An iterator representing the first character to append.
1350 : @param last An iterator one past the last character to append.
1351 : */
1352 : template<class InputIt
1353 : #ifndef BOOST_JSON_DOCS
1354 : ,class = is_inputit<InputIt>
1355 : #endif
1356 : >
1357 : string&
1358 : append(InputIt first, InputIt last);
1359 : /// @}
1360 :
1361 : /** Append characters to the string.
1362 :
1363 : @li **(1)** appends `[sv.begin(), sv.end())`.
1364 : @li **(2)** appends `ch`.
1365 :
1366 : @par Exception Safety
1367 : Strong guarantee.
1368 :
1369 : @return `*this`
1370 :
1371 : @param sv The `string_view` to append.
1372 :
1373 : @throw boost::system::system_error The size of the string after the
1374 : operation would exceed @ref max_size().
1375 :
1376 : @{
1377 : */
1378 : string&
1379 11 : operator+=(string_view sv)
1380 : {
1381 11 : return append(sv);
1382 : }
1383 :
1384 : /** Overload
1385 : @param ch The character to append.
1386 : */
1387 : string&
1388 44 : operator+=(char ch)
1389 : {
1390 44 : push_back(ch);
1391 43 : return *this;
1392 : }
1393 : /// @}
1394 :
1395 : //------------------------------------------------------
1396 :
1397 : /** Compare a string with the string.
1398 :
1399 : Let `comp` be `std::char_traits<char>::compare(data(), sv.data(),
1400 : std::min(size(), sv.size())`. If `comp != 0`, then the result is
1401 : `comp`. Otherwise, the result is `0` if `size() == sv.size()`, `-1` if
1402 : `size() < sv.size()`, and `1` otherwise.
1403 :
1404 : @par Complexity
1405 : Linear.
1406 :
1407 : @return The result of lexicographically comparing the characters of
1408 : `sv` and the string.
1409 :
1410 : @param sv The `string_view` to compare.
1411 : */
1412 : int
1413 13 : compare(string_view sv) const noexcept
1414 : {
1415 13 : return subview().compare(sv);
1416 : }
1417 :
1418 : //------------------------------------------------------
1419 :
1420 : /** Return whether the string begins with another string.
1421 :
1422 : @li **(1)** checks if the string begins with `s`.
1423 : @li **(2)** checks if the string begins with `ch`.
1424 :
1425 : @par Complexity
1426 : @li **(1)** linear in `s.size()`.
1427 : @li **(2)** constant.
1428 :
1429 : @param s The string to check for.
1430 :
1431 : @{
1432 : */
1433 : bool
1434 8 : starts_with(string_view s) const noexcept
1435 : {
1436 8 : return subview(0, s.size()) == s;
1437 : }
1438 :
1439 : /** Overload
1440 :
1441 : @param ch The character to check for.
1442 : */
1443 : bool
1444 4 : starts_with(char ch) const noexcept
1445 : {
1446 4 : return ! empty() && front() == ch;
1447 : }
1448 : /// @}
1449 :
1450 : /** Check if the string ends with given suffix.
1451 :
1452 : @li **(1)** returns `true` if the string ends with `s`.
1453 : @li **(2)** returns `true` if the string ends with the character `ch`.
1454 :
1455 : @par Complexity
1456 : @li **(1)** linear in `s`.
1457 : @li **(2)** constant.
1458 :
1459 : @par Exception Safety
1460 : No-throw guarantee.
1461 :
1462 : @param s The string to check for.
1463 :
1464 : @{
1465 : */
1466 : bool
1467 8 : ends_with(string_view s) const noexcept
1468 : {
1469 16 : return size() >= s.size() &&
1470 16 : subview(size() - s.size()) == s;
1471 : }
1472 :
1473 : /** Overload
1474 : @param ch The character to check for.
1475 : */
1476 : bool
1477 4 : ends_with(char ch) const noexcept
1478 : {
1479 4 : return ! empty() && back() == ch;
1480 : }
1481 : /// @}
1482 :
1483 : /** Replace a substring with another string.
1484 :
1485 : @li **(1)** replaces `std::min(count, size() - pos)` characters
1486 : starting at index `pos` with those of `sv`.
1487 : @li **(2)** replaces the characters in the range `[first, last)` with
1488 : those of `sv`.
1489 : @li **(3)** replaces the characters in the range `[first, last)` with
1490 : those of `[first2, last2)`.
1491 : @li **(4)** replaces `std::min(count, size() - pos)` characters
1492 : starting at index `pos` with `count2` copies of `ch`.
1493 : @li **(5)** replaces the characters in the range `[first, last)` with
1494 : `count2` copies of `ch`.
1495 :
1496 : All references, pointers, or iterators referring to contained elements
1497 : are invalidated. Any past-the-end iterators are also invalidated.
1498 :
1499 : @pre
1500 : `[first, last)` is a valid range. `[first2, last2)` is a valid range.
1501 :
1502 : @par Constraints
1503 : `InputIt` satisfies {req_InputIterator}.
1504 :
1505 : @par Exception Safety
1506 : Strong guarantee.
1507 :
1508 : @return `*this`
1509 :
1510 : @param pos The index to replace at.
1511 :
1512 : @param count The number of characters to replace.
1513 :
1514 : @param sv The `string_view` to replace with.
1515 :
1516 : @throw boost::system::system_error The resulting string's size would
1517 : have exceeded @ref max_size().
1518 :
1519 : @{
1520 : */
1521 : BOOST_JSON_DECL
1522 : string&
1523 : replace(
1524 : std::size_t pos,
1525 : std::size_t count,
1526 : string_view sv);
1527 :
1528 : /** Overload
1529 :
1530 : @param first An iterator referring to the first character to replace.
1531 : @param last An iterator one past the end of the last character to
1532 : replace.
1533 : @param sv
1534 : */
1535 : string&
1536 6 : replace(
1537 : const_iterator first,
1538 : const_iterator last,
1539 : string_view sv)
1540 : {
1541 6 : return replace(first - begin(), last - first, sv);
1542 : }
1543 :
1544 : /** Overload
1545 :
1546 : @tparam InputIt The type of the iterators.
1547 :
1548 : @param first2 An iterator referring to the first character to replace
1549 : with.
1550 : @param last2 An iterator one past the end of the last character to
1551 : replace with.
1552 : @param first
1553 : @param last
1554 : */
1555 : template<class InputIt
1556 : #ifndef BOOST_JSON_DOCS
1557 : ,class = is_inputit<InputIt>
1558 : #endif
1559 : >
1560 : string&
1561 : replace(
1562 : const_iterator first,
1563 : const_iterator last,
1564 : InputIt first2,
1565 : InputIt last2);
1566 :
1567 : /** Overload
1568 :
1569 : @param count2 The number of characters to replace with.
1570 : @param ch The character to replace with.
1571 : @param pos
1572 : @param count
1573 : */
1574 : BOOST_JSON_DECL
1575 : string&
1576 : replace(
1577 : std::size_t pos,
1578 : std::size_t count,
1579 : std::size_t count2,
1580 : char ch);
1581 :
1582 : /** Overload
1583 :
1584 : @param first
1585 : @param last
1586 : @param count2
1587 : @param ch
1588 : */
1589 : string&
1590 1 : replace(
1591 : const_iterator first,
1592 : const_iterator last,
1593 : std::size_t count2,
1594 : char ch)
1595 : {
1596 1 : return replace(first - begin(), last - first, count2, ch);
1597 : }
1598 : /// @}
1599 :
1600 : //------------------------------------------------------
1601 :
1602 : /** Return a view.
1603 :
1604 : @li **(1)** equivalent to `subview().substr(pos, count)`.
1605 : @li **(2)** equivalent to `string_view(data(), size())`.
1606 :
1607 : @par Exception Safety
1608 : Strong guarantee.
1609 :
1610 : @param pos The index of the first character of the substring.
1611 : @param count The length of the substring.
1612 :
1613 : @throw boost::system::system_error `pos > ` @ref size().
1614 : */
1615 : string_view
1616 43 : subview(
1617 : std::size_t pos,
1618 : std::size_t count = npos) const
1619 : {
1620 43 : return subview().substr(pos, count);
1621 : }
1622 :
1623 : /// Overload
1624 : string_view
1625 29030 : subview() const noexcept
1626 : {
1627 29030 : return string_view( data(), size() );
1628 : }
1629 :
1630 : //------------------------------------------------------
1631 :
1632 : /** Copy a substring to another string.
1633 :
1634 : Copies `std::min(count, size() - pos)` characters starting at index
1635 : `pos` to the string pointed to by `dest`.
1636 :
1637 : @attention This function doesn't put the null terminator after the
1638 : copied characters.
1639 :
1640 : @return The number of characters copied.
1641 :
1642 : @param count The number of characters to copy.
1643 :
1644 : @param dest The string to copy to.
1645 :
1646 : @param pos The index to begin copying from.
1647 :
1648 : @throw boost::system::system_error `pos >` @ref max_size().
1649 : */
1650 : std::size_t
1651 2 : copy(
1652 : char* dest,
1653 : std::size_t count,
1654 : std::size_t pos = 0) const
1655 : {
1656 2 : return subview().copy(dest, count, pos);
1657 : }
1658 :
1659 : //------------------------------------------------------
1660 :
1661 : /** Change the size of the string.
1662 :
1663 : Resizes the string to contain `count` characters. If
1664 : `count > `@ref size(), **(2)** appends copies of `ch` and **(1)**
1665 : appends ``'\0'``. Otherwise, `size()` is reduced to `count`.
1666 :
1667 : @param count The size to resize the string to.
1668 :
1669 : @throw boost::system::system_error `count > `@ref max_size().
1670 :
1671 : @{
1672 : */
1673 : void
1674 57 : resize(std::size_t count)
1675 : {
1676 57 : resize(count, 0);
1677 54 : }
1678 :
1679 : /** Overload
1680 :
1681 : @param count
1682 : @param ch The characters to append if the size increases.
1683 : */
1684 : BOOST_JSON_DECL
1685 : void
1686 : resize(std::size_t count, char ch);
1687 : /// @}
1688 :
1689 : /** Increase size without changing capacity.
1690 :
1691 : This increases the size of the string by `n` characters, adjusting the
1692 : position of the terminating null character for the new size. The new
1693 : characters remain uninitialized. This function may be used to append
1694 : characters directly into the storage between @ref end() and @ref data()
1695 : ` + ` @ref capacity().
1696 :
1697 : @pre
1698 : @code
1699 : count <= capacity() - size()
1700 : @endcode
1701 :
1702 : @param n The amount to increase the size by.
1703 : */
1704 : void
1705 15183 : grow(std::size_t n) noexcept
1706 : {
1707 15183 : BOOST_ASSERT(
1708 : n <= impl_.capacity() - impl_.size());
1709 15183 : impl_.term(impl_.size() + n);
1710 15183 : }
1711 :
1712 : /** Swap the contents.
1713 :
1714 : Exchanges the contents of this string with another string. Ownership of
1715 : the respective @ref boost::container::pmr::memory_resource objects is
1716 : not transferred.
1717 :
1718 : @li If `&other == this`, do nothing. Otherwise,
1719 : @li if `*other.storage() == *this->storage()`, ownership of the
1720 : underlying memory is swapped in constant time, with no possibility
1721 : of exceptions. All iterators and references remain valid.
1722 : Otherwise,
1723 : @li the contents are logically swapped by making copies, which can
1724 : throw. In this case all iterators and references are invalidated.
1725 :
1726 : @par Complexity
1727 : Constant or linear in @ref size() `+ other.size()`.
1728 :
1729 : @par Exception Safety
1730 : Strong guarantee. Calls to `memory_resource::allocate` may throw.
1731 : */
1732 : BOOST_JSON_DECL
1733 : void
1734 : swap(string& other);
1735 :
1736 : /** Exchange the given values.
1737 :
1738 : Exchanges the contents of the string `lhs` with another string `rhs`.
1739 : Ownership of the respective @ref boost::container::pmr::memory_resource
1740 : objects is not transferred.
1741 :
1742 : @li If `&lhs == &rhs`, do nothing. Otherwise,
1743 : @li if `*lhs.storage() == *rhs.storage()`, ownership of the underlying
1744 : memory is swapped in constant time, with no possibility of
1745 : exceptions. All iterators and references remain valid. Otherwise,
1746 : @li the contents are logically swapped by making a copy, which can
1747 : throw. In this case all iterators and references are invalidated.
1748 :
1749 : @par Effects
1750 : @code
1751 : lhs.swap( rhs );
1752 : @endcode
1753 :
1754 : @par Complexity
1755 : Constant or linear in `lhs.size() + rhs.size()`.
1756 :
1757 : @par Exception Safety
1758 : Strong guarantee.
1759 : Calls to `memory_resource::allocate` may throw.
1760 :
1761 : @param lhs The string to exchange.
1762 : @param rhs The string to exchange.
1763 :
1764 : @see @ref string::swap
1765 : */
1766 : friend
1767 : void
1768 2 : swap(string& lhs, string& rhs)
1769 : {
1770 2 : lhs.swap(rhs);
1771 2 : }
1772 : //------------------------------------------------------
1773 : //
1774 : // Search
1775 : //
1776 : //------------------------------------------------------
1777 :
1778 : /** Find the first occurrence of characters within the string.
1779 :
1780 : Search from `pos` onward for the first substring that is equal to the
1781 : first argument.
1782 :
1783 : @li **(1)** searches for the presense of the substring equal to `sv`.
1784 : @li **(2)** searches for the presense of the substring consisting of
1785 : the character `ch`.
1786 :
1787 : @par Complexity
1788 : Linear in @ref size().
1789 :
1790 : @par Exception Safety
1791 : No-throw guarantee.
1792 :
1793 : @return The index of the first character of the found substring, or
1794 : @ref npos if none was found.
1795 :
1796 : @param sv The `string_view` to search for.
1797 : @param pos The index to start searching at.
1798 :
1799 : @{
1800 : */
1801 : std::size_t
1802 5 : find(
1803 : string_view sv,
1804 : std::size_t pos = 0) const noexcept
1805 : {
1806 5 : return subview().find(sv, pos);
1807 : }
1808 :
1809 : /** Overload
1810 :
1811 : @param ch The character to search for.
1812 : @param pos
1813 : */
1814 : std::size_t
1815 3 : find(
1816 : char ch,
1817 : std::size_t pos = 0) const noexcept
1818 : {
1819 3 : return subview().find(ch, pos);
1820 : }
1821 : /// @}
1822 :
1823 : /** Find the last occurrence of a string within the string.
1824 :
1825 : @li **(1)** searches for the last substring equal to `sv`.
1826 : @li **(2)** searches for the last occurrence of `ch`.
1827 :
1828 : Both functions search for substrings fully contained within `[begin(),
1829 : begin() + pos)`.
1830 :
1831 : @par Complexity
1832 : Linear.
1833 :
1834 : @return Index of the first character of the found substring or
1835 : @ref npos if none was found.
1836 :
1837 : @param sv The string to search for.
1838 : @param pos The index to start searching at. By default searches from
1839 : the end of the string.
1840 :
1841 : @{
1842 : */
1843 : std::size_t
1844 5 : rfind(
1845 : string_view sv,
1846 : std::size_t pos = npos) const noexcept
1847 : {
1848 5 : return subview().rfind(sv, pos);
1849 : }
1850 :
1851 : /** Overload
1852 :
1853 : @param ch The character to search for.
1854 : @param pos
1855 : */
1856 : std::size_t
1857 3 : rfind(
1858 : char ch,
1859 : std::size_t pos = npos) const noexcept
1860 : {
1861 3 : return subview().rfind(ch, pos);
1862 : }
1863 : /// @}
1864 :
1865 : //------------------------------------------------------
1866 :
1867 : /** Find the first character present in the specified string.
1868 :
1869 : Search from `pos` onward for the first character in this string that is
1870 : equal to any of the characters of `sv`.
1871 :
1872 : @par Complexity
1873 : Linear in @ref size() `+ sv.size()`.
1874 :
1875 : @par Exception Safety
1876 : No-throw guarantee.
1877 :
1878 : @return The index of the found character, or @ref npos if none exists.
1879 :
1880 : @param sv The characters to search for.
1881 : @param pos The index to start searching at.
1882 : */
1883 : std::size_t
1884 5 : find_first_of(
1885 : string_view sv,
1886 : std::size_t pos = 0) const noexcept
1887 : {
1888 5 : return subview().find_first_of(sv, pos);
1889 : }
1890 :
1891 : /** Find the first character missing from the specified string.
1892 :
1893 : Search from `pos` onward for the first character in this string that is
1894 : not equal to any of the characters in the string provided as the first
1895 : argument.
1896 :
1897 : @li **(1)** compares with the characters in `sv`.
1898 : @li **(2)** compares with the character `ch`.
1899 :
1900 : @par Complexity
1901 : @li **(1)** linear in @ref size() `+ sv.size()`.
1902 : @li **(2)** linear in @ref size().
1903 :
1904 : @par Exception Safety
1905 : No-throw guarantee.
1906 :
1907 : @return The index of the found character, or @ref npos if none exists.
1908 :
1909 : @param sv The characters to compare with.
1910 : @param pos The index to start searching at.
1911 :
1912 : @{
1913 : */
1914 : std::size_t
1915 4 : find_first_not_of(
1916 : string_view sv,
1917 : std::size_t pos = 0) const noexcept
1918 : {
1919 4 : return subview().find_first_not_of(sv, pos);
1920 : }
1921 :
1922 : /** Overload
1923 : @param ch The character to compare with.
1924 : @param pos
1925 : */
1926 : std::size_t
1927 3 : find_first_not_of(
1928 : char ch,
1929 : std::size_t pos = 0) const noexcept
1930 : {
1931 3 : return subview().find_first_not_of(ch, pos);
1932 : }
1933 : /// @}
1934 :
1935 : /** Find the last character present in the specified string.
1936 :
1937 : Search from `pos` backwards for the first character in this string that
1938 : is equal to any of the characters of `sv`. If `pos` is equal to @ref
1939 : npos (the default), search from the last character.
1940 :
1941 : @par Complexity
1942 : Linear in @ref size() `+ sv.size()`.
1943 :
1944 : @par Exception Safety
1945 : No-throw guarantee.
1946 :
1947 : @return The index of the found character, or @ref npos if none exists.
1948 :
1949 : @param sv The characters to search for.
1950 : @param pos The index to start searching at.
1951 : */
1952 : std::size_t
1953 5 : find_last_of(
1954 : string_view sv,
1955 : std::size_t pos = npos) const noexcept
1956 : {
1957 5 : return subview().find_last_of(sv, pos);
1958 : }
1959 :
1960 : /** Find the last character missing from the specified string.
1961 :
1962 :
1963 : Search from `pos` backwards for the first character in this string that
1964 : is not equal to any of the characters in the string provided as the
1965 : first argument. If `pos` is equal to @ref npos (the default), search
1966 : from the last character.
1967 :
1968 : @li **(1)** compares with the characters in `sv`.
1969 : @li **(2)** compares with the character `ch`.
1970 :
1971 : @par Complexity
1972 : @li **(1)** linear in @ref size() `+ sv.size()`.
1973 : @li **(2)** linear in @ref size().
1974 :
1975 : @par Exception Safety
1976 : No-throw guarantee.
1977 :
1978 : @return The index of the found character, or @ref npos if none exists.
1979 :
1980 : @param sv The characters to compare with.
1981 : @param pos The index to start searching at.
1982 :
1983 : @{
1984 : */
1985 : std::size_t
1986 4 : find_last_not_of(
1987 : string_view sv,
1988 : std::size_t pos = npos) const noexcept
1989 : {
1990 4 : return subview().find_last_not_of(sv, pos);
1991 : }
1992 :
1993 : /** Overload
1994 : @param ch The character to compare with.
1995 : @param pos
1996 : */
1997 : std::size_t
1998 3 : find_last_not_of(
1999 : char ch,
2000 : std::size_t pos = npos) const noexcept
2001 : {
2002 3 : return subview().find_last_not_of(ch, pos);
2003 : }
2004 : /// @}
2005 :
2006 : /** Serialize a @ref string to an output stream.
2007 :
2008 : This function serializes a `string` as JSON into the output stream.
2009 :
2010 : @return Reference to `os`.
2011 :
2012 : @par Complexity
2013 : Linear in the `str.size()`.
2014 :
2015 : @par Exception Safety
2016 : Strong guarantee. Calls to `memory_resource::allocate` may throw.
2017 :
2018 : @param os The output stream to serialize to.
2019 : @param str The value to serialize.
2020 : */
2021 : BOOST_JSON_DECL
2022 : friend
2023 : std::ostream&
2024 : operator<<(
2025 : std::ostream& os,
2026 : string const& str);
2027 :
2028 : private:
2029 : class undo;
2030 :
2031 : template<class It>
2032 : using iter_cat = typename
2033 : std::iterator_traits<It>::iterator_category;
2034 :
2035 : template<class InputIt>
2036 : void
2037 : assign(InputIt first, InputIt last,
2038 : std::random_access_iterator_tag);
2039 :
2040 : template<class InputIt>
2041 : void
2042 : assign(InputIt first, InputIt last,
2043 : std::input_iterator_tag);
2044 :
2045 : template<class InputIt>
2046 : void
2047 : append(InputIt first, InputIt last,
2048 : std::random_access_iterator_tag);
2049 :
2050 : template<class InputIt>
2051 : void
2052 : append(InputIt first, InputIt last,
2053 : std::input_iterator_tag);
2054 :
2055 : BOOST_JSON_DECL
2056 : void
2057 : reserve_impl(std::size_t new_capacity);
2058 : };
2059 :
2060 : //----------------------------------------------------------
2061 :
2062 : namespace detail
2063 : {
2064 :
2065 : template <>
2066 : inline
2067 : string_view
2068 28860 : to_string_view<string>(string const& s) noexcept
2069 : {
2070 28860 : return s.subview();
2071 : }
2072 :
2073 : } // namespace detail
2074 :
2075 :
2076 : /** Checks if lhs equals rhs.
2077 :
2078 : @li **(1)** A lexicographical comparison is used.
2079 : @li **(2)** equivalent to `lhs.get() == rhs.get()`.
2080 :
2081 : @par Complexity
2082 : @li **(1)** linear in `lhs.size() + rhs.size()`.
2083 : @li **(2)** constant.
2084 :
2085 : @par Exception Safety
2086 : No-throw guarantee.
2087 : */
2088 : #ifdef BOOST_JSON_DOCS
2089 : bool
2090 : operator==(string const& lhs, string const& rhs) noexcept
2091 : #else
2092 : template<class T, class U>
2093 : detail::string_comp_op_requirement<T, U>
2094 15623 : operator==(T const& lhs, U const& rhs) noexcept
2095 : #endif
2096 : {
2097 15623 : return detail::to_string_view(lhs) == detail::to_string_view(rhs);
2098 : }
2099 :
2100 : /** Checks if lhs does not equal rhs.
2101 :
2102 : @li **(1)** A lexicographical comparison is used.
2103 : @li **(2)** equivalent to `lhs.get() != rhs.get()`.
2104 :
2105 : @par Complexity
2106 : @li **(1)** linear in `lhs.size() + rhs.size()`.
2107 : @li **(2)** constant.
2108 :
2109 : @par Exception Safety
2110 : No-throw guarantee.
2111 : */
2112 : #ifdef BOOST_JSON_DOCS
2113 : bool
2114 : operator!=(string const& lhs, string const& rhs) noexcept
2115 : #else
2116 : template<class T, class U>
2117 : detail::string_comp_op_requirement<T, U>
2118 24 : operator!=(T const& lhs, U const& rhs) noexcept
2119 : #endif
2120 : {
2121 24 : return detail::to_string_view(lhs) != detail::to_string_view(rhs);
2122 : }
2123 :
2124 : /** Check if lhs is less than rhs.
2125 :
2126 : A lexicographical comparison is used.
2127 :
2128 : @par Complexity
2129 : Linear in `lhs.size() + rhs.size()`.
2130 :
2131 : @par Exception Safety
2132 : No-throw guarantee.
2133 : */
2134 : #ifdef BOOST_JSON_DOCS
2135 : bool
2136 : operator<(string const& lhs, string const& rhs) noexcept
2137 : #else
2138 : template<class T, class U>
2139 : detail::string_comp_op_requirement<T, U>
2140 12 : operator<(T const& lhs, U const& rhs) noexcept
2141 : #endif
2142 : {
2143 12 : return detail::to_string_view(lhs) < detail::to_string_view(rhs);
2144 : }
2145 :
2146 : /** Check if lhs is less than or equal to rhs.
2147 :
2148 : A lexicographical comparison is used.
2149 :
2150 : @par Complexity
2151 : Linear in `lhs.size() + rhs.size()`.
2152 :
2153 : @par Exception Safety
2154 : No-throw guarantee.
2155 : */
2156 : #ifdef BOOST_JSON_DOCS
2157 : bool
2158 : operator<=(string const& lhs, string const& rhs) noexcept
2159 : #else
2160 : template<class T, class U>
2161 : detail::string_comp_op_requirement<T, U>
2162 12 : operator<=(T const& lhs, U const& rhs) noexcept
2163 : #endif
2164 : {
2165 12 : return detail::to_string_view(lhs) <= detail::to_string_view(rhs);
2166 : }
2167 :
2168 : /** Check if lhs is more than or equal to rhs.
2169 :
2170 : A lexicographical comparison is used.
2171 :
2172 : @par Complexity
2173 : Linear in `lhs.size() + rhs.size()`.
2174 :
2175 : @par Exception Safety
2176 : No-throw guarantee.
2177 : */
2178 : #ifdef BOOST_JSON_DOCS
2179 : bool
2180 : operator>=(string const& lhs, string const& rhs) noexcept
2181 : #else
2182 : template<class T, class U>
2183 : detail::string_comp_op_requirement<T, U>
2184 12 : operator>=(T const& lhs, U const& rhs) noexcept
2185 : #endif
2186 : {
2187 12 : return detail::to_string_view(lhs) >= detail::to_string_view(rhs);
2188 : }
2189 :
2190 : /** Check if lhs is greater than rhs.
2191 :
2192 : A lexicographical comparison is used.
2193 :
2194 : @par Complexity
2195 : Linear in `lhs.size() + rhs.size()`.
2196 :
2197 : @par Exception Safety
2198 : No-throw guarantee.
2199 : */
2200 : #ifdef BOOST_JSON_DOCS
2201 : bool
2202 : operator>(string const& lhs, string const& rhs) noexcept
2203 : #else
2204 : template<class T, class U>
2205 : detail::string_comp_op_requirement<T, U>
2206 12 : operator>(T const& lhs, U const& rhs) noexcept
2207 : #endif
2208 : {
2209 12 : return detail::to_string_view(lhs) > detail::to_string_view(rhs);
2210 : }
2211 :
2212 : } // namespace json
2213 : } // namespace boost
2214 :
2215 : // std::hash specialization
2216 : #ifndef BOOST_JSON_DOCS
2217 : namespace std {
2218 : template<>
2219 : struct hash< ::boost::json::string >
2220 : {
2221 : BOOST_JSON_DECL
2222 : std::size_t
2223 : operator()( ::boost::json::string const& js ) const noexcept;
2224 : };
2225 : } // std
2226 : #endif
2227 :
2228 : #include <boost/json/impl/string.hpp>
2229 :
2230 : #endif
|