[/
    Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

    Official repository: https://github.com/boostorg/url
]

[section StringToken]

A string token is an rvalue passed to a function template which
customizes the return type of the function and also controls how
a modifiable character buffer is obtained and presented. The
string token's lifetime extends only for the duration of the
function call in which it appears as a parameter. A string
token cannot be copied, moved, or assigned, and must be
destroyed when the function returns or throws.

[heading Requirements]

In this table:

* `T` is a type meeting the requirements of ['StringToken]
* `t` is an rvalue reference of type T
* `n` is a value of type `std::size_t`

[table Valid expressions
[[Expression] [Result] [Semantics, Pre/Post-conditions]]
[
    [
    ```
    std::derived_from<T,string_token::arg>
    ```
    ]
    [
    ```
    true
    ```
    ]
    [
        All string tokens must be publicly and
        unambiguously derived from
        [link url.ref.boost__urls__string_token__arg `string_token::arg`].
    ]
][
    [
    ```
    T::result_type
    ```
    ]
    []
    [
        This type determines the return type of functions
        which accept a string token.
    ]
][
    [
    ```
    t.prepare(n);
    ```
    ]
    [
    ```
    char*
    ```
    ]
    [
        This function overrides the virtual function in the base.
        It must return a pointer to a character buffer of at least
        size `n`, otherwise throw an exception.
    ]
][
    [
    ```
    t.result();
    ```
    ]
    [
    ```
    T::result_type
    ```
    ]
    [
        This function is invoked by the algorithm to receive the result
        from the string token.
        It is only invoked if `prepare` returned successfuly and the
        string token was not destroyed.
    ]
]]



[heading Algorithm Requirements]

When an algorithm accepts a string token, it must meet these requirements:

* `prepare` is called only once or not at all,
* `result` is only called after `prepare` returns successfully, and
* The string token is destroyed when the algorithm completes or if
  an exception is thrown.

String tokens cannot be reused.



[heading Exemplars]

String token prototype:

```
struct StringToken : string_token::arg
{
    using result_type = std::string;

    char* prepare( std::size_t n ) override;

    result_type result();
};
```

Algorithm prototype:

```
namespace detail {

// Algorithm implementation may be placed
// out of line, and written as an ordinary
// function (no template required).

void algorithm_impl( string_token::arg& token )
{
    std::size_t n = 0;

    // calculate space needed in `n`

    // acquire a destination buffer
    char* dest = token.prepare( n );

    // write the characters to the buffer
}    

} // detail

// public interface is a function template,
// defaulting to return `std::string`.

template< class StringToken = string_token::return_string >
auto
algorithm( StringToken&& token = {} ) ->
    typename StringToken::result_type
{
    // invoke the algorithm with the token
    algorithm_impl( token );

    // return the result from the token
    return token.result();
}

```

Models

* __append_to__
* __assign_to__
* __preserve_size__
* __append_to__

[endsect]
