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_REF_HPP
11  
#ifndef BOOST_URL_SEGMENTS_REF_HPP
12  
#define BOOST_URL_SEGMENTS_REF_HPP
12  
#define BOOST_URL_SEGMENTS_REF_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/segments_base.hpp>
15  
#include <boost/url/segments_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_view;
24  
class segments_view;
25  
#endif
25  
#endif
26  

26  

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

28  

29  
    Presents the decoded path segments of a
29  
    Presents the decoded path segments of a
30  
    @ref url_base as a bidirectional range whose
30  
    @ref url_base as a bidirectional range whose
31  
    modifiers update the underlying URL. The proxy
31  
    modifiers update the underlying URL. The proxy
32  
    references the URL’s storage directly, so the
32  
    references the URL’s storage directly, so the
33  
    owning URL must remain alive while the proxy
33  
    owning URL must remain alive while the proxy
34  
    is used.
34  
    is used.
35  

35  

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

39  

40  
    segments_ref ps = u.segments();
40  
    segments_ref ps = u.segments();
41  
    @endcode
41  
    @endcode
42  

42  

43  
    Percent escapes in strings returned when
43  
    Percent escapes in strings returned when
44  
    dereferencing iterators are automatically
44  
    dereferencing iterators are automatically
45  
    decoded.
45  
    decoded.
46  
    Reserved characters in strings supplied
46  
    Reserved characters in strings supplied
47  
    to modifier functions are automatically
47  
    to modifier functions are automatically
48  
    percent-escaped.
48  
    percent-escaped.
49  

49  

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

56  

57  
    @li @ref push_back : Only `end()`.
57  
    @li @ref push_back : Only `end()`.
58  

58  

59  
    @li @ref assign, @ref clear,
59  
    @li @ref assign, @ref clear,
60  
        @ref operator= : All elements.
60  
        @ref operator= : All elements.
61  

61  

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

64  

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

67  

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

71  

72  
    @see
72  
    @see
73  
        @ref segments_encoded_ref,
73  
        @ref segments_encoded_ref,
74  
        @ref segments_encoded_view,
74  
        @ref segments_encoded_view,
75  
        @ref segments_view.
75  
        @ref segments_view.
76  
*/
76  
*/
77  
class segments_ref
77  
class segments_ref
78  
    : public segments_base
78  
    : public segments_base
79  
{
79  
{
80  
    url_base* u_ = nullptr;
80  
    url_base* u_ = nullptr;
81  

81  

82  
    friend class url_base;
82  
    friend class url_base;
83  
    friend class segments_encoded_ref;
83  
    friend class segments_encoded_ref;
84  

84  

85  
    segments_ref(url_base& u) noexcept;
85  
    segments_ref(url_base& u) noexcept;
86  

86  

87  
public:
87  
public:
88  
    //--------------------------------------------
88  
    //--------------------------------------------
89  
    //
89  
    //
90  
    // Special Members
90  
    // Special Members
91  
    //
91  
    //
92  
    //--------------------------------------------
92  
    //--------------------------------------------
93  

93  

94  
    /** Constructor
94  
    /** Constructor
95  

95  

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

102  

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

107  

108  
        @par Complexity
108  
        @par Complexity
109  
        Constant.
109  
        Constant.
110  

110  

111  
        @par Exception Safety
111  
        @par Exception Safety
112  
        Throws nothing.
112  
        Throws nothing.
113  

113  

114  
        @param other The other view.
114  
        @param other The other view.
115  
    */
115  
    */
116  
    segments_ref(
116  
    segments_ref(
117  
        segments_ref const& other) = default;
117  
        segments_ref const& other) = default;
118  

118  

119  
    /** Assignment
119  
    /** Assignment
120  

120  

121  
        The existing contents are replaced
121  
        The existing contents are replaced
122  
        by a copy of the other segments.
122  
        by a copy of the other segments.
123  

123  

124  
        <br>
124  
        <br>
125  
        All iterators are invalidated.
125  
        All iterators are invalidated.
126  

126  

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

132  

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

137  

138  
        @par Complexity
138  
        @par Complexity
139  
        Linear in `other.buffer().size()`.
139  
        Linear in `other.buffer().size()`.
140  

140  

141  
        @par Exception Safety
141  
        @par Exception Safety
142  
        Strong guarantee.
142  
        Strong guarantee.
143  
        Calls to allocate may throw.
143  
        Calls to allocate may throw.
144  

144  

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

151  

152  
    /// @copydoc segments_ref::operator=(segments_ref const&)
152  
    /// @copydoc segments_ref::operator=(segments_ref const&)
153  
    BOOST_URL_DECL
153  
    BOOST_URL_DECL
154  
    segments_ref&
154  
    segments_ref&
155  
    operator=(segments_view const& other);
155  
    operator=(segments_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  

164  

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

167  

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

171  

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

174  

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

180  

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

185  

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

188  

189  
        @par Exception Safety
189  
        @par Exception Safety
190  
        Strong guarantee.
190  
        Strong guarantee.
191  
        Calls to allocate may throw.
191  
        Calls to allocate may throw.
192  

192  

193  
        @param init The list of segments to assign.
193  
        @param init The list of segments to assign.
194  
        @return A reference to this object.
194  
        @return A reference to this object.
195  
    */
195  
    */
196  
    BOOST_URL_DECL
196  
    BOOST_URL_DECL
197  
    segments_ref&
197  
    segments_ref&
198  
    operator=(std::initializer_list<
198  
    operator=(std::initializer_list<
199  
        core::string_view> init);
199  
        core::string_view> init);
200  

200  

201  
    /** Conversion
201  
    /** Conversion
202  

202  

203  
        @see
203  
        @see
204  
            @ref segments_view.
204  
            @ref segments_view.
205  

205  

206  
        @return A view of the segments.
206  
        @return A view of the segments.
207  
    */
207  
    */
208  
    BOOST_URL_DECL
208  
    BOOST_URL_DECL
209  
    operator
209  
    operator
210  
    segments_view() const noexcept;
210  
    segments_view() const noexcept;
211  

211  

212  
    //--------------------------------------------
212  
    //--------------------------------------------
213  
    //
213  
    //
214  
    // Observers
214  
    // Observers
215  
    //
215  
    //
216  
    //--------------------------------------------
216  
    //--------------------------------------------
217  

217  

218  
    /** Return the referenced url
218  
    /** Return the referenced url
219  

219  

220  
        This function returns the url referenced
220  
        This function returns the url referenced
221  
        by the view.
221  
        by the view.
222  

222  

223  
        @par Example
223  
        @par Example
224  
        @code
224  
        @code
225  
        url u( "/path/to/file.txt" );
225  
        url u( "/path/to/file.txt" );
226  

226  

227  
        assert( &u.segments().url() == &u );
227  
        assert( &u.segments().url() == &u );
228  
        @endcode
228  
        @endcode
229  

229  

230  
        @par Exception Safety
230  
        @par Exception Safety
231  
        Throws nothing.
231  
        Throws nothing.
232  

232  

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

240  

241  
    //--------------------------------------------
241  
    //--------------------------------------------
242  
    //
242  
    //
243  
    // Modifiers
243  
    // Modifiers
244  
    //
244  
    //
245  
    //--------------------------------------------
245  
    //--------------------------------------------
246  

246  

247  
    /** Clear the contents of the container
247  
    /** Clear the contents of the container
248  

248  

249  
        <br>
249  
        <br>
250  
        All iterators are invalidated.
250  
        All iterators are invalidated.
251  

251  

252  
        @par Effects
252  
        @par Effects
253  
        @code
253  
        @code
254  
        this->url().set_encoded_path( "" );
254  
        this->url().set_encoded_path( "" );
255  
        @endcode
255  
        @endcode
256  

256  

257  
        @par Postconditions
257  
        @par Postconditions
258  
        @code
258  
        @code
259  
        this->empty() == true
259  
        this->empty() == true
260  
        @endcode
260  
        @endcode
261  

261  

262  
        @par Complexity
262  
        @par Complexity
263  
        Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
263  
        Linear in `this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
264  

264  

265  
        @par Exception Safety
265  
        @par Exception Safety
266  
        Throws nothing.
266  
        Throws nothing.
267  
    */
267  
    */
268  
    void
268  
    void
269  
    clear() noexcept;
269  
    clear() noexcept;
270  

270  

271  
    /** Assign segments
271  
    /** Assign segments
272  

272  

273  
        The existing contents are replaced
273  
        The existing contents are replaced
274  
        by a copy of the contents of the
274  
        by a copy of the contents of the
275  
        initializer list.
275  
        initializer list.
276  
        Reserved characters in the list are
276  
        Reserved characters in the list are
277  
        automatically escaped.
277  
        automatically escaped.
278  

278  

279  
        <br>
279  
        <br>
280  
        All iterators are invalidated.
280  
        All iterators are invalidated.
281  

281  

282  
        @note
282  
        @note
283  
        None of the character buffers referenced
283  
        None of the character buffers referenced
284  
        by `init` may overlap the character buffer
284  
        by `init` may overlap the character buffer
285  
        of the underlying url, or else the behavior
285  
        of the underlying url, or else the behavior
286  
        is undefined.
286  
        is undefined.
287  

287  

288  
        @par Example
288  
        @par Example
289  
        @code
289  
        @code
290  
        url u;
290  
        url u;
291  

291  

292  
        u.segments().assign( { "path", "to", "file.txt" } );
292  
        u.segments().assign( { "path", "to", "file.txt" } );
293  
        @endcode
293  
        @endcode
294  

294  

295  
        @par Complexity
295  
        @par Complexity
296  
        Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
296  
        Linear in `init.size() + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
297  

297  

298  
        @par Exception Safety
298  
        @par Exception Safety
299  
        Strong guarantee.
299  
        Strong guarantee.
300  
        Calls to allocate may throw.
300  
        Calls to allocate may throw.
301  

301  

302  
        @param init The list of segments to assign.
302  
        @param init The list of segments to assign.
303  
    */
303  
    */
304  
    BOOST_URL_DECL
304  
    BOOST_URL_DECL
305  
    void
305  
    void
306  
    assign(std::initializer_list<
306  
    assign(std::initializer_list<
307  
        core::string_view> init);
307  
        core::string_view> init);
308  

308  

309  
    /** Assign segments
309  
    /** Assign segments
310  

310  

311  
        The existing contents are replaced
311  
        The existing contents are replaced
312  
        by a copy of the contents of the range.
312  
        by a copy of the contents of the range.
313  
        Reserved characters in the range are
313  
        Reserved characters in the range are
314  
        automatically escaped.
314  
        automatically escaped.
315  

315  

316  
        <br>
316  
        <br>
317  
        All iterators are invalidated.
317  
        All iterators are invalidated.
318  

318  

319  
        @note
319  
        @note
320  
        None of the character buffers referenced
320  
        None of the character buffers referenced
321  
        by the range may overlap the character
321  
        by the range may overlap the character
322  
        buffer of the underlying url, or else
322  
        buffer of the underlying url, or else
323  
        the behavior is undefined.
323  
        the behavior is undefined.
324  

324  

325  
        @par Mandates
325  
        @par Mandates
326  
        @code
326  
        @code
327  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
327  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
328  
        @endcode
328  
        @endcode
329  

329  

330  
        @par Complexity
330  
        @par Complexity
331  
        Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
331  
        Linear in `std::distance( first, last ) + this->url().encoded_query().size() + this->url().encoded_fragment().size()`.
332  

332  

333  
        @par Exception Safety
333  
        @par Exception Safety
334  
        Strong guarantee.
334  
        Strong guarantee.
335  
        Calls to allocate may throw.
335  
        Calls to allocate may throw.
336  

336  

337  
        @param first The beginning of the range of segments to assign.
337  
        @param first The beginning of the range of segments to assign.
338  
        @param last The end of the range of segments to assign.
338  
        @param last The end of the range of segments to assign.
339  
    */
339  
    */
340  
    template<class FwdIt>
340  
    template<class FwdIt>
341  
    void
341  
    void
342  
    assign(FwdIt first, FwdIt last);
342  
    assign(FwdIt first, FwdIt last);
343  

343  

344  
    //--------------------------------------------
344  
    //--------------------------------------------
345  

345  

346  
    /** Insert segments
346  
    /** Insert segments
347  

347  

348  
        This function inserts a segment
348  
        This function inserts a segment
349  
        before the specified position.
349  
        before the specified position.
350  
        Reserved characters in the segment are
350  
        Reserved characters in the segment are
351  
        automatically escaped.
351  
        automatically escaped.
352  

352  

353  
        <br>
353  
        <br>
354  
        All iterators that are equal to
354  
        All iterators that are equal to
355  
        `before` or come after are invalidated.
355  
        `before` or come after are invalidated.
356  

356  

357  
        @par Complexity
357  
        @par Complexity
358  
        Linear in `s.size() + this->url().encoded_resource().size()`.
358  
        Linear in `s.size() + this->url().encoded_resource().size()`.
359  

359  

360  
        @par Exception Safety
360  
        @par Exception Safety
361  
        Strong guarantee.
361  
        Strong guarantee.
362  
        Calls to allocate may throw.
362  
        Calls to allocate may throw.
363  

363  

364  
        @return An iterator to the inserted
364  
        @return An iterator to the inserted
365  
        segment.
365  
        segment.
366  

366  

367  
        @param before An iterator before which
367  
        @param before An iterator before which
368  
        the segment is inserted. This may
368  
        the segment is inserted. This may
369  
        be equal to `end()`.
369  
        be equal to `end()`.
370  

370  

371  
        @param s The segment to insert.
371  
        @param s The segment to insert.
372  
    */
372  
    */
373  
    BOOST_URL_DECL
373  
    BOOST_URL_DECL
374  
    iterator
374  
    iterator
375  
    insert(
375  
    insert(
376  
        iterator before,
376  
        iterator before,
377  
        core::string_view s);
377  
        core::string_view s);
378  

378  

379  
    /** Insert segments
379  
    /** Insert segments
380  

380  

381  
        This function inserts the segments
381  
        This function inserts the segments
382  
        in an initializer list before the
382  
        in an initializer list before the
383  
        specified position.
383  
        specified position.
384  
        Reserved characters in the list are
384  
        Reserved characters in the list are
385  
        percent-escaped in the result.
385  
        percent-escaped in the result.
386  

386  

387  
        <br>
387  
        <br>
388  
        All iterators that are equal to
388  
        All iterators that are equal to
389  
        `before` or come after are invalidated.
389  
        `before` or come after are invalidated.
390  

390  

391  
        @note
391  
        @note
392  
        None of the character buffers referenced
392  
        None of the character buffers referenced
393  
        by the list may overlap the character
393  
        by the list may overlap the character
394  
        buffer of the underlying url, or else
394  
        buffer of the underlying url, or else
395  
        the behavior is undefined.
395  
        the behavior is undefined.
396  

396  

397  
        @par Example
397  
        @par Example
398  
        @code
398  
        @code
399  
        url u( "/file.txt" );
399  
        url u( "/file.txt" );
400  

400  

401  
        u.segments().insert( u.segments().begin(), { "path", "to" } );
401  
        u.segments().insert( u.segments().begin(), { "path", "to" } );
402  
        @endcode
402  
        @endcode
403  

403  

404  
        @par Complexity
404  
        @par Complexity
405  
        Linear in `init.size() + this->url().encoded_resource().size()`.
405  
        Linear in `init.size() + this->url().encoded_resource().size()`.
406  

406  

407  
        @par Exception Safety
407  
        @par Exception Safety
408  
        Strong guarantee.
408  
        Strong guarantee.
409  
        Calls to allocate may throw.
409  
        Calls to allocate may throw.
410  

410  

411  
        @return An iterator to the first
411  
        @return An iterator to the first
412  
        element inserted, or `before` if
412  
        element inserted, or `before` if
413  
        `init.size() == 0`.
413  
        `init.size() == 0`.
414  

414  

415  
        @param before An iterator before which
415  
        @param before An iterator before which
416  
        the list is inserted. This may
416  
        the list is inserted. This may
417  
        be equal to `end()`.
417  
        be equal to `end()`.
418  

418  

419  
        @param init The list of segments to insert.
419  
        @param init The list of segments to insert.
420  
    */
420  
    */
421  
    BOOST_URL_DECL
421  
    BOOST_URL_DECL
422  
    iterator
422  
    iterator
423  
    insert(
423  
    insert(
424  
        iterator before,
424  
        iterator before,
425  
        std::initializer_list<core::string_view> init);
425  
        std::initializer_list<core::string_view> init);
426  

426  

427  
    /** Insert segments
427  
    /** Insert segments
428  

428  

429  
        This function inserts the segments in
429  
        This function inserts the segments in
430  
        a range before the specified position.
430  
        a range before the specified position.
431  
        Reserved characters in the list are
431  
        Reserved characters in the list are
432  
        automatically escaped.
432  
        automatically escaped.
433  

433  

434  
        <br>
434  
        <br>
435  
        All iterators that are equal to
435  
        All iterators that are equal to
436  
        `before` or come after are invalidated.
436  
        `before` or come after are invalidated.
437  

437  

438  
        @note
438  
        @note
439  
        None of the character buffers referenced
439  
        None of the character buffers referenced
440  
        by the range may overlap the character
440  
        by the range may overlap the character
441  
        buffer of the underlying url, or else
441  
        buffer of the underlying url, or else
442  
        the behavior is undefined.
442  
        the behavior is undefined.
443  

443  

444  
        @par Mandates
444  
        @par Mandates
445  
        @code
445  
        @code
446  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
446  
        std::is_convertible< std::iterator_traits< FwdIt >::reference_type, core::string_view >::value == true
447  
        @endcode
447  
        @endcode
448  

448  

449  
        @par Complexity
449  
        @par Complexity
450  
        Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
450  
        Linear in `std::distance( first, last ) + this->url().encoded_resource().size()`.
451  

451  

452  
        @par Exception Safety
452  
        @par Exception Safety
453  
        Strong guarantee.
453  
        Strong guarantee.
454  
        Calls to allocate may throw.
454  
        Calls to allocate may throw.
455  

455  

456  
        @return An iterator to the first
456  
        @return An iterator to the first
457  
        segment inserted, or `before` if
457  
        segment inserted, or `before` if
458  
        `init.empty()`.
458  
        `init.empty()`.
459  

459  

460  
        @param before An iterator before which
460  
        @param before An iterator before which
461  
        the range is inserted. This may
461  
        the range is inserted. This may
462  
        be equal to `end()`.
462  
        be equal to `end()`.
463  

463  

464  
        @param first The beginning of the range of segments to insert.
464  
        @param first The beginning of the range of segments to insert.
465  
        @param last The end of the range of segments to insert.
465  
        @param last The end of the range of segments to insert.
466  
    */
466  
    */
467  
    template<class FwdIt>
467  
    template<class FwdIt>
468  
    iterator
468  
    iterator
469  
    insert(
469  
    insert(
470  
        iterator before,
470  
        iterator before,
471  
        FwdIt first,
471  
        FwdIt first,
472  
        FwdIt last);
472  
        FwdIt last);
473  

473  

474  
    //--------------------------------------------
474  
    //--------------------------------------------
475  

475  

476  
    /** Erase segments
476  
    /** Erase segments
477  

477  

478  
        This function removes a segment.
478  
        This function removes a segment.
479  

479  

480  
        <br>
480  
        <br>
481  
        All iterators that are equal to
481  
        All iterators that are equal to
482  
        `pos` or come after are invalidated.
482  
        `pos` or come after are invalidated.
483  

483  

484  
        @par Complexity
484  
        @par Complexity
485  
        Linear in `this->url().encoded_resource().size()`.
485  
        Linear in `this->url().encoded_resource().size()`.
486  

486  

487  
        @par Exception Safety
487  
        @par Exception Safety
488  
        Throws nothing.
488  
        Throws nothing.
489  

489  

490  
        @return An iterator to one past
490  
        @return An iterator to one past
491  
        the removed segment.
491  
        the removed segment.
492  

492  

493  
        @param pos An iterator to the segment.
493  
        @param pos An iterator to the segment.
494  
    */
494  
    */
495  
    iterator
495  
    iterator
496  
    erase(
496  
    erase(
497  
        iterator pos) noexcept;
497  
        iterator pos) noexcept;
498  

498  

499  
    /** Erase segments
499  
    /** Erase segments
500  

500  

501  
        This function removes a range of segments.
501  
        This function removes a range of segments.
502  

502  

503  
        <br>
503  
        <br>
504  
        All iterators that are equal to
504  
        All iterators that are equal to
505  
        `first` or come after are invalidated.
505  
        `first` or come after are invalidated.
506  

506  

507  
        @par Complexity
507  
        @par Complexity
508  
        Linear in `this->url().encoded_resource().size()`.
508  
        Linear in `this->url().encoded_resource().size()`.
509  

509  

510  
        @par Exception Safety
510  
        @par Exception Safety
511  
        Throws nothing.
511  
        Throws nothing.
512  

512  

513  
        @return An iterator to one past
513  
        @return An iterator to one past
514  
        the removed range.
514  
        the removed range.
515  

515  

516  
        @param first The beginning of the range to remove.
516  
        @param first The beginning of the range to remove.
517  
        @param last The end of the range to remove.
517  
        @param last The end of the range to remove.
518  
    */
518  
    */
519  
    BOOST_URL_DECL
519  
    BOOST_URL_DECL
520  
    iterator
520  
    iterator
521  
    erase(
521  
    erase(
522  
        iterator first,
522  
        iterator first,
523  
        iterator last) noexcept;
523  
        iterator last) noexcept;
524  

524  

525  
    //--------------------------------------------
525  
    //--------------------------------------------
526  

526  

527  
    /** Replace segments
527  
    /** Replace segments
528  

528  

529  
        This function replaces the segment at
529  
        This function replaces the segment at
530  
        the specified position.
530  
        the specified position.
531  
        Reserved characters in the string are
531  
        Reserved characters in the string are
532  
        automatically escaped.
532  
        automatically escaped.
533  

533  

534  
        <br>
534  
        <br>
535  
        All iterators that are equal to
535  
        All iterators that are equal to
536  
        `pos` or come after are invalidated.
536  
        `pos` or come after are invalidated.
537  

537  

538  
        @par Complexity
538  
        @par Complexity
539  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
539  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
540  

540  

541  
        @par Exception Safety
541  
        @par Exception Safety
542  
        Strong guarantee.
542  
        Strong guarantee.
543  
        Calls to allocate may throw.
543  
        Calls to allocate may throw.
544  

544  

545  
        @return An iterator to the replaced segment.
545  
        @return An iterator to the replaced segment.
546  

546  

547  
        @param pos An iterator to the segment.
547  
        @param pos An iterator to the segment.
548  

548  

549  
        @param s The string to assign.
549  
        @param s The string to assign.
550  
    */
550  
    */
551  
    BOOST_URL_DECL
551  
    BOOST_URL_DECL
552  
    iterator
552  
    iterator
553  
    replace(
553  
    replace(
554  
        iterator pos,
554  
        iterator pos,
555  
        core::string_view s);
555  
        core::string_view s);
556  

556  

557  
    /** Replace segments
557  
    /** Replace segments
558  

558  

559  
        This function replaces a range of
559  
        This function replaces a range of
560  
        segments with one segment.
560  
        segments with one segment.
561  
        Reserved characters in the string are
561  
        Reserved characters in the string are
562  
        automatically escaped.
562  
        automatically escaped.
563  

563  

564  
        <br>
564  
        <br>
565  
        All iterators that are equal to
565  
        All iterators that are equal to
566  
        `from` or come after are invalidated.
566  
        `from` or come after are invalidated.
567  

567  

568  
        @par Complexity
568  
        @par Complexity
569  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
569  
        Linear in `s.size() + this->url().encoded_resouce().size()`.
570  

570  

571  
        @par Exception Safety
571  
        @par Exception Safety
572  
        Strong guarantee.
572  
        Strong guarantee.
573  
        Calls to allocate may throw.
573  
        Calls to allocate may throw.
574  

574  

575  
        @return An iterator to the new segment.
575  
        @return An iterator to the new segment.
576  

576  

577  
        @param from The beginning of the range of segments to replace.
577  
        @param from The beginning of the range of segments to replace.
578  
        @param to The end of the range of segments to replace.
578  
        @param to The end of the range of segments to replace.
579  

579  

580  
        @param s The string to assign.
580  
        @param s The string to assign.
581  
    */
581  
    */
582  
    BOOST_URL_DECL
582  
    BOOST_URL_DECL
583  
    iterator
583  
    iterator
584  
    replace(
584  
    replace(
585  
        iterator from,
585  
        iterator from,
586  
        iterator to,
586  
        iterator to,
587  
        core::string_view s);
587  
        core::string_view s);
588  

588  

589  
    /** Replace segments
589  
    /** Replace segments
590  

590  

591  
        This function replaces a range of
591  
        This function replaces a range of
592  
        segments with a list of segments in
592  
        segments with a list of segments in
593  
        an initializer list.
593  
        an initializer list.
594  
        Reserved characters in the list are
594  
        Reserved characters in the list are
595  
        automatically escaped.
595  
        automatically escaped.
596  

596  

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

600  

601  
        @par Preconditions
601  
        @par Preconditions
602  
        None of the character buffers referenced
602  
        None of the character buffers referenced
603  
        by the list may overlap the character
603  
        by the list may overlap the character
604  
        buffer of the underlying url, or else
604  
        buffer of the underlying url, or else
605  
        the behavior is undefined.
605  
        the behavior is undefined.
606  

606  

607  
        @par Complexity
607  
        @par Complexity
608  
        Linear in `init.size() + this->url().encoded_resouce().size()`.
608  
        Linear in `init.size() + this->url().encoded_resouce().size()`.
609  

609  

610  
        @par Exception Safety
610  
        @par Exception Safety
611  
        Strong guarantee.
611  
        Strong guarantee.
612  
        Calls to allocate may throw.
612  
        Calls to allocate may throw.
613  

613  

614  
        @return An iterator to the first
614  
        @return An iterator to the first
615  
        segment inserted, or one past `to` if
615  
        segment inserted, or one past `to` if
616  
        `init.size() == 0`.
616  
        `init.size() == 0`.
617  

617  

618  
        @param from The beginning of the range of segments to replace.
618  
        @param from The beginning of the range of segments to replace.
619  
        @param to The end of the range of segments to replace.
619  
        @param to The end of the range of segments to replace.
620  

620  

621  
        @param init The list of segments to assign.
621  
        @param init The list of segments to assign.
622  
    */
622  
    */
623  
    BOOST_URL_DECL
623  
    BOOST_URL_DECL
624  
    iterator
624  
    iterator
625  
    replace(
625  
    replace(
626  
        iterator from,
626  
        iterator from,
627  
        iterator to,
627  
        iterator to,
628  
        std::initializer_list<
628  
        std::initializer_list<
629  
            core::string_view> init);
629  
            core::string_view> init);
630  

630  

631  
    /** Replace segments
631  
    /** Replace segments
632  

632  

633  
        This function replaces a range of
633  
        This function replaces a range of
634  
        segments with annother range of segments.
634  
        segments with annother range of segments.
635  
        Reserved characters in the new range are
635  
        Reserved characters in the new range are
636  
        automatically escaped.
636  
        automatically escaped.
637  

637  

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

641  

642  
        @par Preconditions
642  
        @par Preconditions
643  
        None of the character buffers referenced
643  
        None of the character buffers referenced
644  
        by the new range may overlap the character
644  
        by the new range may overlap the character
645  
        buffer of the underlying url, or else
645  
        buffer of the underlying url, or else
646  
        the behavior is undefined.
646  
        the behavior is undefined.
647  

647  

648  
        @par Complexity
648  
        @par Complexity
649  
        Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
649  
        Linear in `std::distance( first, last ) + this->url().encoded_resouce().size()`.
650  

650  

651  
        @par Exception Safety
651  
        @par Exception Safety
652  
        Strong guarantee.
652  
        Strong guarantee.
653  
        Calls to allocate may throw.
653  
        Calls to allocate may throw.
654  

654  

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

658  

659  
        @param from The beginning of the range of segments to replace.
659  
        @param from The beginning of the range of segments to replace.
660  
        @param to The end of the range of segments to replace.
660  
        @param to The end of the range of segments to replace.
661  
        @param first The beginning of the range of segments to assign.
661  
        @param first The beginning of the range of segments to assign.
662  
        @param last The end of the range of segments to assign.
662  
        @param last The end of the range of segments to assign.
663  
    */
663  
    */
664  
    template<class FwdIt>
664  
    template<class FwdIt>
665  
    iterator
665  
    iterator
666  
    replace(
666  
    replace(
667  
        iterator from,
667  
        iterator from,
668  
        iterator to,
668  
        iterator to,
669  
        FwdIt first,
669  
        FwdIt first,
670  
        FwdIt last);
670  
        FwdIt last);
671  

671  

672  
    /** Append a segment
672  
    /** Append a segment
673  

673  

674  
        This function appends a segment to
674  
        This function appends a segment to
675  
        the end of the path.
675  
        the end of the path.
676  
        Reserved characters in the string are
676  
        Reserved characters in the string are
677  
        automatically escaped.
677  
        automatically escaped.
678  

678  

679  
        <br>
679  
        <br>
680  
        All end iterators are invalidated.
680  
        All end iterators are invalidated.
681  

681  

682  
        @par Postconditions
682  
        @par Postconditions
683  
        @code
683  
        @code
684  
        this->back() == s
684  
        this->back() == s
685  
        @endcode
685  
        @endcode
686  

686  

687  
        @par Exception Safety
687  
        @par Exception Safety
688  
        Strong guarantee.
688  
        Strong guarantee.
689  
        Calls to allocate may throw.
689  
        Calls to allocate may throw.
690  

690  

691  
        @param s The segment to append.
691  
        @param s The segment to append.
692  
    */
692  
    */
693  
    void
693  
    void
694  
    push_back(
694  
    push_back(
695  
        core::string_view s);
695  
        core::string_view s);
696  

696  

697  
    /** Remove the last segment
697  
    /** Remove the last segment
698  

698  

699  
        This function removes the last segment
699  
        This function removes the last segment
700  
        from the container.
700  
        from the container.
701  

701  

702  
        <br>
702  
        <br>
703  
        Iterators to the last segment as well
703  
        Iterators to the last segment as well
704  
        as all end iterators are invalidated.
704  
        as all end iterators are invalidated.
705  

705  

706  
        @par Preconditions
706  
        @par Preconditions
707  
        @code
707  
        @code
708  
        not this->empty()
708  
        not this->empty()
709  
        @endcode
709  
        @endcode
710  

710  

711  
        @par Exception Safety
711  
        @par Exception Safety
712  
        Throws nothing.
712  
        Throws nothing.
713  
    */
713  
    */
714  
    void
714  
    void
715  
    pop_back() noexcept;
715  
    pop_back() noexcept;
716  

716  

717  
private:
717  
private:
718  
    template<class FwdIt>
718  
    template<class FwdIt>
719  
    iterator
719  
    iterator
720  
    insert(
720  
    insert(
721  
        iterator before,
721  
        iterator before,
722  
        FwdIt first,
722  
        FwdIt first,
723  
        FwdIt last,
723  
        FwdIt last,
724  
        std::input_iterator_tag) = delete;
724  
        std::input_iterator_tag) = delete;
725  

725  

726  
    template<class FwdIt>
726  
    template<class FwdIt>
727  
    iterator
727  
    iterator
728  
    insert(
728  
    insert(
729  
        iterator before,
729  
        iterator before,
730  
        FwdIt first,
730  
        FwdIt first,
731  
        FwdIt last,
731  
        FwdIt last,
732  
        std::forward_iterator_tag);
732  
        std::forward_iterator_tag);
733  
};
733  
};
734  

734  

735  
} // urls
735  
} // urls
736  
} // boost
736  
} // boost
737  

737  

738  
// This include is at the bottom of
738  
// This include is at the bottom of
739  
// url_base.hpp because of a circular dependency
739  
// url_base.hpp because of a circular dependency
740  
//
740  
//
741  
// #include <boost/url/impl/segments_ref.hpp>
741  
// #include <boost/url/impl/segments_ref.hpp>
742  

742  

743  
//------------------------------------------------
743  
//------------------------------------------------
744  
//
744  
//
745  
// std::ranges::enable_borrowed_range
745  
// std::ranges::enable_borrowed_range
746  
//
746  
//
747  
//------------------------------------------------
747  
//------------------------------------------------
748  

748  

749  
#ifdef BOOST_URL_HAS_CONCEPTS
749  
#ifdef BOOST_URL_HAS_CONCEPTS
750  
#include <ranges>
750  
#include <ranges>
751  
namespace std::ranges {
751  
namespace std::ranges {
752  
    template<>
752  
    template<>
753  
    inline constexpr bool
753  
    inline constexpr bool
754  
        enable_borrowed_range<
754  
        enable_borrowed_range<
755  
            boost::urls::segments_ref> = true;
755  
            boost::urls::segments_ref> = true;
756  
} // std::ranges
756  
} // std::ranges
757  
#endif
757  
#endif
758  

758  

759  
#endif
759  
#endif