string.hpp

100.0% Lines (156/156) 100.0% List of functions (95/95)
string.hpp
f(x) Functions (95)
Function Calls Lines Blocks
boost::json::string::~string() :147 30737x 100.0% 100.0% boost::json::string::string() :233 2471x 100.0% 100.0% boost::json::string::string(boost::json::storage_ptr) :242 9110x 100.0% 100.0% boost::json::string::string(boost::json::string&&) :318 425x 100.0% 100.0% boost::json::string::string(boost::json::pilfered<boost::json::string>) :333 5x 100.0% 100.0% boost::json::string::assign(boost::core::basic_string_view<char>) :507 17995x 100.0% 100.0% boost::json::string::storage() const :540 118x 100.0% 100.0% boost::json::string::get_allocator() const :557 1x 100.0% 100.0% boost::json::string::is_seamless() const :564 14751x 100.0% 100.0% boost::json::string::set_seamless(bool) :570 4x 100.0% 100.0% boost::json::string::operator[](unsigned long) :654 18x 100.0% 100.0% boost::json::string::operator[](unsigned long) const :660 2x 100.0% 100.0% boost::json::string::front() :684 10x 100.0% 100.0% boost::json::string::front() const :690 6x 100.0% 100.0% boost::json::string::back() :711 39x 100.0% 100.0% boost::json::string::back() const :717 6x 100.0% 100.0% boost::json::string::data() :741 24137x 100.0% 100.0% boost::json::string::data() const :747 44146x 100.0% 100.0% boost::json::string::c_str() const :766 4x 100.0% 100.0% boost::json::string::operator boost::core::basic_string_view<char>() const :781 61x 100.0% 100.0% boost::json::string::begin() :824 34x 100.0% 100.0% boost::json::string::begin() const :830 8x 100.0% 100.0% boost::json::string::cbegin() const :847 2x 100.0% 100.0% boost::json::string::end() :866 3x 100.0% 100.0% boost::json::string::end() const :872 3x 100.0% 100.0% boost::json::string::cend() const :890 2x 100.0% 100.0% boost::json::string::rbegin() :907 3x 100.0% 100.0% boost::json::string::rbegin() const :913 3x 100.0% 100.0% boost::json::string::crbegin() const :932 2x 100.0% 100.0% boost::json::string::rend() :952 3x 100.0% 100.0% boost::json::string::rend() const :958 3x 100.0% 100.0% boost::json::string::crend() const :978 2x 100.0% 100.0% boost::json::string::empty() const :1001 69x 100.0% 100.0% boost::json::string::size() const :1015 48118x 100.0% 100.0% boost::json::string::max_size() :1032 7900x 100.0% 100.0% boost::json::string::capacity() const :1050 11774x 100.0% 100.0% boost::json::string::reserve(unsigned long) :1078 11395x 100.0% 100.0% boost::json::string::insert(unsigned long, char) :1181 3x 100.0% 100.0% boost::json::string::operator+=(boost::core::basic_string_view<char>) :1379 11x 100.0% 100.0% boost::json::string::operator+=(char) :1388 44x 100.0% 100.0% boost::json::string::compare(boost::core::basic_string_view<char>) const :1413 13x 100.0% 100.0% boost::json::string::starts_with(boost::core::basic_string_view<char>) const :1434 8x 100.0% 100.0% boost::json::string::starts_with(char) const :1444 4x 100.0% 100.0% boost::json::string::ends_with(boost::core::basic_string_view<char>) const :1467 8x 100.0% 100.0% boost::json::string::ends_with(char) const :1477 4x 100.0% 100.0% boost::json::string::replace(char const*, char const*, boost::core::basic_string_view<char>) :1536 6x 100.0% 100.0% boost::json::string::replace(char const*, char const*, unsigned long, char) :1590 1x 100.0% 100.0% boost::json::string::subview(unsigned long, unsigned long) const :1616 43x 100.0% 100.0% boost::json::string::subview() const :1625 29030x 100.0% 100.0% boost::json::string::copy(char*, unsigned long, unsigned long) const :1651 2x 100.0% 100.0% boost::json::string::resize(unsigned long) :1674 57x 100.0% 100.0% boost::json::string::grow(unsigned long) :1705 15183x 100.0% 86.0% boost::json::swap(boost::json::string&, boost::json::string&) :1768 2x 100.0% 100.0% boost::json::string::find(boost::core::basic_string_view<char>, unsigned long) const :1802 5x 100.0% 100.0% boost::json::string::find(char, unsigned long) const :1815 3x 100.0% 100.0% boost::json::string::rfind(boost::core::basic_string_view<char>, unsigned long) const :1844 5x 100.0% 100.0% boost::json::string::rfind(char, unsigned long) const :1857 3x 100.0% 100.0% boost::json::string::find_first_of(boost::core::basic_string_view<char>, unsigned long) const :1884 5x 100.0% 100.0% boost::json::string::find_first_not_of(boost::core::basic_string_view<char>, unsigned long) const :1915 4x 100.0% 100.0% boost::json::string::find_first_not_of(char, unsigned long) const :1927 3x 100.0% 100.0% boost::json::string::find_last_of(boost::core::basic_string_view<char>, unsigned long) const :1953 5x 100.0% 100.0% boost::json::string::find_last_not_of(boost::core::basic_string_view<char>, unsigned long) const :1986 4x 100.0% 100.0% boost::json::string::find_last_not_of(char, unsigned long) const :1998 3x 100.0% 100.0% boost::core::basic_string_view<char> boost::json::detail::to_string_view<boost::json::string>(boost::json::string const&) :2068 28860x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::core::basic_string_view<char>, boost::json::string>(boost::core::basic_string_view<char> const&, boost::json::string const&) :2094 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, boost::core::basic_string_view<char> >(boost::json::string const&, boost::core::basic_string_view<char> const&) :2094 102x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, boost::json::string>(boost::json::string const&, boost::json::string const&) :2094 56x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const (&) [14], boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char [14], boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, char [14]>(boost::json::string const&, char const (&) [14]) :2094 1x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const (&) [3], boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char [3], boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, char [3]>(boost::json::string const&, char const (&) [3]) :2094 97x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const (&) [4], boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char [4], boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, char [4]>(boost::json::string const&, char const (&) [4]) :2094 8x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const (&) [6], boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char [6], boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, char [6]>(boost::json::string const&, char const (&) [6]) :2094 15x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, char const*>(boost::json::string const&, char const* const&) :2094 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<boost::json::string, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(boost::json::string const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) :2094 91x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator==<char const*, boost::json::string>(char const* const&, boost::json::string const&) :2094 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator!=<boost::core::basic_string_view<char>, boost::json::string>(boost::core::basic_string_view<char> const&, boost::json::string const&) :2118 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator!=<boost::json::string, boost::core::basic_string_view<char> >(boost::json::string const&, boost::core::basic_string_view<char> const&) :2118 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator!=<boost::json::string, boost::json::string>(boost::json::string const&, boost::json::string const&) :2118 4x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const (&) [3], boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char [3], boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator!=<boost::json::string, char [3]>(boost::json::string const&, char const (&) [3]) :2118 12x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator!=<boost::json::string, char const*>(boost::json::string const&, char const* const&) :2118 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator!=<char const*, boost::json::string>(char const* const&, boost::json::string const&) :2118 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator< <boost::core::basic_string_view<char>, boost::json::string>(boost::core::basic_string_view<char> const&, boost::json::string const&) :2140 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator< <boost::json::string, boost::core::basic_string_view<char> >(boost::json::string const&, boost::core::basic_string_view<char> const&) :2140 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator< <boost::json::string, boost::json::string>(boost::json::string const&, boost::json::string const&) :2140 4x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator< <boost::json::string, char const*>(boost::json::string const&, char const* const&) :2140 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator< <char const*, boost::json::string>(char const* const&, boost::json::string const&) :2140 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator<=<boost::core::basic_string_view<char>, boost::json::string>(boost::core::basic_string_view<char> const&, boost::json::string const&) :2162 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator<=<boost::json::string, boost::core::basic_string_view<char> >(boost::json::string const&, boost::core::basic_string_view<char> const&) :2162 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator<=<boost::json::string, boost::json::string>(boost::json::string const&, boost::json::string const&) :2162 4x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator<=<boost::json::string, char const*>(boost::json::string const&, char const* const&) :2162 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator<=<char const*, boost::json::string>(char const* const&, boost::json::string const&) :2162 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator>=<boost::core::basic_string_view<char>, boost::json::string>(boost::core::basic_string_view<char> const&, boost::json::string const&) :2184 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::core::basic_string_view<char> const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::core::basic_string_view<char>, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator>=<boost::json::string, boost::core::basic_string_view<char> >(boost::json::string const&, boost::core::basic_string_view<char> const&) :2184 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator>=<boost::json::string, boost::json::string>(boost::json::string const&, boost::json::string const&) :2184 4x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator>=<boost::json::string, char const*>(boost::json::string const&, char const* const&) :2184 2x 100.0% 100.0% std::enable_if<std::integral_constant<bool, std::is_same<char const*, boost::json::string>::value&&std::is_convertible<boost::json::string const&, boost::core::basic_string_view<char> >::value>::value||std::integral_constant<bool, std::is_same<boost::json::string, boost::json::string>::value&&std::is_convertible<char const* const&, boost::core::basic_string_view<char> >::value>::value, bool>::type boost::json::operator>=<char const*, boost::json::string>(char const* const&, boost::json::string const&) :2184 2x 100.0% 100.0%
Line TLA Hits 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 30737x ~string() noexcept
148 {
149 30737x impl_.destroy(sp_);
150 30737x }
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 2471x 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 9110x string(storage_ptr sp)
243 9110x : sp_(std::move(sp))
244 {
245 9110x }
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 425x string(string&& other) noexcept
319 425x : sp_(other.sp_)
320 425x , impl_(other.impl_)
321 {
322 425x ::new(&other.impl_) string_impl();
323 425x }
324
325 /// Overload
326 BOOST_JSON_DECL
327 explicit
328 string(
329 string&& other,
330 storage_ptr sp);
331
332 /// Overload
333 5x string(pilfered<string> other) noexcept
334 5x : sp_(std::move(other.get().sp_))
335 5x , impl_(other.get().impl_)
336 {
337 5x ::new(&other.get().impl_) string_impl();
338 5x }
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 17995x assign(string_view s)
508 {
509 17995x 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 118x storage() const noexcept
541 {
542 118x 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 1x get_allocator() const noexcept
558 {
559 1x return sp_.get();
560 }
561
562 constexpr
563 bool
564 14751x is_seamless() const noexcept
565 {
566 14751x return impl_.is_seamless();
567 }
568
569 void
570 4x set_seamless(bool on) noexcept
571 {
572 4x impl_.set_seamless(on);
573 4x }
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 18x operator[](std::size_t pos)
655 {
656 18x return impl_.data()[pos];
657 }
658
659 const char&
660 2x operator[](std::size_t pos) const
661 {
662 2x 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 10x front()
685 {
686 10x return impl_.data()[0];
687 }
688
689 char const&
690 6x front() const
691 {
692 6x 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 39x back()
712 {
713 39x return impl_.data()[impl_.size() - 1];
714 }
715
716 char const&
717 6x back() const
718 {
719 6x 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 24137x data() noexcept
742 {
743 24137x return impl_.data();
744 }
745
746 char const*
747 44146x data() const noexcept
748 {
749 44146x 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 4x c_str() const noexcept
767 {
768 4x 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 61x operator string_view() const noexcept
782 {
783 61x 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 34x begin() noexcept
825 {
826 34x return impl_.data();
827 }
828
829 const_iterator
830 8x begin() const noexcept
831 {
832 8x 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 2x cbegin() const noexcept
848 {
849 2x 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 3x end() noexcept
867 {
868 3x return impl_.end();
869 }
870
871 const_iterator
872 3x end() const noexcept
873 {
874 3x 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 2x cend() const noexcept
891 {
892 2x 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 3x rbegin() noexcept
908 {
909 3x return reverse_iterator(impl_.end());
910 }
911
912 const_reverse_iterator
913 3x rbegin() const noexcept
914 {
915 3x 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 2x crbegin() const noexcept
933 {
934 2x 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 3x rend() noexcept
953 {
954 3x return reverse_iterator(begin());
955 }
956
957 const_reverse_iterator
958 3x rend() const noexcept
959 {
960 3x 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 2x crend() const noexcept
979 {
980 2x 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 69x empty() const noexcept
1002 {
1003 69x 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 48118x size() const noexcept
1016 {
1017 48118x 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 7900x max_size() noexcept
1033 {
1034 7900x 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 11774x capacity() const noexcept
1051 {
1052 11774x 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 11395x reserve(std::size_t new_capacity)
1079 {
1080 11395x if(new_capacity <= capacity())
1081 1668x return;
1082 9727x 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 3x insert(
1182 size_type pos,
1183 char ch)
1184 {
1185 3x 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 11x operator+=(string_view sv)
1380 {
1381 11x return append(sv);
1382 }
1383
1384 /** Overload
1385 @param ch The character to append.
1386 */
1387 string&
1388 44x operator+=(char ch)
1389 {
1390 44x push_back(ch);
1391 43x 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 13x compare(string_view sv) const noexcept
1414 {
1415 13x 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 8x starts_with(string_view s) const noexcept
1435 {
1436 8x return subview(0, s.size()) == s;
1437 }
1438
1439 /** Overload
1440
1441 @param ch The character to check for.
1442 */
1443 bool
1444 4x starts_with(char ch) const noexcept
1445 {
1446 4x 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 8x ends_with(string_view s) const noexcept
1468 {
1469 16x return size() >= s.size() &&
1470 16x subview(size() - s.size()) == s;
1471 }
1472
1473 /** Overload
1474 @param ch The character to check for.
1475 */
1476 bool
1477 4x ends_with(char ch) const noexcept
1478 {
1479 4x 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 6x replace(
1537 const_iterator first,
1538 const_iterator last,
1539 string_view sv)
1540 {
1541 6x 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 1x replace(
1591 const_iterator first,
1592 const_iterator last,
1593 std::size_t count2,
1594 char ch)
1595 {
1596 1x 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 43x subview(
1617 std::size_t pos,
1618 std::size_t count = npos) const
1619 {
1620 43x return subview().substr(pos, count);
1621 }
1622
1623 /// Overload
1624 string_view
1625 29030x subview() const noexcept
1626 {
1627 29030x 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 2x copy(
1652 char* dest,
1653 std::size_t count,
1654 std::size_t pos = 0) const
1655 {
1656 2x 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 57x resize(std::size_t count)
1675 {
1676 57x resize(count, 0);
1677 54x }
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 15183x grow(std::size_t n) noexcept
1706 {
1707 15183x BOOST_ASSERT(
1708 n <= impl_.capacity() - impl_.size());
1709 15183x impl_.term(impl_.size() + n);
1710 15183x }
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 2x swap(string& lhs, string& rhs)
1769 {
1770 2x lhs.swap(rhs);
1771 2x }
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 5x find(
1803 string_view sv,
1804 std::size_t pos = 0) const noexcept
1805 {
1806 5x 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 3x find(
1816 char ch,
1817 std::size_t pos = 0) const noexcept
1818 {
1819 3x 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 5x rfind(
1845 string_view sv,
1846 std::size_t pos = npos) const noexcept
1847 {
1848 5x 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 3x rfind(
1858 char ch,
1859 std::size_t pos = npos) const noexcept
1860 {
1861 3x 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 5x find_first_of(
1885 string_view sv,
1886 std::size_t pos = 0) const noexcept
1887 {
1888 5x 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 4x find_first_not_of(
1916 string_view sv,
1917 std::size_t pos = 0) const noexcept
1918 {
1919 4x 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 3x find_first_not_of(
1928 char ch,
1929 std::size_t pos = 0) const noexcept
1930 {
1931 3x 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 5x find_last_of(
1954 string_view sv,
1955 std::size_t pos = npos) const noexcept
1956 {
1957 5x 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 4x find_last_not_of(
1987 string_view sv,
1988 std::size_t pos = npos) const noexcept
1989 {
1990 4x 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 3x find_last_not_of(
1999 char ch,
2000 std::size_t pos = npos) const noexcept
2001 {
2002 3x 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 28860x to_string_view<string>(string const& s) noexcept
2069 {
2070 28860x 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 15623x operator==(T const& lhs, U const& rhs) noexcept
2095 #endif
2096 {
2097 15623x 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 24x operator!=(T const& lhs, U const& rhs) noexcept
2119 #endif
2120 {
2121 24x 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 12x operator<(T const& lhs, U const& rhs) noexcept
2141 #endif
2142 {
2143 12x 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 12x operator<=(T const& lhs, U const& rhs) noexcept
2163 #endif
2164 {
2165 12x 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 12x operator>=(T const& lhs, U const& rhs) noexcept
2185 #endif
2186 {
2187 12x 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 12x operator>(T const& lhs, U const& rhs) noexcept
2207 #endif
2208 {
2209 12x 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
2231