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 BOOST_SYMBOL_VISIBLE segments_encoded_ref
79  
class BOOST_SYMBOL_VISIBLE 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  
    segments_encoded_ref&
150  
    segments_encoded_ref&
151  
    operator=(segments_encoded_ref const& other);
151  
    operator=(segments_encoded_ref const& other);
152  

152  

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

156  

157  
    /** Assignment
157  
    /** Assignment
158  

158  

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

165  

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

168  

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

172  

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

175  

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

181  

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

186  

187  
        @par Complexity
187  
        @par Complexity
188  
        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()`.
189  

189  

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

194  

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

197  

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

204  

205  
    /** Conversion
205  
    /** Conversion
206  

206  

207  
        @see
207  
        @see
208  
            @ref segments_encoded_view.
208  
            @ref segments_encoded_view.
209  

209  

210  
        @return A view of the segments.
210  
        @return A view of the segments.
211  
    */
211  
    */
212  
    operator
212  
    operator
213  
    segments_encoded_view() const noexcept;
213  
    segments_encoded_view() const noexcept;
214  

214  

215  
    //--------------------------------------------
215  
    //--------------------------------------------
216  
    //
216  
    //
217  
    // Observers
217  
    // Observers
218  
    //
218  
    //
219  
    //--------------------------------------------
219  
    //--------------------------------------------
220  

220  

221  
    /** Return the referenced url
221  
    /** Return the referenced url
222  

222  

223  
        This function returns the url referenced
223  
        This function returns the url referenced
224  
        by the view.
224  
        by the view.
225  

225  

226  
        @par Example
226  
        @par Example
227  
        @code
227  
        @code
228  
        url u( "/path/to/file.txt" );
228  
        url u( "/path/to/file.txt" );
229  

229  

230  
        assert( &u.encoded_segments().url() == &u );
230  
        assert( &u.encoded_segments().url() == &u );
231  
        @endcode
231  
        @endcode
232  

232  

233  
        @par Exception Safety
233  
        @par Exception Safety
234  
        Throws nothing.
234  
        Throws nothing.
235  

235  

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

243  

244  
    //--------------------------------------------
244  
    //--------------------------------------------
245  
    //
245  
    //
246  
    // Modifiers
246  
    // Modifiers
247  
    //
247  
    //
248  
    //--------------------------------------------
248  
    //--------------------------------------------
249  

249  

250  
    /** Clear the contents of the container
250  
    /** Clear the contents of the container
251  

251  

252  
        <br>
252  
        <br>
253  
        All iterators are invalidated.
253  
        All iterators are invalidated.
254  

254  

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

259  

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

264  

265  
        @par Complexity
265  
        @par Complexity
266  
        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()`.
267  

267  

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

273  

274  
    /** Assign segments
274  
    /** Assign segments
275  

275  

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

282  

283  
        <br>
283  
        <br>
284  
        All iterators are invalidated.
284  
        All iterators are invalidated.
285  

285  

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

291  

292  
        @par Example
292  
        @par Example
293  
        @code
293  
        @code
294  
        url u;
294  
        url u;
295  

295  

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

298  

299  
        @par Complexity
299  
        @par Complexity
300  
        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()`.
301  

301  

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

306  

307  
        @throw system_error
307  
        @throw system_error
308  
        The list contains an invalid percent-encoding.
308  
        The list contains an invalid percent-encoding.
309  

309  

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

315  

316  
    /** Assign segments
316  
    /** Assign segments
317  

317  

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

323  

324  
        <br>
324  
        <br>
325  
        All iterators are invalidated.
325  
        All iterators are invalidated.
326  

326  

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

332  

333  
        @par Mandates
333  
        @par Mandates
334  
        @code
334  
        @code
335  
        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
336  
        @endcode
336  
        @endcode
337  

337  

338  
        @par Complexity
338  
        @par Complexity
339  
        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()`.
340  

340  

341  
        @par Exception Safety
341  
        @par Exception Safety
342  
        Strong guarantee.
342  
        Strong guarantee.
343  
        Calls to allocate may throw.
343  
        Calls to allocate may throw.
344  
        Exceptions thrown on invalid input.
344  
        Exceptions thrown on invalid input.
345  

345  

346  
        @throw system_error
346  
        @throw system_error
347  
        The range contains an invalid percent-encoding.
347  
        The range contains an invalid percent-encoding.
348  

348  

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

355  

356  
    //--------------------------------------------
356  
    //--------------------------------------------
357  

357  

358  
    /** Insert segments
358  
    /** Insert segments
359  

359  

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

365  

366  
        <br>
366  
        <br>
367  
        All iterators that are equal to
367  
        All iterators that are equal to
368  
        `before` or come after are invalidated.
368  
        `before` or come after are invalidated.
369  

369  

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

372  

373  
        @par Exception Safety
373  
        @par Exception Safety
374  
        Strong guarantee.
374  
        Strong guarantee.
375  
        Calls to allocate may throw.
375  
        Calls to allocate may throw.
376  
        Exceptions thrown on invalid input.
376  
        Exceptions thrown on invalid input.
377  

377  

378  
        @throw system_error
378  
        @throw system_error
379  
        The segment contains an invalid percent-encoding.
379  
        The segment contains an invalid percent-encoding.
380  

380  

381  
        @return An iterator to the inserted
381  
        @return An iterator to the inserted
382  
        segment.
382  
        segment.
383  

383  

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

387  

388  
        @param s The segment to insert.
388  
        @param s The segment to insert.
389  
    */
389  
    */
390  
    iterator
390  
    iterator
391  
    insert(
391  
    insert(
392  
        iterator before,
392  
        iterator before,
393  
        pct_string_view s);
393  
        pct_string_view s);
394  

394  

395  
    /** Insert segments
395  
    /** Insert segments
396  

396  

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

403  

404  
        <br>
404  
        <br>
405  
        All iterators that are equal to
405  
        All iterators that are equal to
406  
        `before` or come after are invalidated.
406  
        `before` or come after are invalidated.
407  

407  

408  
        @note
408  
        @note
409  
        None of the character buffers referenced
409  
        None of the character buffers referenced
410  
        by the list may overlap the character
410  
        by the list may overlap the character
411  
        buffer of the underlying url, or else
411  
        buffer of the underlying url, or else
412  
        the behavior is undefined.
412  
        the behavior is undefined.
413  

413  

414  
        @par Example
414  
        @par Example
415  
        @code
415  
        @code
416  
        url u( "/file.txt" );
416  
        url u( "/file.txt" );
417  

417  

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

420  

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

423  

424  
        @par Exception Safety
424  
        @par Exception Safety
425  
        Strong guarantee.
425  
        Strong guarantee.
426  
        Calls to allocate may throw.
426  
        Calls to allocate may throw.
427  
        Exceptions thrown on invalid input.
427  
        Exceptions thrown on invalid input.
428  

428  

429  
        @throw system_error
429  
        @throw system_error
430  
        The list contains an invalid percent-encoding.
430  
        The list contains an invalid percent-encoding.
431  

431  

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

435  

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

439  

440  
        @param init The list of segments to insert.
440  
        @param init The list of segments to insert.
441  
    */
441  
    */
442  
    iterator
442  
    iterator
443  
    insert(
443  
    insert(
444  
        iterator before,
444  
        iterator before,
445  
        std::initializer_list<
445  
        std::initializer_list<
446  
            pct_string_view> init);
446  
            pct_string_view> init);
447  

447  

448  
    /** Insert segments
448  
    /** Insert segments
449  

449  

450  
        This function inserts the segments in
450  
        This function inserts the segments in
451  
        a range before the specified position.
451  
        a range before the specified position.
452  
        Reserved characters in the range are
452  
        Reserved characters in the range are
453  
        automatically escaped.
453  
        automatically escaped.
454  
        Escapes in the range are preserved.
454  
        Escapes in the range are preserved.
455  

455  

456  
        <br>
456  
        <br>
457  
        All iterators that are equal to
457  
        All iterators that are equal to
458  
        `before` or come after are invalidated.
458  
        `before` or come after are invalidated.
459  

459  

460  
        @note
460  
        @note
461  
        None of the character buffers referenced
461  
        None of the character buffers referenced
462  
        by the range may overlap the character
462  
        by the range may overlap the character
463  
        buffer of the underlying url, or else
463  
        buffer of the underlying url, or else
464  
        the behavior is undefined.
464  
        the behavior is undefined.
465  

465  

466  
        @par Mandates
466  
        @par Mandates
467  
        @code
467  
        @code
468  
        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
469  
        @endcode
469  
        @endcode
470  

470  

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

473  

474  
        @par Exception Safety
474  
        @par Exception Safety
475  
        Strong guarantee.
475  
        Strong guarantee.
476  
        Calls to allocate may throw.
476  
        Calls to allocate may throw.
477  
        Exceptions thrown on invalid input.
477  
        Exceptions thrown on invalid input.
478  

478  

479  
        @throw system_error
479  
        @throw system_error
480  
        The range contains an invalid percent-encoding.
480  
        The range contains an invalid percent-encoding.
481  

481  

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

485  

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

489  

490  
        @param first The first element in the range to insert.
490  
        @param first The first element in the range to insert.
491  
        @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.
492  
    */
492  
    */
493  
    template<class FwdIt>
493  
    template<class FwdIt>
494  
    iterator
494  
    iterator
495  
    insert(
495  
    insert(
496  
        iterator before,
496  
        iterator before,
497  
        FwdIt first,
497  
        FwdIt first,
498  
        FwdIt last);
498  
        FwdIt last);
499  

499  

500  
    //--------------------------------------------
500  
    //--------------------------------------------
501  

501  

502  
    /** Erase segments
502  
    /** Erase segments
503  

503  

504  
        This function removes a segment.
504  
        This function removes a segment.
505  

505  

506  
        <br>
506  
        <br>
507  
        All iterators that are equal to
507  
        All iterators that are equal to
508  
        `pos` or come after are invalidated.
508  
        `pos` or come after are invalidated.
509  

509  

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

512  

513  
        @par Exception Safety
513  
        @par Exception Safety
514  
        Throws nothing.
514  
        Throws nothing.
515  

515  

516  
        @return An iterator to one past
516  
        @return An iterator to one past
517  
        the removed segment.
517  
        the removed segment.
518  

518  

519  
        @param pos An iterator to the element.
519  
        @param pos An iterator to the element.
520  
    */
520  
    */
521  
    iterator
521  
    iterator
522  
    erase(
522  
    erase(
523  
        iterator pos) noexcept;
523  
        iterator pos) noexcept;
524  

524  

525  
    /** Erase segments
525  
    /** Erase segments
526  

526  

527  
        This function removes a range of segments
527  
        This function removes a range of segments
528  
        from the container.
528  
        from the container.
529  

529  

530  
        <br>
530  
        <br>
531  
        All iterators that are equal to
531  
        All iterators that are equal to
532  
        `first` or come after are invalidated.
532  
        `first` or come after are invalidated.
533  

533  

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

536  

537  
        @par Exception Safety
537  
        @par Exception Safety
538  
        Throws nothing.
538  
        Throws nothing.
539  

539  

540  
        @param first The first element in the range to erase.
540  
        @param first The first element in the range to erase.
541  
        @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.
542  
        @return An iterator to one past the removed range.
542  
        @return An iterator to one past the removed range.
543  
    */
543  
    */
544  
    iterator
544  
    iterator
545  
    erase(
545  
    erase(
546  
        iterator first,
546  
        iterator first,
547  
        iterator last) noexcept;
547  
        iterator last) noexcept;
548  

548  

549  
    //--------------------------------------------
549  
    //--------------------------------------------
550  

550  

551  
    /** Replace segments
551  
    /** Replace segments
552  

552  

553  
        This function replaces the segment at
553  
        This function replaces the segment at
554  
        the specified position.
554  
        the specified position.
555  
        Reserved characters in the string are
555  
        Reserved characters in the string are
556  
        automatically escaped.
556  
        automatically escaped.
557  
        Escapes in the string are preserved.
557  
        Escapes in the string are preserved.
558  

558  

559  
        <br>
559  
        <br>
560  
        All iterators that are equal to
560  
        All iterators that are equal to
561  
        `pos` or come after are invalidated.
561  
        `pos` or come after are invalidated.
562  

562  

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

565  

566  
        @par Exception Safety
566  
        @par Exception Safety
567  
        Strong guarantee.
567  
        Strong guarantee.
568  
        Calls to allocate may throw.
568  
        Calls to allocate may throw.
569  

569  

570  
        @return An iterator to the replaced segment.
570  
        @return An iterator to the replaced segment.
571  

571  

572  
        @param pos An iterator to the segment.
572  
        @param pos An iterator to the segment.
573  

573  

574  
        @param s The string to assign.
574  
        @param s The string to assign.
575  
    */
575  
    */
576  
    iterator
576  
    iterator
577  
    replace(
577  
    replace(
578  
        iterator pos,
578  
        iterator pos,
579  
        pct_string_view s);
579  
        pct_string_view s);
580  

580  

581  
    /** Replace segments
581  
    /** Replace segments
582  

582  

583  
        This function replaces a range of
583  
        This function replaces a range of
584  
        segments with one segment.
584  
        segments with one segment.
585  
        Reserved characters in the string are
585  
        Reserved characters in the string are
586  
        automatically escaped.
586  
        automatically escaped.
587  
        Escapes in the string are preserved.
587  
        Escapes in the string are preserved.
588  

588  

589  
        <br>
589  
        <br>
590  
        All iterators that are equal to
590  
        All iterators that are equal to
591  
        `from` or come after are invalidated.
591  
        `from` or come after are invalidated.
592  

592  

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

595  

596  
        @par Exception Safety
596  
        @par Exception Safety
597  
        Strong guarantee.
597  
        Strong guarantee.
598  
        Calls to allocate may throw.
598  
        Calls to allocate may throw.
599  
        Exceptions thrown on invalid input.
599  
        Exceptions thrown on invalid input.
600  

600  

601  
        @throw system_error
601  
        @throw system_error
602  
        The string contains an invalid percent-encoding.
602  
        The string contains an invalid percent-encoding.
603  

603  

604  
        @return An iterator to the new segment.
604  
        @return An iterator to the new segment.
605  

605  

606  
        @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.
607  
        @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.
608  

608  

609  
        @param s The string to assign.
609  
        @param s The string to assign.
610  
    */
610  
    */
611  
    iterator
611  
    iterator
612  
    replace(
612  
    replace(
613  
        iterator from,
613  
        iterator from,
614  
        iterator to,
614  
        iterator to,
615  
        pct_string_view s);
615  
        pct_string_view s);
616  

616  

617  
    /** Replace segments
617  
    /** Replace segments
618  

618  

619  
        This function replaces a range of
619  
        This function replaces a range of
620  
        segments with a list of segments in
620  
        segments with a list of segments in
621  
        an initializer list.
621  
        an initializer list.
622  
        Reserved characters in the list are
622  
        Reserved characters in the list are
623  
        automatically escaped.
623  
        automatically escaped.
624  
        Escapes in the list are preserved.
624  
        Escapes in the list are preserved.
625  

625  

626  
        <br>
626  
        <br>
627  
        All iterators that are equal to
627  
        All iterators that are equal to
628  
        `from` or come after are invalidated.
628  
        `from` or come after are invalidated.
629  

629  

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

635  

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

638  

639  
        @par Exception Safety
639  
        @par Exception Safety
640  
        Strong guarantee.
640  
        Strong guarantee.
641  
        Calls to allocate may throw.
641  
        Calls to allocate may throw.
642  
        Exceptions thrown on invalid input.
642  
        Exceptions thrown on invalid input.
643  

643  

644  
        @throw system_error
644  
        @throw system_error
645  
        The list contains an invalid percent-encoding.
645  
        The list contains an invalid percent-encoding.
646  

646  

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

650  

651  
        @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.
652  
        @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.
653  

653  

654  
        @param init The list of segments to assign.
654  
        @param init The list of segments to assign.
655  
    */
655  
    */
656  
    iterator
656  
    iterator
657  
    replace(
657  
    replace(
658  
        iterator from,
658  
        iterator from,
659  
        iterator to,
659  
        iterator to,
660  
        std::initializer_list<
660  
        std::initializer_list<
661  
            pct_string_view> init);
661  
            pct_string_view> init);
662  

662  

663  
    /** Replace segments
663  
    /** Replace segments
664  

664  

665  
        This function replaces a range of
665  
        This function replaces a range of
666  
        segments with annother range of segments.
666  
        segments with annother range of segments.
667  
        Reserved characters in the new range are
667  
        Reserved characters in the new range are
668  
        automatically escaped.
668  
        automatically escaped.
669  
        Escapes in the new range are preserved.
669  
        Escapes in the new range are preserved.
670  

670  

671  
        <br>
671  
        <br>
672  
        All iterators that are equal to
672  
        All iterators that are equal to
673  
        `from` or come after are invalidated.
673  
        `from` or come after are invalidated.
674  

674  

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

680  

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

683  

684  
        @par Exception Safety
684  
        @par Exception Safety
685  
        Strong guarantee.
685  
        Strong guarantee.
686  
        Calls to allocate may throw.
686  
        Calls to allocate may throw.
687  
        Exceptions thrown on invalid input.
687  
        Exceptions thrown on invalid input.
688  

688  

689  
        @throw system_error
689  
        @throw system_error
690  
        The range contains an invalid percent-encoding.
690  
        The range contains an invalid percent-encoding.
691  

691  

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

695  

696  
        @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.
697  
        @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.
698  
        @param first The first element in the new range of segments.
698  
        @param first The first element in the new range of segments.
699  
        @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.
700  
    */
700  
    */
701  
    template<class FwdIt>
701  
    template<class FwdIt>
702  
    iterator
702  
    iterator
703  
    replace(
703  
    replace(
704  
        iterator from,
704  
        iterator from,
705  
        iterator to,
705  
        iterator to,
706  
        FwdIt first,
706  
        FwdIt first,
707  
        FwdIt last);
707  
        FwdIt last);
708  

708  

709  
    //--------------------------------------------
709  
    //--------------------------------------------
710  

710  

711  
    /** Append a segment
711  
    /** Append a segment
712  

712  

713  
        This function appends a segment to
713  
        This function appends a segment to
714  
        the end of the path.
714  
        the end of the path.
715  
        Reserved characters in the string are
715  
        Reserved characters in the string are
716  
        automatically escaped.
716  
        automatically escaped.
717  
        Escapes in the string are preserved.
717  
        Escapes in the string are preserved.
718  

718  

719  
        <br>
719  
        <br>
720  
        All end iterators are invalidated.
720  
        All end iterators are invalidated.
721  

721  

722  
        @par Postconditions
722  
        @par Postconditions
723  
        @code
723  
        @code
724  
        this->back() == s
724  
        this->back() == s
725  
        @endcode
725  
        @endcode
726  

726  

727  
        @par Exception Safety
727  
        @par Exception Safety
728  
        Strong guarantee.
728  
        Strong guarantee.
729  
        Calls to allocate may throw.
729  
        Calls to allocate may throw.
730  
        Exceptions thrown on invalid input.
730  
        Exceptions thrown on invalid input.
731  

731  

732  
        @throw system_error
732  
        @throw system_error
733  
        The string contains an invalid percent-encoding.
733  
        The string contains an invalid percent-encoding.
734  

734  

735  
        @param s The segment to append.
735  
        @param s The segment to append.
736  
    */
736  
    */
737  
    void
737  
    void
738  
    push_back(
738  
    push_back(
739  
        pct_string_view s);
739  
        pct_string_view s);
740  

740  

741  
    /** Remove the last segment
741  
    /** Remove the last segment
742  

742  

743  
        This function removes the last segment
743  
        This function removes the last segment
744  
        from the container.
744  
        from the container.
745  

745  

746  
        <br>
746  
        <br>
747  
        Iterators to the last segment as well
747  
        Iterators to the last segment as well
748  
        as all end iterators are invalidated.
748  
        as all end iterators are invalidated.
749  

749  

750  
        @par Preconditions
750  
        @par Preconditions
751  
        @code
751  
        @code
752  
        !this->empty()
752  
        !this->empty()
753  
        @endcode
753  
        @endcode
754  

754  

755  
        @par Exception Safety
755  
        @par Exception Safety
756  
        Throws nothing.
756  
        Throws nothing.
757  
    */
757  
    */
758  
    void
758  
    void
759  
    pop_back() noexcept;
759  
    pop_back() noexcept;
760  

760  

761  
private:
761  
private:
762  
    template<class FwdIt>
762  
    template<class FwdIt>
763  
    iterator
763  
    iterator
764  
    insert(
764  
    insert(
765  
        iterator before,
765  
        iterator before,
766  
        FwdIt first,
766  
        FwdIt first,
767  
        FwdIt last,
767  
        FwdIt last,
768  
        std::input_iterator_tag) = delete;
768  
        std::input_iterator_tag) = delete;
769  

769  

770  
    template<class FwdIt>
770  
    template<class FwdIt>
771  
    iterator
771  
    iterator
772  
    insert(
772  
    insert(
773  
        iterator before,
773  
        iterator before,
774  
        FwdIt first,
774  
        FwdIt first,
775  
        FwdIt last,
775  
        FwdIt last,
776  
        std::forward_iterator_tag);
776  
        std::forward_iterator_tag);
777  
};
777  
};
778  

778  

779  
} // urls
779  
} // urls
780  
} // boost
780  
} // boost
781  

781  

782  
// This is in <boost/url/url_base.hpp>
782  
// This is in <boost/url/url_base.hpp>
783  
//
783  
//
784  
// #include <boost/url/impl/segments_encoded_ref.hpp>
784  
// #include <boost/url/impl/segments_encoded_ref.hpp>
785  

785  

786  
//------------------------------------------------
786  
//------------------------------------------------
787  
//
787  
//
788  
// std::ranges::enable_borrowed_range
788  
// std::ranges::enable_borrowed_range
789  
//
789  
//
790  
//------------------------------------------------
790  
//------------------------------------------------
791  

791  

792  
#ifdef BOOST_URL_HAS_CONCEPTS
792  
#ifdef BOOST_URL_HAS_CONCEPTS
793  
#include <ranges>
793  
#include <ranges>
794  
namespace std::ranges {
794  
namespace std::ranges {
795  
    template<>
795  
    template<>
796  
    inline constexpr bool
796  
    inline constexpr bool
797  
        enable_borrowed_range<
797  
        enable_borrowed_range<
798  
            boost::urls::segments_encoded_ref> = true;
798  
            boost::urls::segments_encoded_ref> = true;
799  
} // std::ranges
799  
} // std::ranges
800  
#endif
800  
#endif
801  

801  

802  
#endif
802  
#endif