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 BOOST_URL_DECL 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 -
    BOOST_URL_DECL
 
150  
    */
149  
    */
151  
    segments_encoded_ref&
150  
    segments_encoded_ref&
152  
    operator=(segments_encoded_ref const& other);
151  
    operator=(segments_encoded_ref const& other);
153  

152  

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

156  

159  
    /** Assignment
157  
    /** Assignment
160  

158  

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

165  

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

168  

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

172  

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

175  

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

181  

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

186  

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

189  

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

194  

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

197  

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

204  

208  
    /** Conversion
205  
    /** Conversion
209  

206  

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

209  

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

214  

219  
    //--------------------------------------------
215  
    //--------------------------------------------
220  
    //
216  
    //
221  
    // Observers
217  
    // Observers
222  
    //
218  
    //
223  
    //--------------------------------------------
219  
    //--------------------------------------------
224  

220  

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

222  

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

225  

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

229  

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

232  

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

235  

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

243  

248  
    //--------------------------------------------
244  
    //--------------------------------------------
249  
    //
245  
    //
250  
    // Modifiers
246  
    // Modifiers
251  
    //
247  
    //
252  
    //--------------------------------------------
248  
    //--------------------------------------------
253  

249  

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

251  

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

254  

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

259  

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

264  

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

267  

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

273  

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

275  

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

282  

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

285  

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

291  

296  
        @par Example
292  
        @par Example
297  
        @code
293  
        @code
298  
        url u;
294  
        url u;
299  

295  

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

298  

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

301  

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

306  

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

309  

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

315  

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

317  

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

323  

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

326  

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

332  

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

337  

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

340  

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

345  

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

348  

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

355  

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

357  

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

359  

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

365  

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

369  

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

372  

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

377  

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

380  

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

383  

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

387  

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

394  

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

396  

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

403  

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

407  

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

413  

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

417  

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

420  

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

423  

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

428  

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

431  

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

435  

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

439  

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

447  

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

449  

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

455  

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

459  

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

465  

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

470  

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

473  

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

478  

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

481  

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

485  

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

489  

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

499  

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

501  

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

503  

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

505  

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

509  

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

512  

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

515  

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

518  

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

524  

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

526  

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

529  

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

533  

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

536  

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

539  

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

548  

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

550  

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

552  

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

558  

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

562  

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

565  

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

569  

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

571  

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

573  

582  
        @param s The string to assign.
574  
        @param s The string to assign.
583 -
    BOOST_URL_DECL
 
584  
    */
575  
    */
585  
    iterator
576  
    iterator
586  
    replace(
577  
    replace(
587  
        iterator pos,
578  
        iterator pos,
588  
        pct_string_view s);
579  
        pct_string_view s);
589  

580  

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

582  

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

588  

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

592  

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

595  

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

600  

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

603  

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

605  

615  
        @param from The first element in the range of segments to replace.
606  
        @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.
607  
        @param to One past the last element in the range of segments to replace.
617  

608  

618  
        @param s The string to assign.
609  
        @param s The string to assign.
619 -
    BOOST_URL_DECL
 
620  
    */
610  
    */
621  
    iterator
611  
    iterator
622  
    replace(
612  
    replace(
623  
        iterator from,
613  
        iterator from,
624  
        iterator to,
614  
        iterator to,
625  
        pct_string_view s);
615  
        pct_string_view s);
626  

616  

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

618  

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

625  

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

629  

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

635  

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

638  

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

643  

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

646  

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

650  

661  
        @param from The first element in the range of segments to replace.
651  
        @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.
652  
        @param to One past the last element in the range of segments to replace.
663  

653  

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

662  

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

664  

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

670  

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

674  

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

680  

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

683  

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

688  

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

691  

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

695  

707  
        @param from The first element in the range of segments to replace.
696  
        @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.
697  
        @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.
698  
        @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.
699  
        @param last One past the last element in the new range of segments.
711  
    */
700  
    */
712  
    template<class FwdIt>
701  
    template<class FwdIt>
713  
    iterator
702  
    iterator
714  
    replace(
703  
    replace(
715  
        iterator from,
704  
        iterator from,
716  
        iterator to,
705  
        iterator to,
717  
        FwdIt first,
706  
        FwdIt first,
718  
        FwdIt last);
707  
        FwdIt last);
719  

708  

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

710  

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

712  

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

718  

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

721  

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

726  

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

731  

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

734  

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

740  

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

742  

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

745  

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

749  

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

754  

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

760  

772  
private:
761  
private:
773  
    template<class FwdIt>
762  
    template<class FwdIt>
774  
    iterator
763  
    iterator
775  
    insert(
764  
    insert(
776  
        iterator before,
765  
        iterator before,
777  
        FwdIt first,
766  
        FwdIt first,
778  
        FwdIt last,
767  
        FwdIt last,
779  
        std::input_iterator_tag) = delete;
768  
        std::input_iterator_tag) = delete;
780  

769  

781  
    template<class FwdIt>
770  
    template<class FwdIt>
782  
    iterator
771  
    iterator
783  
    insert(
772  
    insert(
784  
        iterator before,
773  
        iterator before,
785  
        FwdIt first,
774  
        FwdIt first,
786  
        FwdIt last,
775  
        FwdIt last,
787  
        std::forward_iterator_tag);
776  
        std::forward_iterator_tag);
788  
};
777  
};
789  

778  

790  
} // urls
779  
} // urls
791  
} // boost
780  
} // boost
792  

781  

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

785  

797  
//------------------------------------------------
786  
//------------------------------------------------
798  
//
787  
//
799  
// std::ranges::enable_borrowed_range
788  
// std::ranges::enable_borrowed_range
800  
//
789  
//
801  
//------------------------------------------------
790  
//------------------------------------------------
802  

791  

803  
#ifdef BOOST_URL_HAS_CONCEPTS
792  
#ifdef BOOST_URL_HAS_CONCEPTS
804  
#include <ranges>
793  
#include <ranges>
805  
namespace std::ranges {
794  
namespace std::ranges {
806  
    template<>
795  
    template<>
807  
    inline constexpr bool
796  
    inline constexpr bool
808  
        enable_borrowed_range<
797  
        enable_borrowed_range<
809  
            boost::urls::segments_encoded_ref> = true;
798  
            boost::urls::segments_encoded_ref> = true;
810  
} // std::ranges
799  
} // std::ranges
811  
#endif
800  
#endif
812  

801  

813  
#endif
802  
#endif