| Home | Libraries | People | FAQ | More

### string

Modifiable sequences of characters are represented using objects of type `string`. The interface and functionality of `string` is the same as `std::basic_string` except that:

- `string` is not a class template,
- `string` uses `char` as 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_ptr` is used instead of Allocator, and
- guaranteed small buffer optimisation that 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`, `json::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::string` parameter, or
- a `std::string` parameter and two `size_type` parameters that specify a substring, or
- a parameter of a type convertible to `string_view`, or
- a parameter of a type convertible to `string_view` and two `size_type` parameters that specify a substring, or
- a `const_pointer`, or
- a parameter of type `const_pointer` and a `size_type` parameter 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 a 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 `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;
    }