1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_PARAM_HPP
11  
#ifndef BOOST_URL_PARAM_HPP
12  
#define BOOST_URL_PARAM_HPP
12  
#define BOOST_URL_PARAM_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/detail/optional_string.hpp>
15  
#include <boost/url/detail/optional_string.hpp>
16  
#include <boost/url/pct_string_view.hpp>
16  
#include <boost/url/pct_string_view.hpp>
17  
#include <cstddef>
17  
#include <cstddef>
18  
#include <string>
18  
#include <string>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace urls {
21  
namespace urls {
22  

22  

23  
#ifndef BOOST_URL_DOCS
23  
#ifndef BOOST_URL_DOCS
24  
struct param_pct_view;
24  
struct param_pct_view;
25  
struct param_view;
25  
struct param_view;
26  
#endif
26  
#endif
27  

27  

28  
/** The type of @ref no_value
28  
/** The type of @ref no_value
29  
*/
29  
*/
30  
struct no_value_t
30  
struct no_value_t
31  
{
31  
{
32  
};
32  
};
33  

33  

34  
/** Constant indicating no value in a param
34  
/** Constant indicating no value in a param
35  
*/
35  
*/
36  
constexpr no_value_t no_value{};
36  
constexpr no_value_t no_value{};
37  

37  

38  
//------------------------------------------------
38  
//------------------------------------------------
39  

39  

40  
/** A query parameter
40  
/** A query parameter
41  

41  

42  
    Objects of this type represent a single key
42  
    Objects of this type represent a single key
43  
    and value pair in a query string where a key
43  
    and value pair in a query string where a key
44  
    is always present and may be empty, while the
44  
    is always present and may be empty, while the
45  
    presence of a value is indicated by
45  
    presence of a value is indicated by
46  
    @ref has_value equal to true.
46  
    @ref has_value equal to true.
47  
    An empty value is distinct from no value.
47  
    An empty value is distinct from no value.
48  

48  

49  
    Depending on where the object was obtained,
49  
    Depending on where the object was obtained,
50  
    the strings may or may not contain percent
50  
    the strings may or may not contain percent
51  
    escapes.
51  
    escapes.
52  

52  

53  
    For most usages, key comparisons are
53  
    For most usages, key comparisons are
54  
    case-sensitive and duplicate keys in
54  
    case-sensitive and duplicate keys in
55  
    a query are possible. However, it is
55  
    a query are possible. However, it is
56  
    the authority that has final control
56  
    the authority that has final control
57  
    over how the query is interpreted.
57  
    over how the query is interpreted.
58  

58  

59  
    @par BNF
59  
    @par BNF
60  
    @code
60  
    @code
61  
    query-params    = query-param *( "&" query-param )
61  
    query-params    = query-param *( "&" query-param )
62  
    query-param     = key [ "=" value ]
62  
    query-param     = key [ "=" value ]
63  
    key             = *qpchar
63  
    key             = *qpchar
64  
    value           = *( qpchar / "=" )
64  
    value           = *( qpchar / "=" )
65  
    @endcode
65  
    @endcode
66  

66  

67  
    @par Specification
67  
    @par Specification
68  
    @li <a href="https://en.wikipedia.org/wiki/Query_string"
68  
    @li <a href="https://en.wikipedia.org/wiki/Query_string"
69  
        >Query string (Wikipedia)</a>
69  
        >Query string (Wikipedia)</a>
70  

70  

71  
    @see
71  
    @see
72  
        @ref param_view,
72  
        @ref param_view,
73  
        @ref param_pct_view.
73  
        @ref param_pct_view.
74  
*/
74  
*/
75  
struct param
75  
struct param
76  
{
76  
{
77  
    /** The key
77  
    /** The key
78  

78  

79  
        For most usages, key comparisons are
79  
        For most usages, key comparisons are
80  
        case-sensitive and duplicate keys in
80  
        case-sensitive and duplicate keys in
81  
        a query are possible. However, it is
81  
        a query are possible. However, it is
82  
        the authority that has final control
82  
        the authority that has final control
83  
        over how the query is interpreted.
83  
        over how the query is interpreted.
84  
    */
84  
    */
85  
    std::string key;
85  
    std::string key;
86  

86  

87  
    /** The value
87  
    /** The value
88  

88  

89  
        The presence of a value is indicated by
89  
        The presence of a value is indicated by
90  
        @ref has_value equal to true.
90  
        @ref has_value equal to true.
91  
        An empty value is distinct from no value.
91  
        An empty value is distinct from no value.
92  
    */
92  
    */
93  
    std::string value;
93  
    std::string value;
94  

94  

95  
    /** True if a value is present
95  
    /** True if a value is present
96  

96  

97  
        The presence of a value is indicated by
97  
        The presence of a value is indicated by
98  
        `has_value == true`.
98  
        `has_value == true`.
99  
        An empty value is distinct from no value.
99  
        An empty value is distinct from no value.
100  
    */
100  
    */
101  
    bool has_value = false;
101  
    bool has_value = false;
102  

102  

103  
    /** Constructor
103  
    /** Constructor
104  

104  

105  
        Default constructed query parameters
105  
        Default constructed query parameters
106  
        have an empty key and no value.
106  
        have an empty key and no value.
107  

107  

108  
        @par Example
108  
        @par Example
109  
        @code
109  
        @code
110  
        param qp;
110  
        param qp;
111  
        @endcode
111  
        @endcode
112  

112  

113  
        @par Postconditions
113  
        @par Postconditions
114  
        @code
114  
        @code
115  
        this->key == "" && this->value == "" && this->has_value == false
115  
        this->key == "" && this->value == "" && this->has_value == false
116  
        @endcode
116  
        @endcode
117  

117  

118  
        @par Complexity
118  
        @par Complexity
119  
        Constant.
119  
        Constant.
120  

120  

121  
        @par Exception Safety
121  
        @par Exception Safety
122  
        Throws nothing.
122  
        Throws nothing.
123  
    */
123  
    */
124  
    param() = default;
124  
    param() = default;
125  

125  

126  
    /** Constructor
126  
    /** Constructor
127  

127  

128  
        Upon construction, this acquires
128  
        Upon construction, this acquires
129  
        ownership of the members of other
129  
        ownership of the members of other
130  
        via move construction. The moved
130  
        via move construction. The moved
131  
        from object is as if default
131  
        from object is as if default
132  
        constructed.
132  
        constructed.
133  

133  

134  
        @par Complexity
134  
        @par Complexity
135  
        Constant.
135  
        Constant.
136  

136  

137  
        @par Exception Safety
137  
        @par Exception Safety
138  
        Throws nothing.
138  
        Throws nothing.
139  

139  

140  
        @param other The object to construct from.
140  
        @param other The object to construct from.
141  
    */
141  
    */
142  
    param(param&& other) noexcept
142  
    param(param&& other) noexcept
143  
        : key(std::move(other.key))
143  
        : key(std::move(other.key))
144  
        , value(std::move(other.value))
144  
        , value(std::move(other.value))
145  
        , has_value(other.has_value)
145  
        , has_value(other.has_value)
146  
    {
146  
    {
147  
    #ifdef BOOST_URL_COW_STRINGS
147  
    #ifdef BOOST_URL_COW_STRINGS
148  
        // for copy-on-write std::string
148  
        // for copy-on-write std::string
149  
        other.key.clear();
149  
        other.key.clear();
150  
        other.value.clear();
150  
        other.value.clear();
151  
    #endif
151  
    #endif
152  
        other.has_value = false;
152  
        other.has_value = false;
153  
    }
153  
    }
154  

154  

155  
    /** Constructor
155  
    /** Constructor
156  

156  

157  
        Upon construction, this becomes a copy
157  
        Upon construction, this becomes a copy
158  
        of `other`.
158  
        of `other`.
159  

159  

160  
        @par Postconditions
160  
        @par Postconditions
161  
        @code
161  
        @code
162  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
162  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
163  
        @endcode
163  
        @endcode
164  

164  

165  
        @par Complexity
165  
        @par Complexity
166  
        Linear in `other.key.size() + other.value.size()`.
166  
        Linear in `other.key.size() + other.value.size()`.
167  

167  

168  
        @par Exception Safety
168  
        @par Exception Safety
169  
        Calls to allocate may throw.
169  
        Calls to allocate may throw.
170  

170  

171  
        @param other The object to construct from.
171  
        @param other The object to construct from.
172  
        @return A reference to this object.
172  
        @return A reference to this object.
173  
    */
173  
    */
174  
    param(param const& other) = default;
174  
    param(param const& other) = default;
175  

175  

176  
    /** Assignment
176  
    /** Assignment
177  

177  

178  
        Upon assignment, this acquires
178  
        Upon assignment, this acquires
179  
        ownership of the members of other
179  
        ownership of the members of other
180  
        via move assignment. The moved
180  
        via move assignment. The moved
181  
        from object is as if default
181  
        from object is as if default
182  
        constructed.
182  
        constructed.
183  

183  

184  
        @par Complexity
184  
        @par Complexity
185  
        Constant.
185  
        Constant.
186  

186  

187  
        @par Exception Safety
187  
        @par Exception Safety
188  
        Throws nothing.
188  
        Throws nothing.
189  

189  

190  

190  

191  
        @param other The object to assign from.
191  
        @param other The object to assign from.
192  
        @return A reference to this object.
192  
        @return A reference to this object.
193  
    */
193  
    */
194  
    param&
194  
    param&
195  
    operator=(param&& other) noexcept
195  
    operator=(param&& other) noexcept
196  
    {
196  
    {
197  
        key = std::move(other.key);
197  
        key = std::move(other.key);
198  
        value = std::move(other.value);
198  
        value = std::move(other.value);
199  
        has_value = other.has_value;
199  
        has_value = other.has_value;
200  
    #ifdef BOOST_URL_COW_STRINGS
200  
    #ifdef BOOST_URL_COW_STRINGS
201  
        // for copy-on-write std::string
201  
        // for copy-on-write std::string
202  
        other.key.clear();
202  
        other.key.clear();
203  
        other.value.clear();
203  
        other.value.clear();
204  
    #endif
204  
    #endif
205  
        other.has_value = false;
205  
        other.has_value = false;
206  
        return *this;
206  
        return *this;
207  
    }
207  
    }
208  

208  

209  
    /** Assignment
209  
    /** Assignment
210  

210  

211  
        Upon assignment, this becomes a copy
211  
        Upon assignment, this becomes a copy
212  
        of `other`.
212  
        of `other`.
213  

213  

214  
        @par Postconditions
214  
        @par Postconditions
215  
        @code
215  
        @code
216  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
216  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
217  
        @endcode
217  
        @endcode
218  

218  

219  
        @par Complexity
219  
        @par Complexity
220  
        Linear in `other.key.size() + other.value.size()`.
220  
        Linear in `other.key.size() + other.value.size()`.
221  

221  

222  
        @par Exception Safety
222  
        @par Exception Safety
223  
        Calls to allocate may throw.
223  
        Calls to allocate may throw.
224  

224  

225  

225  

226  
        @param other The object to assign from.
226  
        @param other The object to assign from.
227  
        @return A reference to this object.
227  
        @return A reference to this object.
228  
    */
228  
    */
229  
    param& operator=(
229  
    param& operator=(
230  
        param const& other) = default;
230  
        param const& other) = default;
231  

231  

232  
    //--------------------------------------------
232  
    //--------------------------------------------
233  

233  

234  
    /** Constructor
234  
    /** Constructor
235  

235  

236  
        This constructs a parameter with a key
236  
        This constructs a parameter with a key
237  
        and value.
237  
        and value.
238  

238  

239  
        No validation is performed on the strings.
239  
        No validation is performed on the strings.
240  
        Ownership of the key and value is acquired
240  
        Ownership of the key and value is acquired
241  
        by making copies.
241  
        by making copies.
242  

242  

243  
        @par Example
243  
        @par Example
244  
        @code
244  
        @code
245  
        param qp( "key", "value" );
245  
        param qp( "key", "value" );
246  
        @endcode
246  
        @endcode
247  

247  

248  
        @code
248  
        @code
249  
        param qp( "key", optional<core::string_view>("value") );
249  
        param qp( "key", optional<core::string_view>("value") );
250  
        @endcode
250  
        @endcode
251  

251  

252  
        @code
252  
        @code
253  
        param qp( "key", boost::none );
253  
        param qp( "key", boost::none );
254  
        @endcode
254  
        @endcode
255  

255  

256  
        @code
256  
        @code
257  
        param qp( "key", nullptr );
257  
        param qp( "key", nullptr );
258  
        @endcode
258  
        @endcode
259  

259  

260  
        @code
260  
        @code
261  
        param qp( "key", no_value );
261  
        param qp( "key", no_value );
262  
        @endcode
262  
        @endcode
263  

263  

264  
        @par Postconditions
264  
        @par Postconditions
265  
        @code
265  
        @code
266  
        this->key == key && this->value == value && this->has_value == true
266  
        this->key == key && this->value == value && this->has_value == true
267  
        @endcode
267  
        @endcode
268  

268  

269  
        @par Complexity
269  
        @par Complexity
270  
        Linear in `key.size() + value.size()`.
270  
        Linear in `key.size() + value.size()`.
271  

271  

272  
        @par Exception Safety
272  
        @par Exception Safety
273  
        Calls to allocate may throw.
273  
        Calls to allocate may throw.
274  

274  

275  
        @tparam OptionalString An optional string
275  
        @tparam OptionalString An optional string
276  
        type, such as `core::string_view`,
276  
        type, such as `core::string_view`,
277  
        `std::nullptr`, @ref no_value_t, or
277  
        `std::nullptr`, @ref no_value_t, or
278  
        `optional<core::string_view>`.
278  
        `optional<core::string_view>`.
279  

279  

280  
        @param key The key to set.
280  
        @param key The key to set.
281  
        @param value The value to set.
281  
        @param value The value to set.
282  
    */
282  
    */
283  
    template <class OptionalString>
283  
    template <class OptionalString>
284  
    param(
284  
    param(
285  
        core::string_view key,
285  
        core::string_view key,
286  
        OptionalString const& value)
286  
        OptionalString const& value)
287  
        : param(key, detail::get_optional_string(value))
287  
        : param(key, detail::get_optional_string(value))
288  
    {
288  
    {
289  
    }
289  
    }
290  

290  

291  
    /** Assignment
291  
    /** Assignment
292  

292  

293  
        The members of `other` are copied,
293  
        The members of `other` are copied,
294  
        re-using already existing string capacity.
294  
        re-using already existing string capacity.
295  

295  

296  
        @par Postconditions
296  
        @par Postconditions
297  
        @code
297  
        @code
298  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
298  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
299  
        @endcode
299  
        @endcode
300  

300  

301  
        @par Complexity
301  
        @par Complexity
302  
        Linear in `other.key.size() + other.value.size()`.
302  
        Linear in `other.key.size() + other.value.size()`.
303  

303  

304  
        @par Exception Safety
304  
        @par Exception Safety
305  
        Calls to allocate may throw.
305  
        Calls to allocate may throw.
306  

306  

307  
        @param other The parameter to copy.
307  
        @param other The parameter to copy.
308  
        @return A reference to this object.
308  
        @return A reference to this object.
309  
    */
309  
    */
310  
    param&
310  
    param&
311  
    operator=(param_view const& other);
311  
    operator=(param_view const& other);
312  

312  

313  
    /** Assignment
313  
    /** Assignment
314  

314  

315  
        The members of `other` are copied,
315  
        The members of `other` are copied,
316  
        re-using already existing string capacity.
316  
        re-using already existing string capacity.
317  

317  

318  
        @par Postconditions
318  
        @par Postconditions
319  
        @code
319  
        @code
320  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
320  
        this->key == other.key && this->value == other.value && this->has_value == other.has_value
321  
        @endcode
321  
        @endcode
322  

322  

323  
        @par Complexity
323  
        @par Complexity
324  
        Linear in `other.key.size() + other.value.size()`.
324  
        Linear in `other.key.size() + other.value.size()`.
325  

325  

326  
        @par Exception Safety
326  
        @par Exception Safety
327  
        Calls to allocate may throw.
327  
        Calls to allocate may throw.
328  

328  

329  
        @param other The parameter to copy.
329  
        @param other The parameter to copy.
330  
        @return A reference to this object.
330  
        @return A reference to this object.
331  
    */
331  
    */
332  
    param&
332  
    param&
333  
    operator=(param_pct_view const& other);
333  
    operator=(param_pct_view const& other);
334  

334  

335  
    /** Arrow support
335  
    /** Arrow support
336  

336  

337  
        This operator returns the address of the
337  
        This operator returns the address of the
338  
        object so that it can be used in pointer
338  
        object so that it can be used in pointer
339  
        contexts.
339  
        contexts.
340  

340  

341  
        @return A pointer to the object.
341  
        @return A pointer to the object.
342  

342  

343  
     */
343  
     */
344  
    param const*
344  
    param const*
345  
    operator->() const noexcept
345  
    operator->() const noexcept
346  
    {
346  
    {
347  
        return this;
347  
        return this;
348  
    }
348  
    }
349  

349  

350  
    /** Aggregate construction
350  
    /** Aggregate construction
351  

351  

352  
        @param key The key to set.
352  
        @param key The key to set.
353  
        @param value The value to set.
353  
        @param value The value to set.
354  
        @param has_value True if a value is present.
354  
        @param has_value True if a value is present.
355  
     */
355  
     */
356  
    param(
356  
    param(
357  
        core::string_view key,
357  
        core::string_view key,
358  
        core::string_view value,
358  
        core::string_view value,
359  
        bool has_value) noexcept
359  
        bool has_value) noexcept
360  
        : key(key)
360  
        : key(key)
361  
        , value(has_value
361  
        , value(has_value
362  
            ? value
362  
            ? value
363  
            : core::string_view())
363  
            : core::string_view())
364  
        , has_value(has_value)
364  
        , has_value(has_value)
365  
    {
365  
    {
366  
    }
366  
    }
367  

367  

368  
private:
368  
private:
369  
    param(
369  
    param(
370  
        core::string_view key,
370  
        core::string_view key,
371  
        detail::optional_string const& value)
371  
        detail::optional_string const& value)
372  
        : param(key, value.s, value.b)
372  
        : param(key, value.s, value.b)
373  
    {
373  
    {
374  
    }
374  
    }
375  
};
375  
};
376  

376  

377  
//------------------------------------------------
377  
//------------------------------------------------
378  

378  

379  
/** A view of a query parameter
379  
/** A view of a query parameter
380  

380  

381  
    Objects of this type represent a single key
381  
    Objects of this type represent a single key
382  
    and value pair in a query string where a key
382  
    and value pair in a query string where a key
383  
    is always present and may be empty, while the
383  
    is always present and may be empty, while the
384  
    presence of a value is indicated by
384  
    presence of a value is indicated by
385  
    @ref has_value equal to true.
385  
    @ref has_value equal to true.
386  
    An empty value is distinct from no value.
386  
    An empty value is distinct from no value.
387  

387  

388  
    Depending on where the object was obtained,
388  
    Depending on where the object was obtained,
389  
    the strings may or may not contain percent
389  
    the strings may or may not contain percent
390  
    escapes. Some functions and objects might
390  
    escapes. Some functions and objects might
391  
    expect encoded strings in this view, while
391  
    expect encoded strings in this view, while
392  
    others expect decoded strings. The caller
392  
    others expect decoded strings. The caller
393  
    should be aware of the context in which
393  
    should be aware of the context in which
394  
    the object will be used.
394  
    the object will be used.
395  

395  

396  
    For most usages, key comparisons are
396  
    For most usages, key comparisons are
397  
    case-sensitive and duplicate keys in
397  
    case-sensitive and duplicate keys in
398  
    a query are possible. However, it is
398  
    a query are possible. However, it is
399  
    the authority that has final control
399  
    the authority that has final control
400  
    over how the query is interpreted.
400  
    over how the query is interpreted.
401  

401  

402  
    <br>
402  
    <br>
403  

403  

404  
    Keys and values in this object reference
404  
    Keys and values in this object reference
405  
    external character buffers.
405  
    external character buffers.
406  
    Ownership of the buffers is not transferred;
406  
    Ownership of the buffers is not transferred;
407  
    the caller is responsible for ensuring that
407  
    the caller is responsible for ensuring that
408  
    the assigned buffers remain valid until
408  
    the assigned buffers remain valid until
409  
    they are no longer referenced.
409  
    they are no longer referenced.
410  

410  

411  
    @par BNF
411  
    @par BNF
412  
    @code
412  
    @code
413  
    query-params    = query-param *( "&" query-param )
413  
    query-params    = query-param *( "&" query-param )
414  
    query-param     = key [ "=" value ]
414  
    query-param     = key [ "=" value ]
415  
    key             = *qpchar
415  
    key             = *qpchar
416  
    value           = *( qpchar / "=" )
416  
    value           = *( qpchar / "=" )
417  
    @endcode
417  
    @endcode
418  

418  

419  
    @par Specification
419  
    @par Specification
420  
    @li <a href="https://en.wikipedia.org/wiki/Query_string"
420  
    @li <a href="https://en.wikipedia.org/wiki/Query_string"
421  
        >Query string (Wikipedia)</a>
421  
        >Query string (Wikipedia)</a>
422  

422  

423  
    @see
423  
    @see
424  
        @ref param,
424  
        @ref param,
425  
        @ref param_pct_view.
425  
        @ref param_pct_view.
426  
*/
426  
*/
427  
struct param_view
427  
struct param_view
428  
{
428  
{
429  
    /** The key
429  
    /** The key
430  

430  

431  
        For most usages, key comparisons are
431  
        For most usages, key comparisons are
432  
        case-sensitive and duplicate keys in
432  
        case-sensitive and duplicate keys in
433  
        a query are possible. However, it is
433  
        a query are possible. However, it is
434  
        the authority that has final control
434  
        the authority that has final control
435  
        over how the query is interpreted.
435  
        over how the query is interpreted.
436  
    */
436  
    */
437  
    core::string_view key;
437  
    core::string_view key;
438  

438  

439  
    /** The value
439  
    /** The value
440  

440  

441  
        The presence of a value is indicated by
441  
        The presence of a value is indicated by
442  
        @ref has_value equal to true.
442  
        @ref has_value equal to true.
443  
        An empty value is distinct from no value.
443  
        An empty value is distinct from no value.
444  
    */
444  
    */
445  
    core::string_view value;
445  
    core::string_view value;
446  

446  

447  
    /** True if a value is present
447  
    /** True if a value is present
448  

448  

449  
        The presence of a value is indicated by
449  
        The presence of a value is indicated by
450  
        `has_value == true`.
450  
        `has_value == true`.
451  
        An empty value is distinct from no value.
451  
        An empty value is distinct from no value.
452  
    */
452  
    */
453  
    bool has_value = false;
453  
    bool has_value = false;
454  

454  

455  
    //--------------------------------------------
455  
    //--------------------------------------------
456  

456  

457  
    /** Constructor
457  
    /** Constructor
458  

458  

459  
        Default constructed query parameters
459  
        Default constructed query parameters
460  
        have an empty key and no value.
460  
        have an empty key and no value.
461  

461  

462  
        @par Example
462  
        @par Example
463  
        @code
463  
        @code
464  
        param_view qp;
464  
        param_view qp;
465  
        @endcode
465  
        @endcode
466  

466  

467  
        @par Postconditions
467  
        @par Postconditions
468  
        @code
468  
        @code
469  
        this->key == "" && this->value == "" && this->has_value == false
469  
        this->key == "" && this->value == "" && this->has_value == false
470  
        @endcode
470  
        @endcode
471  

471  

472  
        @par Complexity
472  
        @par Complexity
473  
        Constant.
473  
        Constant.
474  

474  

475  
        @par Exception Safety
475  
        @par Exception Safety
476  
        Throws nothing.
476  
        Throws nothing.
477  
    */
477  
    */
478  
    param_view() = default;
478  
    param_view() = default;
479  

479  

480  
    /** Constructor
480  
    /** Constructor
481  

481  

482  
        This constructs a parameter with a key
482  
        This constructs a parameter with a key
483  
        and value.
483  
        and value.
484  
        No validation is performed on the strings.
484  
        No validation is performed on the strings.
485  
        The new key and value reference
485  
        The new key and value reference
486  
        the same corresponding underlying
486  
        the same corresponding underlying
487  
        character buffers.
487  
        character buffers.
488  
        Ownership of the buffers is not transferred;
488  
        Ownership of the buffers is not transferred;
489  
        the caller is responsible for ensuring that
489  
        the caller is responsible for ensuring that
490  
        the assigned buffers remain valid until
490  
        the assigned buffers remain valid until
491  
        they are no longer referenced.
491  
        they are no longer referenced.
492  

492  

493  
        @par Example
493  
        @par Example
494  
        @code
494  
        @code
495  
        param_view qp( "key", "value" );
495  
        param_view qp( "key", "value" );
496  
        @endcode
496  
        @endcode
497  

497  

498  
        @par Postconditions
498  
        @par Postconditions
499  
        @code
499  
        @code
500  
        this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
500  
        this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
501  
        @endcode
501  
        @endcode
502  

502  

503  
        @par Complexity
503  
        @par Complexity
504  
        Constant.
504  
        Constant.
505  

505  

506  
        @par Exception Safety
506  
        @par Exception Safety
507  
        Throws nothing.
507  
        Throws nothing.
508  

508  

509  
        @tparam OptionalString An optional string
509  
        @tparam OptionalString An optional string
510  
        type, such as `core::string_view`,
510  
        type, such as `core::string_view`,
511  
        `std::nullptr`, @ref no_value_t, or
511  
        `std::nullptr`, @ref no_value_t, or
512  
        `optional<core::string_view>`.
512  
        `optional<core::string_view>`.
513  

513  

514  
        @param key The key to set.
514  
        @param key The key to set.
515  
        @param value The value to set.
515  
        @param value The value to set.
516  
    */
516  
    */
517  
    template <class OptionalString>
517  
    template <class OptionalString>
518  
    param_view(
518  
    param_view(
519  
        core::string_view key,
519  
        core::string_view key,
520  
        OptionalString const& value) noexcept
520  
        OptionalString const& value) noexcept
521  
        : param_view(key, detail::get_optional_string(value))
521  
        : param_view(key, detail::get_optional_string(value))
522  
    {
522  
    {
523  
    }
523  
    }
524  

524  

525  
    /** Constructor
525  
    /** Constructor
526  

526  

527  
        This function constructs a param
527  
        This function constructs a param
528  
        which references the character buffers
528  
        which references the character buffers
529  
        representing the key and value in another
529  
        representing the key and value in another
530  
        container.
530  
        container.
531  
        Ownership of the buffers is not transferred;
531  
        Ownership of the buffers is not transferred;
532  
        the caller is responsible for ensuring that
532  
        the caller is responsible for ensuring that
533  
        the assigned buffers remain valid until
533  
        the assigned buffers remain valid until
534  
        they are no longer referenced.
534  
        they are no longer referenced.
535  

535  

536  
        @par Example
536  
        @par Example
537  
        @code
537  
        @code
538  
        param qp( "key", "value" );
538  
        param qp( "key", "value" );
539  
        param_view qpv( qp );
539  
        param_view qpv( qp );
540  
        @endcode
540  
        @endcode
541  

541  

542  
        @par Postconditions
542  
        @par Postconditions
543  
        @code
543  
        @code
544  
        this->key == key && this->value == value && this->has_value == other.has_value
544  
        this->key == key && this->value == value && this->has_value == other.has_value
545  
        @endcode
545  
        @endcode
546  

546  

547  
        @par Complexity
547  
        @par Complexity
548  
        Constant.
548  
        Constant.
549  

549  

550  
        @par Exception Safety
550  
        @par Exception Safety
551  
        Throws nothing.
551  
        Throws nothing.
552  

552  

553  
        @param other The param to reference
553  
        @param other The param to reference
554  
    */
554  
    */
555  
    param_view(
555  
    param_view(
556  
        param const& other) noexcept
556  
        param const& other) noexcept
557  
        : param_view(
557  
        : param_view(
558  
            other.key,
558  
            other.key,
559  
            other.value,
559  
            other.value,
560  
            other.has_value)
560  
            other.has_value)
561  
    {
561  
    {
562  
    }
562  
    }
563  

563  

564  
    /** Conversion
564  
    /** Conversion
565  

565  

566  
        This function performs a conversion from
566  
        This function performs a conversion from
567  
        a reference-like query parameter to one
567  
        a reference-like query parameter to one
568  
        retaining ownership of the strings by
568  
        retaining ownership of the strings by
569  
        making a copy.
569  
        making a copy.
570  
        No validation is performed on the strings.
570  
        No validation is performed on the strings.
571  

571  

572  
        @par Complexity
572  
        @par Complexity
573  
        Linear in `this->key.size() + this->value.size()`.
573  
        Linear in `this->key.size() + this->value.size()`.
574  

574  

575  
        @par Exception Safety
575  
        @par Exception Safety
576  
        Calls to allocate may throw.
576  
        Calls to allocate may throw.
577  

577  

578  
        @return A new query parameter.
578  
        @return A new query parameter.
579  
    */
579  
    */
580  
    explicit
580  
    explicit
581  
    operator
581  
    operator
582  
    param()
582  
    param()
583  
    {
583  
    {
584  
        return { key, value, has_value };
584  
        return { key, value, has_value };
585  
    }
585  
    }
586  

586  

587  
    /** Arrow support
587  
    /** Arrow support
588  

588  

589  
        This operator returns the address of the
589  
        This operator returns the address of the
590  
        object so that it can be used in pointer
590  
        object so that it can be used in pointer
591  
        contexts.
591  
        contexts.
592  

592  

593  
        @return A pointer to the object.
593  
        @return A pointer to the object.
594  
     */
594  
     */
595  
    param_view const*
595  
    param_view const*
596  
    operator->() const noexcept
596  
    operator->() const noexcept
597  
    {
597  
    {
598  
        return this;
598  
        return this;
599  
    }
599  
    }
600  

600  

601  
#if defined(_MSC_VER)
601  
#if defined(_MSC_VER)
602  
#pragma warning(push)
602  
#pragma warning(push)
603  
#pragma warning(disable: 4458) // declaration hides class member
603  
#pragma warning(disable: 4458) // declaration hides class member
604  
#endif
604  
#endif
605  
#if defined(__clang__)
605  
#if defined(__clang__)
606  
#pragma clang diagnostic push
606  
#pragma clang diagnostic push
607  
#pragma clang diagnostic ignored "-Wshadow"
607  
#pragma clang diagnostic ignored "-Wshadow"
608  
#elif defined(__GNUC__)
608  
#elif defined(__GNUC__)
609  
#pragma GCC diagnostic push
609  
#pragma GCC diagnostic push
610  
#pragma GCC diagnostic ignored "-Wshadow"
610  
#pragma GCC diagnostic ignored "-Wshadow"
611  
#endif
611  
#endif
612  

612  

613  
    /** Aggregate construction
613  
    /** Aggregate construction
614  

614  

615  
        @param key The key to set.
615  
        @param key The key to set.
616  
        @param value The value to set.
616  
        @param value The value to set.
617  
        @param has_value True if a value is present.
617  
        @param has_value True if a value is present.
618  
     */
618  
     */
619  
    param_view(
619  
    param_view(
620  
        core::string_view key,
620  
        core::string_view key,
621  
        core::string_view value,
621  
        core::string_view value,
622  
        bool has_value) noexcept
622  
        bool has_value) noexcept
623  
        : key(key)
623  
        : key(key)
624  
        , value(has_value
624  
        , value(has_value
625  
            ? value
625  
            ? value
626  
            : core::string_view())
626  
            : core::string_view())
627  
        , has_value(has_value)
627  
        , has_value(has_value)
628  
    {
628  
    {
629  
    }
629  
    }
630  

630  

631  
#if defined(__clang__)
631  
#if defined(__clang__)
632  
#pragma clang diagnostic pop
632  
#pragma clang diagnostic pop
633  
#elif defined(__GNUC__)
633  
#elif defined(__GNUC__)
634  
#pragma GCC diagnostic pop
634  
#pragma GCC diagnostic pop
635  
#endif
635  
#endif
636  
#if defined(_MSC_VER)
636  
#if defined(_MSC_VER)
637  
#pragma warning(pop)
637  
#pragma warning(pop)
638  
#endif
638  
#endif
639  

639  

640  
private:
640  
private:
641  
    param_view(
641  
    param_view(
642  
        core::string_view key,
642  
        core::string_view key,
643  
        detail::optional_string const& value)
643  
        detail::optional_string const& value)
644  
        : param_view(key, value.s, value.b)
644  
        : param_view(key, value.s, value.b)
645  
    {
645  
    {
646  
    }
646  
    }
647  
};
647  
};
648  

648  

649  
//------------------------------------------------
649  
//------------------------------------------------
650  

650  

651  
/** A view of a percent-encoded query parameter
651  
/** A view of a percent-encoded query parameter
652  

652  

653  
    Objects of this type represent a single key
653  
    Objects of this type represent a single key
654  
    and value pair in a query string where a key
654  
    and value pair in a query string where a key
655  
    is always present and may be empty, while the
655  
    is always present and may be empty, while the
656  
    presence of a value is indicated by
656  
    presence of a value is indicated by
657  
    @ref has_value equal to true.
657  
    @ref has_value equal to true.
658  
    An empty value is distinct from no value.
658  
    An empty value is distinct from no value.
659  

659  

660  
    The strings may have percent escapes, and
660  
    The strings may have percent escapes, and
661  
    offer an additional invariant: they never
661  
    offer an additional invariant: they never
662  
    contain an invalid percent-encoding.
662  
    contain an invalid percent-encoding.
663  

663  

664  
    For most usages, key comparisons are
664  
    For most usages, key comparisons are
665  
    case-sensitive and duplicate keys in
665  
    case-sensitive and duplicate keys in
666  
    a query are possible. However, it is
666  
    a query are possible. However, it is
667  
    the authority that has final control
667  
    the authority that has final control
668  
    over how the query is interpreted.
668  
    over how the query is interpreted.
669  

669  

670  
    <br>
670  
    <br>
671  

671  

672  
    Keys and values in this object reference
672  
    Keys and values in this object reference
673  
    external character buffers.
673  
    external character buffers.
674  
    Ownership of the buffers is not transferred;
674  
    Ownership of the buffers is not transferred;
675  
    the caller is responsible for ensuring that
675  
    the caller is responsible for ensuring that
676  
    the assigned buffers remain valid until
676  
    the assigned buffers remain valid until
677  
    they are no longer referenced.
677  
    they are no longer referenced.
678  

678  

679  
    @par BNF
679  
    @par BNF
680  
    @code
680  
    @code
681  
    query-params    = query-param *( "&" query-param )
681  
    query-params    = query-param *( "&" query-param )
682  
    query-param     = key [ "=" value ]
682  
    query-param     = key [ "=" value ]
683  
    key             = *qpchar
683  
    key             = *qpchar
684  
    value           = *( qpchar / "=" )
684  
    value           = *( qpchar / "=" )
685  
    @endcode
685  
    @endcode
686  

686  

687  
    @par Specification
687  
    @par Specification
688  
    @li <a href="https://en.wikipedia.org/wiki/Query_string"
688  
    @li <a href="https://en.wikipedia.org/wiki/Query_string"
689  
        >Query string (Wikipedia)</a>
689  
        >Query string (Wikipedia)</a>
690  

690  

691  
    @see
691  
    @see
692  
        @ref param,
692  
        @ref param,
693  
        @ref param_view.
693  
        @ref param_view.
694  
*/
694  
*/
695  
struct param_pct_view
695  
struct param_pct_view
696  
{
696  
{
697  
    /** The key
697  
    /** The key
698  

698  

699  
        For most usages, key comparisons are
699  
        For most usages, key comparisons are
700  
        case-sensitive and duplicate keys in
700  
        case-sensitive and duplicate keys in
701  
        a query are possible. However, it is
701  
        a query are possible. However, it is
702  
        the authority that has final control
702  
        the authority that has final control
703  
        over how the query is interpreted.
703  
        over how the query is interpreted.
704  
    */
704  
    */
705  
    pct_string_view key;
705  
    pct_string_view key;
706  

706  

707  
    /** The value
707  
    /** The value
708  

708  

709  
        The presence of a value is indicated by
709  
        The presence of a value is indicated by
710  
        @ref has_value equal to true.
710  
        @ref has_value equal to true.
711  
        An empty value is distinct from no value.
711  
        An empty value is distinct from no value.
712  
    */
712  
    */
713  
    pct_string_view value;
713  
    pct_string_view value;
714  

714  

715  
    /** True if a value is present
715  
    /** True if a value is present
716  

716  

717  
        The presence of a value is indicated by
717  
        The presence of a value is indicated by
718  
        `has_value == true`.
718  
        `has_value == true`.
719  
        An empty value is distinct from no value.
719  
        An empty value is distinct from no value.
720  
    */
720  
    */
721  
    bool has_value = false;
721  
    bool has_value = false;
722  

722  

723  
    //--------------------------------------------
723  
    //--------------------------------------------
724  

724  

725  
    /** Constructor
725  
    /** Constructor
726  

726  

727  
        Default constructed query parameters
727  
        Default constructed query parameters
728  
        have an empty key and no value.
728  
        have an empty key and no value.
729  

729  

730  
        @par Example
730  
        @par Example
731  
        @code
731  
        @code
732  
        param_pct_view qp;
732  
        param_pct_view qp;
733  
        @endcode
733  
        @endcode
734  

734  

735  
        @par Postconditions
735  
        @par Postconditions
736  
        @code
736  
        @code
737  
        this->key == "" && this->value == "" && this->has_value == false
737  
        this->key == "" && this->value == "" && this->has_value == false
738  
        @endcode
738  
        @endcode
739  

739  

740  
        @par Complexity
740  
        @par Complexity
741  
        Constant.
741  
        Constant.
742  

742  

743  
        @par Exception Safety
743  
        @par Exception Safety
744  
        Throws nothing.
744  
        Throws nothing.
745  
    */
745  
    */
746  
    param_pct_view() = default;
746  
    param_pct_view() = default;
747  

747  

748  
    /** Constructor
748  
    /** Constructor
749  

749  

750  
        This constructs a parameter with a key
750  
        This constructs a parameter with a key
751  
        and value, which may both contain percent
751  
        and value, which may both contain percent
752  
        escapes.
752  
        escapes.
753  
        The new key and value reference
753  
        The new key and value reference
754  
        the same corresponding underlying
754  
        the same corresponding underlying
755  
        character buffers.
755  
        character buffers.
756  
        Ownership of the buffers is not transferred;
756  
        Ownership of the buffers is not transferred;
757  
        the caller is responsible for ensuring that
757  
        the caller is responsible for ensuring that
758  
        the assigned buffers remain valid until
758  
        the assigned buffers remain valid until
759  
        they are no longer referenced.
759  
        they are no longer referenced.
760  

760  

761  
        @par Example
761  
        @par Example
762  
        @code
762  
        @code
763  
        param_pct_view qp( "key", "value" );
763  
        param_pct_view qp( "key", "value" );
764  
        @endcode
764  
        @endcode
765  

765  

766  
        @par Postconditions
766  
        @par Postconditions
767  
        @code
767  
        @code
768  
        this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
768  
        this->key.data() == key.data() && this->value.data() == value.data() && this->has_value == true
769  
        @endcode
769  
        @endcode
770  

770  

771  
        @par Complexity
771  
        @par Complexity
772  
        Linear in `key.size() + value.size()`.
772  
        Linear in `key.size() + value.size()`.
773  

773  

774  
        @par Exception Safety
774  
        @par Exception Safety
775  
        Exceptions thrown on invalid input.
775  
        Exceptions thrown on invalid input.
776  

776  

777  
        @throw system_error
777  
        @throw system_error
778  
        `key` or `value` contains an invalid percent-encoding.
778  
        `key` or `value` contains an invalid percent-encoding.
779  

779  

780  
        @param key The key to set.
780  
        @param key The key to set.
781  
        @param value The value to set.
781  
        @param value The value to set.
782  
    */
782  
    */
783  
    param_pct_view(
783  
    param_pct_view(
784  
        pct_string_view key,
784  
        pct_string_view key,
785  
        pct_string_view value) noexcept
785  
        pct_string_view value) noexcept
786  
        : key(key)
786  
        : key(key)
787  
        , value(value)
787  
        , value(value)
788  
        , has_value(true)
788  
        , has_value(true)
789  
    {
789  
    {
790  
    }
790  
    }
791  

791  

792  
    /** Constructor
792  
    /** Constructor
793  

793  

794  
        This constructs a parameter with a key
794  
        This constructs a parameter with a key
795  
        and optional value, which may both
795  
        and optional value, which may both
796  
        contain percent escapes.
796  
        contain percent escapes.
797  

797  

798  
        The new key and value reference
798  
        The new key and value reference
799  
        the same corresponding underlying
799  
        the same corresponding underlying
800  
        character buffers.
800  
        character buffers.
801  

801  

802  
        Ownership of the buffers is not transferred;
802  
        Ownership of the buffers is not transferred;
803  
        the caller is responsible for ensuring that
803  
        the caller is responsible for ensuring that
804  
        the assigned buffers remain valid until
804  
        the assigned buffers remain valid until
805  
        they are no longer referenced.
805  
        they are no longer referenced.
806  

806  

807  
        @par Example
807  
        @par Example
808  
        @code
808  
        @code
809  
        param_pct_view qp( "key", optional<core::string_view>("value") );
809  
        param_pct_view qp( "key", optional<core::string_view>("value") );
810  
        @endcode
810  
        @endcode
811  

811  

812  
        @par Postconditions
812  
        @par Postconditions
813  
        @code
813  
        @code
814  
        this->key.data() == key.data() && this->value->data() == value->data() && this->has_value == true
814  
        this->key.data() == key.data() && this->value->data() == value->data() && this->has_value == true
815  
        @endcode
815  
        @endcode
816  

816  

817  
        @par Complexity
817  
        @par Complexity
818  
        Linear in `key.size() + value->size()`.
818  
        Linear in `key.size() + value->size()`.
819  

819  

820  
        @par Exception Safety
820  
        @par Exception Safety
821  
        Exceptions thrown on invalid input.
821  
        Exceptions thrown on invalid input.
822  

822  

823  
        @throw system_error
823  
        @throw system_error
824  
        `key` or `value` contains an invalid percent-encoding.
824  
        `key` or `value` contains an invalid percent-encoding.
825  

825  

826  
        @tparam OptionalString An optional
826  
        @tparam OptionalString An optional
827  
        `core::string_view` type, such as
827  
        `core::string_view` type, such as
828  
        `boost::optional<core::string_view>` or
828  
        `boost::optional<core::string_view>` or
829  
        `std::optional<core::string_view>`.
829  
        `std::optional<core::string_view>`.
830  

830  

831  
        @param key The key to set.
831  
        @param key The key to set.
832  
        @param value The optional value to set.
832  
        @param value The optional value to set.
833  
        @return A param object
833  
        @return A param object
834  
    */
834  
    */
835  
    template <class OptionalString>
835  
    template <class OptionalString>
836  
    param_pct_view(
836  
    param_pct_view(
837  
        pct_string_view key,
837  
        pct_string_view key,
838  
        OptionalString const& value)
838  
        OptionalString const& value)
839  
        : param_pct_view(key, detail::get_optional_string(value))
839  
        : param_pct_view(key, detail::get_optional_string(value))
840  
    {
840  
    {
841  
    }
841  
    }
842  

842  

843  
    /** Construction
843  
    /** Construction
844  

844  

845  
        This converts a param which may
845  
        This converts a param which may
846  
        contain unvalidated percent-escapes into
846  
        contain unvalidated percent-escapes into
847  
        a param whose key and value are
847  
        a param whose key and value are
848  
        guaranteed to contain strings with no
848  
        guaranteed to contain strings with no
849  
        invalid percent-escapes, otherwise
849  
        invalid percent-escapes, otherwise
850  
        an exception is thrown.
850  
        an exception is thrown.
851  

851  

852  
        The new key and value reference
852  
        The new key and value reference
853  
        the same corresponding underlying
853  
        the same corresponding underlying
854  
        character buffers.
854  
        character buffers.
855  
        Ownership of the buffers is not transferred;
855  
        Ownership of the buffers is not transferred;
856  
        the caller is responsible for ensuring that
856  
        the caller is responsible for ensuring that
857  
        the assigned buffers remain valid until
857  
        the assigned buffers remain valid until
858  
        they are no longer referenced.
858  
        they are no longer referenced.
859  

859  

860  
        @par Example
860  
        @par Example
861  
        @code
861  
        @code
862  
        param_pct_view qp( param_view( "key", "value" ) );
862  
        param_pct_view qp( param_view( "key", "value" ) );
863  
        @endcode
863  
        @endcode
864  

864  

865  
        @par Complexity
865  
        @par Complexity
866  
        Linear in `key.size() + value.size()`.
866  
        Linear in `key.size() + value.size()`.
867  

867  

868  
        @par Exception Safety
868  
        @par Exception Safety
869  
        Exceptions thrown on invalid input.
869  
        Exceptions thrown on invalid input.
870  

870  

871  
        @throw system_error
871  
        @throw system_error
872  
        `key` or `value` contains an invalid percent escape.
872  
        `key` or `value` contains an invalid percent escape.
873  

873  

874  
        @param p The param to construct from.
874  
        @param p The param to construct from.
875  
    */
875  
    */
876  
    explicit
876  
    explicit
877  
    param_pct_view(
877  
    param_pct_view(
878  
        param_view const& p)
878  
        param_view const& p)
879  
        : key(p.key)
879  
        : key(p.key)
880  
        , value(p.has_value
880  
        , value(p.has_value
881  
            ? pct_string_view(p.value)
881  
            ? pct_string_view(p.value)
882  
            : pct_string_view())
882  
            : pct_string_view())
883  
        , has_value(p.has_value)
883  
        , has_value(p.has_value)
884  
    {
884  
    {
885  
    }
885  
    }
886  

886  

887  
    /** Conversion
887  
    /** Conversion
888  

888  

889  
        This function performs a conversion from
889  
        This function performs a conversion from
890  
        a reference-like query parameter to one
890  
        a reference-like query parameter to one
891  
        retaining ownership of the strings by
891  
        retaining ownership of the strings by
892  
        making a copy.
892  
        making a copy.
893  

893  

894  
        @par Complexity
894  
        @par Complexity
895  
        Linear in `this->key.size() + this->value.size()`.
895  
        Linear in `this->key.size() + this->value.size()`.
896  

896  

897  
        @par Exception Safety
897  
        @par Exception Safety
898  
        Calls to allocate may throw.
898  
        Calls to allocate may throw.
899  

899  

900  
        @return A param object
900  
        @return A param object
901  
    */
901  
    */
902  
    explicit
902  
    explicit
903  
    operator
903  
    operator
904  
    param() const
904  
    param() const
905  
    {
905  
    {
906  
        return param(
906  
        return param(
907  
            static_cast<std::string>(key),
907  
            static_cast<std::string>(key),
908  
            static_cast<std::string>(value),
908  
            static_cast<std::string>(value),
909  
            has_value);
909  
            has_value);
910  
    }
910  
    }
911  

911  

912  
    /** Conversion to param_view
912  
    /** Conversion to param_view
913  

913  

914  
        This function performs a conversion from
914  
        This function performs a conversion from
915  
        a pct_string_view query parameter to one
915  
        a pct_string_view query parameter to one
916  
        using a simple string_view.
916  
        using a simple string_view.
917  

917  

918  
        @par Exception Safety
918  
        @par Exception Safety
919  
        Calls to allocate may throw.
919  
        Calls to allocate may throw.
920  

920  

921  
        @return A param_view object
921  
        @return A param_view object
922  
    */
922  
    */
923  
    operator
923  
    operator
924  
    param_view() const noexcept
924  
    param_view() const noexcept
925  
    {
925  
    {
926  
        return param_view(
926  
        return param_view(
927  
            key, value, has_value);
927  
            key, value, has_value);
928  
    }
928  
    }
929  

929  

930  
    /** Arrow support
930  
    /** Arrow support
931  

931  

932  
        This operator returns the address of the
932  
        This operator returns the address of the
933  
        object so that it can be used in pointer
933  
        object so that it can be used in pointer
934  
        contexts.
934  
        contexts.
935  

935  

936  
        @return A pointer to this object
936  
        @return A pointer to this object
937  
     */
937  
     */
938  
    param_pct_view const*
938  
    param_pct_view const*
939  
    operator->() const noexcept
939  
    operator->() const noexcept
940  
    {
940  
    {
941  
        return this;
941  
        return this;
942  
    }
942  
    }
943  

943  

944  
    /** Aggregate construction
944  
    /** Aggregate construction
945  

945  

946  
        @param key The key
946  
        @param key The key
947  
        @param value The value
947  
        @param value The value
948  
        @param has_value True if a value is present
948  
        @param has_value True if a value is present
949  
     */
949  
     */
950  
    param_pct_view(
950  
    param_pct_view(
951  
        pct_string_view key,
951  
        pct_string_view key,
952  
        pct_string_view value,
952  
        pct_string_view value,
953  
        bool has_value) noexcept
953  
        bool has_value) noexcept
954  
        : key(key)
954  
        : key(key)
955  
        , value(has_value
955  
        , value(has_value
956  
            ? value
956  
            ? value
957  
            : pct_string_view())
957  
            : pct_string_view())
958  
        , has_value(has_value)
958  
        , has_value(has_value)
959  
    {
959  
    {
960  
    }
960  
    }
961  

961  

962  
private:
962  
private:
963  
    param_pct_view(
963  
    param_pct_view(
964  
        pct_string_view key,
964  
        pct_string_view key,
965  
        detail::optional_string const& value)
965  
        detail::optional_string const& value)
966  
        : param_pct_view(key, value.s, value.b)
966  
        : param_pct_view(key, value.s, value.b)
967  
    {
967  
    {
968  
    }
968  
    }
969  
};
969  
};
970  

970  

971  
//------------------------------------------------
971  
//------------------------------------------------
972  

972  

973  
inline
973  
inline
974  
param&
974  
param&
975  
param::
975  
param::
976  
operator=(
976  
operator=(
977  
    param_view const& other)
977  
    param_view const& other)
978  
{
978  
{
979  
    // VFALCO operator= assignment
979  
    // VFALCO operator= assignment
980  
    // causes a loss of original capacity:
980  
    // causes a loss of original capacity:
981  
    // https://godbolt.org/z/nYef8445K
981  
    // https://godbolt.org/z/nYef8445K
982  
    //
982  
    //
983  
    // key = other.key;
983  
    // key = other.key;
984  
    // value = other.value;
984  
    // value = other.value;
985  

985  

986  
    // preserve capacity
986  
    // preserve capacity
987  
    key.assign(
987  
    key.assign(
988  
        other.key.data(),
988  
        other.key.data(),
989  
        other.key.size());
989  
        other.key.size());
990  
    value.assign(
990  
    value.assign(
991  
        other.value.data(),
991  
        other.value.data(),
992  
        other.value.size());
992  
        other.value.size());
993  
    has_value = other.has_value;
993  
    has_value = other.has_value;
994  
    return *this;
994  
    return *this;
995  
}
995  
}
996  

996  

997  
inline
997  
inline
998  
param&
998  
param&
999  
param::
999  
param::
1000  
operator=(
1000  
operator=(
1001  
    param_pct_view const& other)
1001  
    param_pct_view const& other)
1002  
{
1002  
{
1003  
    // preserve capacity
1003  
    // preserve capacity
1004  
    key.assign(
1004  
    key.assign(
1005  
        other.key.data(),
1005  
        other.key.data(),
1006  
        other.key.size());
1006  
        other.key.size());
1007  
    value.assign(
1007  
    value.assign(
1008  
        other.value.data(),
1008  
        other.value.data(),
1009  
        other.value.size());
1009  
        other.value.size());
1010  
    has_value = other.has_value;
1010  
    has_value = other.has_value;
1011  
    return *this;
1011  
    return *this;
1012  
}
1012  
}
1013  

1013  

1014  
} // urls
1014  
} // urls
1015  
} // boost
1015  
} // boost
1016  

1016  

1017  
#endif
1017  
#endif