[/
    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 Params]

While the query is specified as a plain string, it is usually
interpreted as a set of key-value pairs commonly referred to as 
[@https://en.wikipedia.org/wiki/Query_string ['URL Parameters]],
although here we use the term ['query parameters] or ['params]
for short. There is no official, standard specification of the
query parameters format, but the W3C recommendations and HTML 5
have this to say:

* The query string is composed of a series of key-value pairs.

* Within each pair, the field name and value are separated by an
  equals sign, "=".

* The series of pairs is separated by the ampersand, "&".

* Most web frameworks allow multiple values to have the same key.

* Key comparisons are usually case sensitive, but the receiving
  authority is ultimately responsible for deciding this.

This URL has two query parameters, `first` and `last` whose
values are "John" and "Doe" respectively:
[teletype]
```
http://www.example.com?first=John&last=Doe
```

Like the path, the library permits access to the params as
using these separate, bidirectional view types which reference
the underlying URL:

[table Params Types [
    [Type]
    [Accessor]
    [Description]
][
    [__params_view__]
    [[link url.ref.boost__urls__url_view_base.params `params`]]
    [
    A read-only range of decoded params.
    ]
][
    [__params_ref__]
    [[link url.ref.boost__urls__url_base.params `params`]]
    [
    A modifiable range of decoded params.
    ]
][
    [__params_encoded_view__]
    [[link url.ref.boost__urls__url_view_base.encoded_params `encoded_params`]]
    [
    A read-only range of params.
    ]
][
    [__params_encoded_ref__]
    [[link url.ref.boost__urls__url_base.encoded_params `encoded_params`]]
    [
    A modifiable range of params.
    ]
]]

A param always has a key, even if it is the empty string.
The value is optional; an empty string is distinct from
no value. To represent individual params the library uses
these types, distinguished by their ownership model and
whether or not percent-escapes are possible:

[table Param Types [
    [Type]
    [String Type]
    [Description]
][
    [__param__]
    [__std_string__]
    [
    A key-value pair with ownership of the strings.
    This can be used to hold decoded strings, or to
    allow the caller to take ownership of a param
    by making a copy.
    ]
][
    [__param_view__]
    [__string_view__]
    [
    A key-value pair without percent-escapes,
    referencing externally managed character buffers.
    ]
][
    [__param_pct_view__]
    [__pct_string_view__]
    [
    A key-value pair which may contain percent-escapes,
    referencing externally managed character buffers.
    ]
]]

Param types can be constructed from initializer lists,
allowing for convenient notation. To represent a missing
value, the constant
[link url.ref.boost__urls__no_value `no_value`]
or `nullptr` may be used. This table shows some examples
of initializer lists used to construct a param type, and
the resulting data members:

[table Param Initializers [
    [Statement]
    [`qp.key`]
    [`qp.value`]
    [`qp.has_value`]
][
    [`param qp = { "first", "John" };`]
    [`"First"`]
    [`"John"`]
    [`true`]
][
    [`param qp = { "first", "" };`]
    [`"First"`]
    [`""`]
    [`true`]
][
    [`param qp = { "first", no_value };`]
    [`"First"`]
    [`""`]
    [`false`]
][
    [`param qp = { "", "Doe" };`]
    [`""`]
    [`"Doe"`]
    [`true`]
]]

To understand the relationship between the query and the
resulting range of params, first we define this
function `parms` which returns a list of params
corresponding to the elements in a container
of params:

[code_container_5_1]

In the table below we show the result of invoking `parms` with
different queries. This demonstrates how the syntax of the query
maps to the parameter structure:

[table Params Sequences [
    [s]
    [`parms( s )`]
][
    [`"?first=John&last=Doe"`]
    [`{ { "first", "John" }, { "last", "Doe" } }`]
][
    [`"?id=42&unsorted"`]
    [`{ { "id", "42" }, { "last", no_value } }`]
][
    [`"?col=cust&row="`]
    [`{ { "col", "cust" }, { "row", "" } }`]
][
    [`"?justify=left&"`]
    [`{ { "justify", "left" }, { "", no_value } }`]
][
    [`"?"`]
    [`{ { "", no_value } }`]
][
    [`""`]
    [`{ }`]
]]

It may be surprising that an empty query string ("?")
produces a sequence with one empty param. This is by
design, otherwise the sequence would not be
distinguishable from the case where there
is no query string (last two rows of the
table above).

For complete details on containers used to represent
query strings as params please view the reference.

[endsect]
