string
Modifiable sequences of characters are represented using objects of type
string.
The interface and functionality of string is the same as std::string
except that:
-
stringis not a class template, -
stringusescharas its character type, -
redundant overloads for string operations have been replaced with a
string_view-based interface, -
access to characters in the range
[size(), capacity())is permitted, -
storage_ptris used instead of Allocator, and -
small buffer optimisation is guaranteed, which avoids allocating memory for small strings.
With augmented interface, operations requiring an input string are implemented
as a single overload with a parameter of type string_view, and can
accept most string-like objects. Objects such as null terminated character
pointers, std::string, string, subranges of strings, and objects
convertible to string_view can all be passed to these functions.
json::string str = "Boost.JSON";
json::string_view sv = str;
// all of these call compare(string_view)
str.compare(sv);
str.compare(sv.substr(0, 5));
str.compare(str);
str.compare("Boost");
More formally, std::string member function overloads that accept any of the
following parameter combinations as an input string:
-
a
std::stringparameter, or -
a
std::stringparameter and twosize_typeparameters that specify a substring, or -
a parameter of a type convertible to
string_view, or -
a parameter of a type convertible to
string_viewand twosize_typeparameters that specify a substring, or -
a
const_pointerparameter, or -
a parameter of type
const_pointerand asize_typeparameter that specifies the length of the string
are replaced with an overload accepting a string_view parameter.
This design removes several redundant overloads from the interface. For
example, the 11 overloads of std::string::insert are reduced to just 3 in
string, while still providing identical functionality. In addition
to these changes, overloads taking a std::initializer_list<char> parameter
have been removed. Such overloads have little use, as they serve as little more
than wrappers for arrays with an inefficient syntax:
std::string sstr = "hello";
json::string jstr = "hello";
assert(sstr.append({'w', 'o', 'r', 'l', 'd'}) == "helloworld");
// such syntax is inefficient, and the same can
// be achieved with a character array.
assert(jstr.append("world") == "helloworld");
With the removal of overloads that specify parameters for a substring, a member
function subview that returns a string_view is provided to
facilitate cheap substring operations:
std::string sstr1 = "helloworld";
std::string sstr2 = "world";
json::string jstr1 = "helloworld";
json::string jstr2 = "world";
assert( jstr2.insert(0, jstr1.subview(0, 5)) == "helloworld" );
// this is equivalent to
assert( sstr2.insert(0, sstr1, 0, 5) == "helloworld" );
A string may be constructed using the default
memory resource without incurring any memory allocations. Alternatively,
a storage_ptr can be provided explicitly:
string str1; // empty string, uses the default memory resource
string str2( make_shared_resource<monotonic_resource>() ); // empty string, uses a counted monotonic resource
Formatted Output
When a string is formatted to a std::ostream, the result is a valid
JSON. That is, the result will be double quoted and the contents properly
escaped per the JSON specification.
Accessing Storage Beyond size()
string directly supports access to its storage in the range [size(),
capacity()). This can be used for efficient assembly of a string from several
parts. After the string is assembled, use the member function
string::grow to update the string’s size and insert the null terminator.
For example:
string greeting( string_view first_name, string_view last_name )
{
const char hello[] = "Hello, ";
const std::size_t sz = first_name.size() + last_name.size() + sizeof(hello) + 1;
string js;
js.reserve(sz);
char* p = std::copy( hello, hello + sizeof(hello) - 1, js.data() );
p = std::copy( first_name.begin(), first_name.end(), p );
*p++ = ' ';
p = std::copy( last_name.begin(), last_name.end(), p );
*p++ = '!';
js.grow( sz );
return js;
}