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_SEGMENTS_ENCODED_REF_HPP
11  
#ifndef BOOST_URL_SEGMENTS_ENCODED_REF_HPP
12  
#define BOOST_URL_SEGMENTS_ENCODED_REF_HPP
12  
#define BOOST_URL_SEGMENTS_ENCODED_REF_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/segments_encoded_base.hpp>
15  
#include <boost/url/segments_encoded_base.hpp>
16  
#include <initializer_list>
16  
#include <initializer_list>
17  
#include <iterator>
17  
#include <iterator>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace urls {
20  
namespace urls {
21  

21  

22  
#ifndef BOOST_URL_DOCS
22  
#ifndef BOOST_URL_DOCS
23  
class url_base;
23  
class url_base;
24  
class segments_encoded_view;
24  
class segments_encoded_view;
25  
#endif
25  
#endif
26  

26  

27  
/** Mutable encoded path segment proxy
27  
/** Mutable encoded path segment proxy
28  

28  

29  
    Exposes the percent-encoded segments of a
29  
    Exposes the percent-encoded segments of a
30  
    @ref url_base as a bidirectional range that
30  
    @ref url_base as a bidirectional range that
31  
    can modify the underlying URL. The proxy uses
31  
    can modify the underlying URL. The proxy uses
32  
    the URL’s storage directly, so the url must
32  
    the URL’s storage directly, so the url must
33  
    outlive any references.
33  
    outlive any references.
34  

34  

35  
    @par Example
35  
    @par Example
36  
    @code
36  
    @code
37  
    url u( "/path/to/file.txt" );
37  
    url u( "/path/to/file.txt" );
38  

38  

39  
    segments_encoded_ref ps = u.encoded_segments();
39  
    segments_encoded_ref ps = u.encoded_segments();
40  
    @endcode
40  
    @endcode
41  

41  

42  
    The strings returned when iterators are
42  
    The strings returned when iterators are
43  
    dereferenced have type @ref pct_string_view
43  
    dereferenced have type @ref pct_string_view
44  
    and may contain percent-escapes.
44  
    and may contain percent-escapes.
45  

45  

46  
    Reserved characters in inputs are
46  
    Reserved characters in inputs are
47  
    automatically escaped.
47  
    automatically escaped.
48  
    Escapes in inputs are preserved.
48  
    Escapes in inputs are preserved.
49  

49  

50  
    Exceptions are thrown on invalid inputs.
50  
    Exceptions are thrown on invalid inputs.
51  

51  

52  
    @par Iterator Invalidation
52  
    @par Iterator Invalidation
53  
    Changes to the underlying character buffer
53  
    Changes to the underlying character buffer
54  
    can invalidate iterators which reference it.
54  
    can invalidate iterators which reference it.
55  
    Modifications made through the container
55  
    Modifications made through the container
56  
    invalidate some or all iterators:
56  
    invalidate some or all iterators:
57  
    <br>
57  
    <br>
58  

58  

59  
    @li @ref push_back : Only `end()`.
59  
    @li @ref push_back : Only `end()`.
60  

60  

61  
    @li @ref assign, @ref clear,
61  
    @li @ref assign, @ref clear,
62  
        @ref operator= : All elements.
62  
        @ref operator= : All elements.
63  

63  

64  
    @li @ref erase : Erased elements and all
64  
    @li @ref erase : Erased elements and all
65  
        elements after (including `end()`).
65  
        elements after (including `end()`).
66  

66  

67  
    @li @ref insert : All elements at or after
67  
    @li @ref insert : All elements at or after
68  
        the insertion point (including `end()`).
68  
        the insertion point (including `end()`).
69  

69  

70  
    @li @ref replace : Modified
70  
    @li @ref replace : Modified
71  
        elements and all elements
71  
        elements and all elements
72  
        after (including `end()`).
72  
        after (including `end()`).
73  

73  

74  
    @see
74  
    @see
75  
        @ref segments_encoded_view,
75  
        @ref segments_encoded_view,
76  
        @ref segments_view,
76  
        @ref segments_view,
77  
        @ref segments_ref.
77  
        @ref segments_ref.
78  
*/
78  
*/
79  
class segments_encoded_ref
79  
class segments_encoded_ref
80  
    : public segments_encoded_base
80  
    : public segments_encoded_base
81  
{
81  
{
82  
    friend class url_base;
82  
    friend class url_base;
83  

83  

84  
    url_base* u_ = nullptr;
84  
    url_base* u_ = nullptr;
85  

85  

86  
    segments_encoded_ref(
86  
    segments_encoded_ref(
87  
        url_base& u) noexcept;
87  
        url_base& u) noexcept;
88  

88  

89  
public:
89  
public:
90  
    //--------------------------------------------
90  
    //--------------------------------------------
91  
    //
91  
    //
92  
    // Special Members
92  
    // Special Members
93  
    //
93  
    //
94  
    //--------------------------------------------
94  
    //--------------------------------------------
95  

95  

96  
    /** Constructor
96  
    /** Constructor
97  

97  

98  
        After construction, both views
98  
        After construction, both views
99  
        reference the same url. Ownership is not
99  
        reference the same url. Ownership is not
100  
        transferred; the caller is responsible
100  
        transferred; the caller is responsible
101  
        for ensuring the lifetime of the url
101  
        for ensuring the lifetime of the url
102  
        extends until it is no longer
102  
        extends until it is no longer
103  
        referenced.
103  
        referenced.
104  

104  

105  
        @par Postconditions
105  
        @par Postconditions
106  
        @code
106  
        @code
107  
        &this->url() == &other.url();
107  
        &this->url() == &other.url();
108  
        @endcode
108  
        @endcode
109  

109  

110  
        @par Complexity
110  
        @par Complexity
111  
        Constant.
111  
        Constant.
112  

112  

113  
        @par Exception Safety
113  
        @par Exception Safety
114  
        Throws nothing.
114  
        Throws nothing.
115  

115  

116  
        @param other The other view.
116  
        @param other The other view.
117  
    */
117  
    */
118  
    segments_encoded_ref(
118  
    segments_encoded_ref(
119  
        segments_encoded_ref const& other) = default;
119  
        segments_encoded_ref const& other) = default;
120  

120  

121  
    /** Assignment
121  
    /** Assignment
122  

122  

123  
        The existing contents are replaced
123  
        The existing contents are replaced
124  
        by a copy of the other segments.
124  
        by a copy of the other segments.
125  

125  

126  
        <br>
126  
        <br>
127  
        All iterators are invalidated.
127  
        All iterators are invalidated.
128  

128  

129  
        @note
129  
        @note
130  
        None of the character buffers referenced
130  
        None of the character buffers referenced
131  
        by `other` may overlap the buffer of the
131  
        by `other` may overlap the buffer of the
132  
        underlying url, or else the behavior
132  
        underlying url, or else the behavior
133  
        is undefined.
133  
        is undefined.
134  

134  

135  
        @par Effects
135  
        @par Effects
136  
        @code
136  
        @code
137  
        this->assign( other.begin(), other.end() );
137  
        this->assign( other.begin(), other.end() );
138  
        @endcode
138  
        @endcode
139  

139  

140  
        @par Complexity
140  
        @par Complexity
141  
        Linear in `other.buffer().size()`.
141  
        Linear in `other.buffer().size()`.
142  

142  

143  
        @par Exception Safety
143  
        @par Exception Safety
144  
        Strong guarantee.
144  
        Strong guarantee.
145  
        Calls to allocate may throw.
145  
        Calls to allocate may throw.
146  

146  

147  
        @param other The segments to assign.
147  
        @param other The segments to assign.
148  
        @return A reference to this object.
148  
        @return A reference to this object.
149  
    */
149  
    */
150  
    BOOST_URL_DECL
150  
    BOOST_URL_DECL
151  
    segments_encoded_ref&
151  
    segments_encoded_ref&
152  
    operator=(segments_encoded_ref const& other);
152  
    operator=(segments_encoded_ref const& other);
153  

153  

154  
    /// @copydoc operator=(segments_encoded_ref const&)
154  
    /// @copydoc operator=(segments_encoded_ref const&)
155  
    BOOST_URL_DECL
155  
    BOOST_URL_DECL
156  
    segments_encoded_ref&
156  
    segments_encoded_ref&
157  
    operator=(segments_encoded_view const& other);
157  
    operator=(segments_encoded_view const& other);
158  

158  

159  
    /** Assignment
159  
    /** Assignment
160  

160  

161  
        The existing contents are replaced
161  
        The existing contents are replaced
162  
        by a copy of the contents of the
162  
        by a copy of the contents of the
163  
        initializer list.
163  
        initializer list.
164  
        Reserved characters in the list are
164  
        Reserved characters in the list are
165  
        automatically escaped.
165  
        automatically escaped.
166  
        Escapes in the list are preserved.
166  
        Escapes in the list are preserved.
167  

167  

168  
        <br>
168  
        <br>
169  
        All iterators are invalidated.
169  
        All iterators are invalidated.
170  

170  

171  
        @par Example
171  
        @par Example
172  
        @code
172  
        @code
173  
        url u;
173  
        url u;
174  

174  

175  
        u.encoded_segments() = {"path", "to", "file.txt"};
175  
        u.encoded_segments() = {"path", "to", "file.txt"};
176  
        @endcode
176  
        @endcode
177  

177  

178  
        @par Preconditions
178  
        @par Preconditions
179  
        None of the character buffers referenced
179  
        None of the character buffers referenced
180  
        by the list may overlap the character buffer
180  
        by the list may overlap the character buffer
181  
        of the underlying url, or else the behavior
181  
        of the underlying url, or else the behavior
182  
        is undefined.
182  
        is undefined.
183  

183  

184  
        @par Effects
184  
        @par Effects
185  
        @code
185  
        @code
186  
        this->assign( init.begin(), init.end() );
186  
        this->assign( init.begin(), init.end() );
187  
        @endcode
187  
        @endcode
188  

188  

189  
        @par Complexity
189  
        @par Complexity
190  
        Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
190  
        Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
191  

191  

192  
        @par Exception Safety
192  
        @par Exception Safety
193  
        Strong guarantee.
193  
        Strong guarantee.
194  
        Calls to allocate may throw.
194  
        Calls to allocate may throw.
195  
        Exceptions thrown on invalid input.
195  
        Exceptions thrown on invalid input.
196  

196  

197  
        @throw system_error
197  
        @throw system_error
198  
        The list contains an invalid percent-encoding.
198  
        The list contains an invalid percent-encoding.
199  

199  

200  
        @param init The list of segments to assign.
200  
        @param init The list of segments to assign.
201  
        @return A reference to this.
201  
        @return A reference to this.
202  
    */
202  
    */
203  
    BOOST_URL_DECL
203  
    BOOST_URL_DECL
204  
    segments_encoded_ref&
204  
    segments_encoded_ref&
205  
    operator=(std::initializer_list<
205  
    operator=(std::initializer_list<
206  
        pct_string_view> init);
206  
        pct_string_view> init);
207  

207  

208  
    /** Conversion
208  
    /** Conversion
209  

209  

210  
        @see
210  
        @see
211  
            @ref segments_encoded_view.
211  
            @ref segments_encoded_view.
212  

212  

213  
        @return A view of the segments.
213  
        @return A view of the segments.
214  
    */
214  
    */
215  
    BOOST_URL_DECL
215  
    BOOST_URL_DECL
216  
    operator
216  
    operator
217  
    segments_encoded_view() const noexcept;
217  
    segments_encoded_view() const noexcept;
218  

218  

219  
    //--------------------------------------------
219  
    //--------------------------------------------
220  
    //
220  
    //
221  
    // Observers
221  
    // Observers
222  
    //
222  
    //
223  
    //--------------------------------------------
223  
    //--------------------------------------------
224  

224  

225  
    /** Return the referenced url
225  
    /** Return the referenced url
226  

226  

227  
        This function returns the url referenced
227  
        This function returns the url referenced
228  
        by the view.
228  
        by the view.
229  

229  

230  
        @par Example
230  
        @par Example
231  
        @code
231  
        @code
232  
        url u( "/path/to/file.txt" );
232  
        url u( "/path/to/file.txt" );
233  

233  

234  
        assert( &u.encoded_segments().url() == &u );
234  
        assert( &u.encoded_segments().url() == &u );
235  
        @endcode
235  
        @endcode
236  

236  

237  
        @par Exception Safety
237  
        @par Exception Safety
238  
        Throws nothing.
238  
        Throws nothing.
239  

239  

240  
        @return A reference to the url.
240  
        @return A reference to the url.
241  
    */
241  
    */
242  
    url_base&
242  
    url_base&
243  
    url() const noexcept
243  
    url() const noexcept
244  
    {
244  
    {
245  
        return *u_;
245  
        return *u_;
246  
    }
246  
    }
247  

247  

248  
    //--------------------------------------------
248  
    //--------------------------------------------
249  
    //
249  
    //
250  
    // Modifiers
250  
    // Modifiers
251  
    //
251  
    //
252  
    //--------------------------------------------
252  
    //--------------------------------------------
253  

253  

254  
    /** Clear the contents of the container
254  
    /** Clear the contents of the container
255  

255  

256  
        <br>
256  
        <br>
257  
        All iterators are invalidated.
257  
        All iterators are invalidated.
258  

258  

259  
        @par Effects
259  
        @par Effects
260  
        @code
260  
        @code
261  
        this->url().set_encoded_path( "" );
261  
        this->url().set_encoded_path( "" );
262  
        @endcode
262  
        @endcode
263  

263  

264  
        @par Postconditions
264  
        @par Postconditions
265  
        @code
265  
        @code
266  
        this->empty() == true
266  
        this->empty() == true
267  
        @endcode
267  
        @endcode
268  

268  

269  
        @par Complexity
269  
        @par Complexity
270  
        Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
270  
        Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
271  

271  

272  
        @par Exception Safety
272  
        @par Exception Safety
273  
        Throws nothing.
273  
        Throws nothing.
274  
    */
274  
    */
275  
    void
275  
    void
276  
    clear() noexcept;
276  
    clear() noexcept;
277  

277  

278  
    /** Assign segments
278  
    /** Assign segments
279  

279  

280  
        The existing contents are replaced
280  
        The existing contents are replaced
281  
        by a copy of the contents of the
281  
        by a copy of the contents of the
282  
        initializer list.
282  
        initializer list.
283  
        Reserved characters in the list are
283  
        Reserved characters in the list are
284  
        automatically escaped.
284  
        automatically escaped.
285  
        Escapes in the list are preserved.
285  
        Escapes in the list are preserved.
286  

286  

287  
        <br>
287  
        <br>
288  
        All iterators are invalidated.
288  
        All iterators are invalidated.
289  

289  

290  
        @note
290  
        @note
291  
        None of the character buffers referenced
291  
        None of the character buffers referenced
292  
        by the list may overlap the character
292  
        by the list may overlap the character
293  
        buffer of the underlying url, or else
293  
        buffer of the underlying url, or else
294  
        the behavior is undefined.
294  
        the behavior is undefined.
295  

295  

296  
        @par Example
296  
        @par Example
297  
        @code
297  
        @code
298  
        url u;
298  
        url u;
299  

299  

300  
        u.segments().assign( {"path", "to", "file.txt"} );
300  
        u.segments().assign( {"path", "to", "file.txt"} );
301  
        @endcode
301  
        @endcode
302  

302  

303  
        @par Complexity
303  
        @par Complexity
304  
        Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
304  
        Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
305  

305  

306  
        @par Exception Safety
306  
        @par Exception Safety
307  
        Strong guarantee.
307  
        Strong guarantee.
308  
        Calls to allocate may throw.
308  
        Calls to allocate may throw.
309  
        Exceptions thrown on invalid input.
309  
        Exceptions thrown on invalid input.
310  

310  

311  
        @throw system_error
311  
        @throw system_error
312  
        The list contains an invalid percent-encoding.
312  
        The list contains an invalid percent-encoding.
313  

313  

314  
        @param init The list of segments to assign.
314  
        @param init The list of segments to assign.
315  
    */
315  
    */
316  
    BOOST_URL_DECL
316  
    BOOST_URL_DECL
317  
    void
317  
    void
318  
    assign(std::initializer_list<
318  
    assign(std::initializer_list<
319  
        pct_string_view> init);
319  
        pct_string_view> init);
320  

320  

321  
    /** Assign segments
321  
    /** Assign segments
322  

322  

323  
        The existing contents are replaced
323  
        The existing contents are replaced
324  
        by a copy of the contents of the range.
324  
        by a copy of the contents of the range.
325  
        Reserved characters in the range are
325  
        Reserved characters in the range are
326  
        automatically escaped.
326  
        automatically escaped.
327  
        Escapes in the range are preserved.
327  
        Escapes in the range are preserved.
328  

328  

329  
        <br>
329  
        <br>
330  
        All iterators are invalidated.
330  
        All iterators are invalidated.
331  

331  

332  
        @note
332  
        @note
333  
        None of the character buffers referenced
333  
        None of the character buffers referenced
334  
        by the range may overlap the character
334  
        by the range may overlap the character
335  
        buffer of the underlying url, or else
335  
        buffer of the underlying url, or else
336  
        the behavior is undefined.
336  
        the behavior is undefined.
337  

337  

338  
        @par Mandates
338  
        @par Mandates
339  
        @code
339  
        @code
340  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
340  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
341  
        @endcode
341  
        @endcode
342  

342  

343  
        @par Complexity
343  
        @par Complexity
344  
        Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
344  
        Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
345  

345  

346  
        @par Exception Safety
346  
        @par Exception Safety
347  
        Strong guarantee.
347  
        Strong guarantee.
348  
        Calls to allocate may throw.
348  
        Calls to allocate may throw.
349  
        Exceptions thrown on invalid input.
349  
        Exceptions thrown on invalid input.
350  

350  

351  
        @throw system_error
351  
        @throw system_error
352  
        The range contains an invalid percent-encoding.
352  
        The range contains an invalid percent-encoding.
353  

353  

354  
        @param first The first element in the range.
354  
        @param first The first element in the range.
355  
        @param last One past the last element in the range.
355  
        @param last One past the last element in the range.
356  
    */
356  
    */
357  
    template<class FwdIt>
357  
    template<class FwdIt>
358  
    void
358  
    void
359  
    assign(FwdIt first, FwdIt last);
359  
    assign(FwdIt first, FwdIt last);
360  

360  

361  
    //--------------------------------------------
361  
    //--------------------------------------------
362  

362  

363  
    /** Insert segments
363  
    /** Insert segments
364  

364  

365  
        This function inserts a segment
365  
        This function inserts a segment
366  
        before the specified position.
366  
        before the specified position.
367  
        Reserved characters in the segment are
367  
        Reserved characters in the segment are
368  
        automatically escaped.
368  
        automatically escaped.
369  
        Escapes in the segment are preserved.
369  
        Escapes in the segment are preserved.
370  

370  

371  
        <br>
371  
        <br>
372  
        All iterators that are equal to
372  
        All iterators that are equal to
373  
        `before` or come after are invalidated.
373  
        `before` or come after are invalidated.
374  

374  

375  
        @par Complexity
375  
        @par Complexity
376  
        Linear in `s.size() + this->url().encoded_resource().size()`.
376  
        Linear in `s.size() + this->url().encoded_resource().size()`.
377  

377  

378  
        @par Exception Safety
378  
        @par Exception Safety
379  
        Strong guarantee.
379  
        Strong guarantee.
380  
        Calls to allocate may throw.
380  
        Calls to allocate may throw.
381  
        Exceptions thrown on invalid input.
381  
        Exceptions thrown on invalid input.
382  

382  

383  
        @throw system_error
383  
        @throw system_error
384  
        The segment contains an invalid percent-encoding.
384  
        The segment contains an invalid percent-encoding.
385  

385  

386  
        @return An iterator to the inserted
386  
        @return An iterator to the inserted
387  
        segment.
387  
        segment.
388  

388  

389  
        @param before An iterator before which
389  
        @param before An iterator before which
390  
        the segment is inserted. This may
390  
        the segment is inserted. This may
391  
        be equal to `end()`.
391  
        be equal to `end()`.
392  

392  

393  
        @param s The segment to insert.
393  
        @param s The segment to insert.
394  
    */
394  
    */
395  
    BOOST_URL_DECL
395  
    BOOST_URL_DECL
396  
    iterator
396  
    iterator
397  
    insert(
397  
    insert(
398  
        iterator before,
398  
        iterator before,
399  
        pct_string_view s);
399  
        pct_string_view s);
400  

400  

401  
    /** Insert segments
401  
    /** Insert segments
402  

402  

403  
        This function inserts the segments
403  
        This function inserts the segments
404  
        in an initializer list before the
404  
        in an initializer list before the
405  
        specified position.
405  
        specified position.
406  
        Reserved characters in the list are
406  
        Reserved characters in the list are
407  
        automatically escaped.
407  
        automatically escaped.
408  
        Escapes in the list are preserved.
408  
        Escapes in the list are preserved.
409  

409  

410  
        <br>
410  
        <br>
411  
        All iterators that are equal to
411  
        All iterators that are equal to
412  
        `before` or come after are invalidated.
412  
        `before` or come after are invalidated.
413  

413  

414  
        @note
414  
        @note
415  
        None of the character buffers referenced
415  
        None of the character buffers referenced
416  
        by the list may overlap the character
416  
        by the list may overlap the character
417  
        buffer of the underlying url, or else
417  
        buffer of the underlying url, or else
418  
        the behavior is undefined.
418  
        the behavior is undefined.
419  

419  

420  
        @par Example
420  
        @par Example
421  
        @code
421  
        @code
422  
        url u( "/file.txt" );
422  
        url u( "/file.txt" );
423  

423  

424  
        u.encoded_segments().insert( u.encoded_segments().begin(), { "path", "to" } );
424  
        u.encoded_segments().insert( u.encoded_segments().begin(), { "path", "to" } );
425  
        @endcode
425  
        @endcode
426  

426  

427  
        @par Complexity
427  
        @par Complexity
428  
        Linear in `init.size() + this->url().encoded_resource().size()`.
428  
        Linear in `init.size() + this->url().encoded_resource().size()`.
429  

429  

430  
        @par Exception Safety
430  
        @par Exception Safety
431  
        Strong guarantee.
431  
        Strong guarantee.
432  
        Calls to allocate may throw.
432  
        Calls to allocate may throw.
433  
        Exceptions thrown on invalid input.
433  
        Exceptions thrown on invalid input.
434  

434  

435  
        @throw system_error
435  
        @throw system_error
436  
        The list contains an invalid percent-encoding.
436  
        The list contains an invalid percent-encoding.
437  

437  

438  
        @return An iterator to the first
438  
        @return An iterator to the first
439  
        element inserted, or `before` if
439  
        element inserted, or `before` if
440  
        `init.size() == 0`.
440  
        `init.size() == 0`.
441  

441  

442  
        @param before An iterator before which
442  
        @param before An iterator before which
443  
        the list is inserted. This may
443  
        the list is inserted. This may
444  
        be equal to `end()`.
444  
        be equal to `end()`.
445  

445  

446  
        @param init The list of segments to insert.
446  
        @param init The list of segments to insert.
447  
    */
447  
    */
448  
    BOOST_URL_DECL
448  
    BOOST_URL_DECL
449  
    iterator
449  
    iterator
450  
    insert(
450  
    insert(
451  
        iterator before,
451  
        iterator before,
452  
        std::initializer_list<
452  
        std::initializer_list<
453  
            pct_string_view> init);
453  
            pct_string_view> init);
454  

454  

455  
    /** Insert segments
455  
    /** Insert segments
456  

456  

457  
        This function inserts the segments in
457  
        This function inserts the segments in
458  
        a range before the specified position.
458  
        a range before the specified position.
459  
        Reserved characters in the range are
459  
        Reserved characters in the range are
460  
        automatically escaped.
460  
        automatically escaped.
461  
        Escapes in the range are preserved.
461  
        Escapes in the range are preserved.
462  

462  

463  
        <br>
463  
        <br>
464  
        All iterators that are equal to
464  
        All iterators that are equal to
465  
        `before` or come after are invalidated.
465  
        `before` or come after are invalidated.
466  

466  

467  
        @note
467  
        @note
468  
        None of the character buffers referenced
468  
        None of the character buffers referenced
469  
        by the range may overlap the character
469  
        by the range may overlap the character
470  
        buffer of the underlying url, or else
470  
        buffer of the underlying url, or else
471  
        the behavior is undefined.
471  
        the behavior is undefined.
472  

472  

473  
        @par Mandates
473  
        @par Mandates
474  
        @code
474  
        @code
475  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
475  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, pct_string_view >::value == true
476  
        @endcode
476  
        @endcode
477  

477  

478  
        @par Complexity
478  
        @par Complexity
479  
        Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
479  
        Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
480  

480  

481  
        @par Exception Safety
481  
        @par Exception Safety
482  
        Strong guarantee.
482  
        Strong guarantee.
483  
        Calls to allocate may throw.
483  
        Calls to allocate may throw.
484  
        Exceptions thrown on invalid input.
484  
        Exceptions thrown on invalid input.
485  

485  

486  
        @throw system_error
486  
        @throw system_error
487  
        The range contains an invalid percent-encoding.
487  
        The range contains an invalid percent-encoding.
488  

488  

489  
        @return An iterator to the first
489  
        @return An iterator to the first
490  
        segment inserted, or `before` if
490  
        segment inserted, or `before` if
491  
        `init.empty()`.
491  
        `init.empty()`.
492  

492  

493  
        @param before An iterator before which
493  
        @param before An iterator before which
494  
        the range is inserted. This may
494  
        the range is inserted. This may
495  
        be equal to `end()`.
495  
        be equal to `end()`.
496  

496  

497  
        @param first The first element in the range to insert.
497  
        @param first The first element in the range to insert.
498  
        @param last One past the last element in the range to insert.
498  
        @param last One past the last element in the range to insert.
499  
    */
499  
    */
500  
    template<class FwdIt>
500  
    template<class FwdIt>
501  
    iterator
501  
    iterator
502  
    insert(
502  
    insert(
503  
        iterator before,
503  
        iterator before,
504  
        FwdIt first,
504  
        FwdIt first,
505  
        FwdIt last);
505  
        FwdIt last);
506  

506  

507  
    //--------------------------------------------
507  
    //--------------------------------------------
508  

508  

509  
    /** Erase segments
509  
    /** Erase segments
510  

510  

511  
        This function removes a segment.
511  
        This function removes a segment.
512  

512  

513  
        <br>
513  
        <br>
514  
        All iterators that are equal to
514  
        All iterators that are equal to
515  
        `pos` or come after are invalidated.
515  
        `pos` or come after are invalidated.
516  

516  

517  
        @par Complexity
517  
        @par Complexity
518  
        Linear in `this->url().encoded_resource().size()`.
518  
        Linear in `this->url().encoded_resource().size()`.
519  

519  

520  
        @par Exception Safety
520  
        @par Exception Safety
521  
        Throws nothing.
521  
        Throws nothing.
522  

522  

523  
        @return An iterator to one past
523  
        @return An iterator to one past
524  
        the removed segment.
524  
        the removed segment.
525  

525  

526  
        @param pos An iterator to the element.
526  
        @param pos An iterator to the element.
527  
    */
527  
    */
528  
    iterator
528  
    iterator
529  
    erase(
529  
    erase(
530  
        iterator pos) noexcept;
530  
        iterator pos) noexcept;
531  

531  

532  
    /** Erase segments
532  
    /** Erase segments
533  

533  

534  
        This function removes a range of segments
534  
        This function removes a range of segments
535  
        from the container.
535  
        from the container.
536  

536  

537  
        <br>
537  
        <br>
538  
        All iterators that are equal to
538  
        All iterators that are equal to
539  
        `first` or come after are invalidated.
539  
        `first` or come after are invalidated.
540  

540  

541  
        @par Complexity
541  
        @par Complexity
542  
        Linear in `this->url().encoded_resource().size()`.
542  
        Linear in `this->url().encoded_resource().size()`.
543  

543  

544  
        @par Exception Safety
544  
        @par Exception Safety
545  
        Throws nothing.
545  
        Throws nothing.
546  

546  

547  
        @param first The first element in the range to erase.
547  
        @param first The first element in the range to erase.
548  
        @param last One past the last element in the range to erase.
548  
        @param last One past the last element in the range to erase.
549  
        @return An iterator to one past the removed range.
549  
        @return An iterator to one past the removed range.
550  
    */
550  
    */
551  
    BOOST_URL_DECL
551  
    BOOST_URL_DECL
552  
    iterator
552  
    iterator
553  
    erase(
553  
    erase(
554  
        iterator first,
554  
        iterator first,
555  
        iterator last) noexcept;
555  
        iterator last) noexcept;
556  

556  

557  
    //--------------------------------------------
557  
    //--------------------------------------------
558  

558  

559  
    /** Replace segments
559  
    /** Replace segments
560  

560  

561  
        This function replaces the segment at
561  
        This function replaces the segment at
562  
        the specified position.
562  
        the specified position.
563  
        Reserved characters in the string are
563  
        Reserved characters in the string are
564  
        automatically escaped.
564  
        automatically escaped.
565  
        Escapes in the string are preserved.
565  
        Escapes in the string are preserved.
566  

566  

567  
        <br>
567  
        <br>
568  
        All iterators that are equal to
568  
        All iterators that are equal to
569  
        `pos` or come after are invalidated.
569  
        `pos` or come after are invalidated.
570  

570  

571  
        @par Complexity
571  
        @par Complexity
572  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
572  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
573  

573  

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

577  

578  
        @return An iterator to the replaced segment.
578  
        @return An iterator to the replaced segment.
579  

579  

580  
        @param pos An iterator to the segment.
580  
        @param pos An iterator to the segment.
581  

581  

582  
        @param s The string to assign.
582  
        @param s The string to assign.
583  
    */
583  
    */
584  
    BOOST_URL_DECL
584  
    BOOST_URL_DECL
585  
    iterator
585  
    iterator
586  
    replace(
586  
    replace(
587  
        iterator pos,
587  
        iterator pos,
588  
        pct_string_view s);
588  
        pct_string_view s);
589  

589  

590  
    /** Replace segments
590  
    /** Replace segments
591  

591  

592  
        This function replaces a range of
592  
        This function replaces a range of
593  
        segments with one segment.
593  
        segments with one segment.
594  
        Reserved characters in the string are
594  
        Reserved characters in the string are
595  
        automatically escaped.
595  
        automatically escaped.
596  
        Escapes in the string are preserved.
596  
        Escapes in the string are preserved.
597  

597  

598  
        <br>
598  
        <br>
599  
        All iterators that are equal to
599  
        All iterators that are equal to
600  
        `from` or come after are invalidated.
600  
        `from` or come after are invalidated.
601  

601  

602  
        @par Complexity
602  
        @par Complexity
603  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
603  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
604  

604  

605  
        @par Exception Safety
605  
        @par Exception Safety
606  
        Strong guarantee.
606  
        Strong guarantee.
607  
        Calls to allocate may throw.
607  
        Calls to allocate may throw.
608  
        Exceptions thrown on invalid input.
608  
        Exceptions thrown on invalid input.
609  

609  

610  
        @throw system_error
610  
        @throw system_error
611  
        The string contains an invalid percent-encoding.
611  
        The string contains an invalid percent-encoding.
612  

612  

613  
        @return An iterator to the new segment.
613  
        @return An iterator to the new segment.
614  

614  

615  
        @param from The first element in the range of segments to replace.
615  
        @param from The first element in the range of segments to replace.
616  
        @param to One past the last element in the range of segments to replace.
616  
        @param to One past the last element in the range of segments to replace.
617  

617  

618  
        @param s The string to assign.
618  
        @param s The string to assign.
619  
    */
619  
    */
620  
    BOOST_URL_DECL
620  
    BOOST_URL_DECL
621  
    iterator
621  
    iterator
622  
    replace(
622  
    replace(
623  
        iterator from,
623  
        iterator from,
624  
        iterator to,
624  
        iterator to,
625  
        pct_string_view s);
625  
        pct_string_view s);
626  

626  

627  
    /** Replace segments
627  
    /** Replace segments
628  

628  

629  
        This function replaces a range of
629  
        This function replaces a range of
630  
        segments with a list of segments in
630  
        segments with a list of segments in
631  
        an initializer list.
631  
        an initializer list.
632  
        Reserved characters in the list are
632  
        Reserved characters in the list are
633  
        automatically escaped.
633  
        automatically escaped.
634  
        Escapes in the list are preserved.
634  
        Escapes in the list are preserved.
635  

635  

636  
        <br>
636  
        <br>
637  
        All iterators that are equal to
637  
        All iterators that are equal to
638  
        `from` or come after are invalidated.
638  
        `from` or come after are invalidated.
639  

639  

640  
        @par Preconditions
640  
        @par Preconditions
641  
        None of the character buffers referenced
641  
        None of the character buffers referenced
642  
        by the list may overlap the character
642  
        by the list may overlap the character
643  
        buffer of the underlying url, or else
643  
        buffer of the underlying url, or else
644  
        the behavior is undefined.
644  
        the behavior is undefined.
645  

645  

646  
        @par Complexity
646  
        @par Complexity
647  
        Linear in `init.size() + this->url().encoded_resouce().size()`.
647  
        Linear in `init.size() + this->url().encoded_resouce().size()`.
648  

648  

649  
        @par Exception Safety
649  
        @par Exception Safety
650  
        Strong guarantee.
650  
        Strong guarantee.
651  
        Calls to allocate may throw.
651  
        Calls to allocate may throw.
652  
        Exceptions thrown on invalid input.
652  
        Exceptions thrown on invalid input.
653  

653  

654  
        @throw system_error
654  
        @throw system_error
655  
        The list contains an invalid percent-encoding.
655  
        The list contains an invalid percent-encoding.
656  

656  

657  
        @return An iterator to the first
657  
        @return An iterator to the first
658  
        segment inserted, or one past `to` if
658  
        segment inserted, or one past `to` if
659  
        `init.size() == 0`.
659  
        `init.size() == 0`.
660  

660  

661  
        @param from The first element in the range of segments to replace.
661  
        @param from The first element in the range of segments to replace.
662  
        @param to One past the last element in the range of segments to replace.
662  
        @param to One past the last element in the range of segments to replace.
663  

663  

664  
        @param init The list of segments to assign.
664  
        @param init The list of segments to assign.
665  
    */
665  
    */
666  
    BOOST_URL_DECL
666  
    BOOST_URL_DECL
667  
    iterator
667  
    iterator
668  
    replace(
668  
    replace(
669  
        iterator from,
669  
        iterator from,
670  
        iterator to,
670  
        iterator to,
671  
        std::initializer_list<
671  
        std::initializer_list<
672  
            pct_string_view> init);
672  
            pct_string_view> init);
673  

673  

674  
    /** Replace segments
674  
    /** Replace segments
675  

675  

676  
        This function replaces a range of
676  
        This function replaces a range of
677  
        segments with annother range of segments.
677  
        segments with annother range of segments.
678  
        Reserved characters in the new range are
678  
        Reserved characters in the new range are
679  
        automatically escaped.
679  
        automatically escaped.
680  
        Escapes in the new range are preserved.
680  
        Escapes in the new range are preserved.
681  

681  

682  
        <br>
682  
        <br>
683  
        All iterators that are equal to
683  
        All iterators that are equal to
684  
        `from` or come after are invalidated.
684  
        `from` or come after are invalidated.
685  

685  

686  
        @par Preconditions
686  
        @par Preconditions
687  
        None of the character buffers referenced
687  
        None of the character buffers referenced
688  
        by the new range may overlap the character
688  
        by the new range may overlap the character
689  
        buffer of the underlying url, or else
689  
        buffer of the underlying url, or else
690  
        the behavior is undefined.
690  
        the behavior is undefined.
691  

691  

692  
        @par Complexity
692  
        @par Complexity
693  
        Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
693  
        Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
694  

694  

695  
        @par Exception Safety
695  
        @par Exception Safety
696  
        Strong guarantee.
696  
        Strong guarantee.
697  
        Calls to allocate may throw.
697  
        Calls to allocate may throw.
698  
        Exceptions thrown on invalid input.
698  
        Exceptions thrown on invalid input.
699  

699  

700  
        @throw system_error
700  
        @throw system_error
701  
        The range contains an invalid percent-encoding.
701  
        The range contains an invalid percent-encoding.
702  

702  

703  
        @return An iterator to the first
703  
        @return An iterator to the first
704  
        segment inserted, or one past `to` if
704  
        segment inserted, or one past `to` if
705  
        `init.size() == 0`.
705  
        `init.size() == 0`.
706  

706  

707  
        @param from The first element in the range of segments to replace.
707  
        @param from The first element in the range of segments to replace.
708  
        @param to One past the last element in the range of segments to replace.
708  
        @param to One past the last element in the range of segments to replace.
709  
        @param first The first element in the new range of segments.
709  
        @param first The first element in the new range of segments.
710  
        @param last One past the last element in the new range of segments.
710  
        @param last One past the last element in the new range of segments.
711  
    */
711  
    */
712  
    template<class FwdIt>
712  
    template<class FwdIt>
713  
    iterator
713  
    iterator
714  
    replace(
714  
    replace(
715  
        iterator from,
715  
        iterator from,
716  
        iterator to,
716  
        iterator to,
717  
        FwdIt first,
717  
        FwdIt first,
718  
        FwdIt last);
718  
        FwdIt last);
719  

719  

720  
    //--------------------------------------------
720  
    //--------------------------------------------
721  

721  

722  
    /** Append a segment
722  
    /** Append a segment
723  

723  

724  
        This function appends a segment to
724  
        This function appends a segment to
725  
        the end of the path.
725  
        the end of the path.
726  
        Reserved characters in the string are
726  
        Reserved characters in the string are
727  
        automatically escaped.
727  
        automatically escaped.
728  
        Escapes in the string are preserved.
728  
        Escapes in the string are preserved.
729  

729  

730  
        <br>
730  
        <br>
731  
        All end iterators are invalidated.
731  
        All end iterators are invalidated.
732  

732  

733  
        @par Postconditions
733  
        @par Postconditions
734  
        @code
734  
        @code
735  
        this->back() == s
735  
        this->back() == s
736  
        @endcode
736  
        @endcode
737  

737  

738  
        @par Exception Safety
738  
        @par Exception Safety
739  
        Strong guarantee.
739  
        Strong guarantee.
740  
        Calls to allocate may throw.
740  
        Calls to allocate may throw.
741  
        Exceptions thrown on invalid input.
741  
        Exceptions thrown on invalid input.
742  

742  

743  
        @throw system_error
743  
        @throw system_error
744  
        The string contains an invalid percent-encoding.
744  
        The string contains an invalid percent-encoding.
745  

745  

746  
        @param s The segment to append.
746  
        @param s The segment to append.
747  
    */
747  
    */
748  
    void
748  
    void
749  
    push_back(
749  
    push_back(
750  
        pct_string_view s);
750  
        pct_string_view s);
751  

751  

752  
    /** Remove the last segment
752  
    /** Remove the last segment
753  

753  

754  
        This function removes the last segment
754  
        This function removes the last segment
755  
        from the container.
755  
        from the container.
756  

756  

757  
        <br>
757  
        <br>
758  
        Iterators to the last segment as well
758  
        Iterators to the last segment as well
759  
        as all end iterators are invalidated.
759  
        as all end iterators are invalidated.
760  

760  

761  
        @par Preconditions
761  
        @par Preconditions
762  
        @code
762  
        @code
763  
        !this->empty()
763  
        !this->empty()
764  
        @endcode
764  
        @endcode
765  

765  

766  
        @par Exception Safety
766  
        @par Exception Safety
767  
        Throws nothing.
767  
        Throws nothing.
768  
    */
768  
    */
769  
    void
769  
    void
770  
    pop_back() noexcept;
770  
    pop_back() noexcept;
771  

771  

772  
private:
772  
private:
773  
    template<class FwdIt>
773  
    template<class FwdIt>
774  
    iterator
774  
    iterator
775  
    insert(
775  
    insert(
776  
        iterator before,
776  
        iterator before,
777  
        FwdIt first,
777  
        FwdIt first,
778  
        FwdIt last,
778  
        FwdIt last,
779  
        std::input_iterator_tag) = delete;
779  
        std::input_iterator_tag) = delete;
780  

780  

781  
    template<class FwdIt>
781  
    template<class FwdIt>
782  
    iterator
782  
    iterator
783  
    insert(
783  
    insert(
784  
        iterator before,
784  
        iterator before,
785  
        FwdIt first,
785  
        FwdIt first,
786  
        FwdIt last,
786  
        FwdIt last,
787  
        std::forward_iterator_tag);
787  
        std::forward_iterator_tag);
788  
};
788  
};
789  

789  

790  
} // urls
790  
} // urls
791  
} // boost
791  
} // boost
792  

792  

793  
// This is in <boost/url/url_base.hpp>
793  
// This is in <boost/url/url_base.hpp>
794  
//
794  
//
795  
// #include <boost/url/impl/segments_encoded_ref.hpp>
795  
// #include <boost/url/impl/segments_encoded_ref.hpp>
796  

796  

797  
//------------------------------------------------
797  
//------------------------------------------------
798  
//
798  
//
799  
// std::ranges::enable_borrowed_range
799  
// std::ranges::enable_borrowed_range
800  
//
800  
//
801  
//------------------------------------------------
801  
//------------------------------------------------
802  

802  

803  
#ifdef BOOST_URL_HAS_CONCEPTS
803  
#ifdef BOOST_URL_HAS_CONCEPTS
804  
#include <ranges>
804  
#include <ranges>
805  
namespace std::ranges {
805  
namespace std::ranges {
806  
    template<>
806  
    template<>
807  
    inline constexpr bool
807  
    inline constexpr bool
808  
        enable_borrowed_range<
808  
        enable_borrowed_range<
809  
            boost::urls::segments_encoded_ref> = true;
809  
            boost::urls::segments_encoded_ref> = true;
810  
} // std::ranges
810  
} // std::ranges
811  
#endif
811  
#endif
812  

812  

813  
#endif
813  
#endif