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 BOOST_URL_DECL 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 -
    BOOST_URL_DECL
 
148  
    */
147  
    */
149  
    segments_ref&
148  
    segments_ref&
150  
    operator=(segments_ref const& other);
149  
    operator=(segments_ref const& other);
151  

150  

152 -
    BOOST_URL_DECL
 
153  
    /// @copydoc segments_ref::operator=(segments_ref const&)
151  
    /// @copydoc segments_ref::operator=(segments_ref const&)
154  
    segments_ref&
152  
    segments_ref&
155  
    operator=(segments_view const& other);
153  
    operator=(segments_view const& other);
156  

154  

157  
    /** Assignment
155  
    /** Assignment
158  

156  

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

162  

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

165  

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

169  

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

172  

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

178  

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

183  

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

186  

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

190  

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

197  

201  
    /** Conversion
198  
    /** Conversion
202  

199  

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

202  

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

207  

212  
    //--------------------------------------------
208  
    //--------------------------------------------
213  
    //
209  
    //
214  
    // Observers
210  
    // Observers
215  
    //
211  
    //
216  
    //--------------------------------------------
212  
    //--------------------------------------------
217  

213  

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

215  

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

218  

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

222  

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

225  

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

228  

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

236  

241  
    //--------------------------------------------
237  
    //--------------------------------------------
242  
    //
238  
    //
243  
    // Modifiers
239  
    // Modifiers
244  
    //
240  
    //
245  
    //--------------------------------------------
241  
    //--------------------------------------------
246  

242  

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

244  

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

247  

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

252  

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

257  

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

260  

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

266  

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

268  

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

274  

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

277  

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

283  

288  
        @par Example
284  
        @par Example
289  
        @code
285  
        @code
290  
        url u;
286  
        url u;
291  

287  

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

290  

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

293  

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

297  

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

303  

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

305  

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

310  

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

313  

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

319  

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

324  

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

327  

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

331  

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

338  

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

340  

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

342  

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

347  

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

351  

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

354  

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

358  

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

361  

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

365  

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

372  

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

374  

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

380  

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

384  

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

390  

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

394  

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

397  

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

400  

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

404  

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

408  

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

412  

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

419  

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

421  

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

426  

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

430  

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

436  

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

441  

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

444  

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

448  

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

452  

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

456  

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

466  

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

468  

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

470  

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

472  

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

476  

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

479  

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

482  

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

485  

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

491  

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

493  

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

495  

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

499  

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

502  

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

505  

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

508  

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

516  

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

518  

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

520  

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

525  

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

529  

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

532  

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

536  

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

538  

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

540  

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

547  

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

549  

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

554  

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

558  

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

561  

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

565  

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

567  

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

570  

580  
        @param s The string to assign.
571  
        @param s The string to assign.
581 -
    BOOST_URL_DECL
 
582  
    */
572  
    */
583  
    iterator
573  
    iterator
584  
    replace(
574  
    replace(
585  
        iterator from,
575  
        iterator from,
586  
        iterator to,
576  
        iterator to,
587  
        core::string_view s);
577  
        core::string_view s);
588  

578  

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

580  

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

586  

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

590  

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

596  

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

599  

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

603  

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

607  

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

610  

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

619  

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

621  

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

626  

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

630  

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

636  

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

639  

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

643  

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

647  

659  
        @param from The beginning of the range of segments to replace.
648  
        @param from The beginning of the range of segments to replace.
660  
        @param to The end of the range of segments to replace.
649  
        @param to The end of the range of segments to replace.
661  
        @param first The beginning of the range of segments to assign.
650  
        @param first The beginning of the range of segments to assign.
662  
        @param last The end of the range of segments to assign.
651  
        @param last The end of the range of segments to assign.
663  
    */
652  
    */
664  
    template<class FwdIt>
653  
    template<class FwdIt>
665  
    iterator
654  
    iterator
666  
    replace(
655  
    replace(
667  
        iterator from,
656  
        iterator from,
668  
        iterator to,
657  
        iterator to,
669  
        FwdIt first,
658  
        FwdIt first,
670  
        FwdIt last);
659  
        FwdIt last);
671  

660  

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

662  

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

667  

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

670  

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

675  

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

679  

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

685  

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

687  

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

690  

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

694  

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

699  

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

705  

717  
private:
706  
private:
718  
    template<class FwdIt>
707  
    template<class FwdIt>
719  
    iterator
708  
    iterator
720  
    insert(
709  
    insert(
721  
        iterator before,
710  
        iterator before,
722  
        FwdIt first,
711  
        FwdIt first,
723  
        FwdIt last,
712  
        FwdIt last,
724  
        std::input_iterator_tag) = delete;
713  
        std::input_iterator_tag) = delete;
725  

714  

726  
    template<class FwdIt>
715  
    template<class FwdIt>
727  
    iterator
716  
    iterator
728  
    insert(
717  
    insert(
729  
        iterator before,
718  
        iterator before,
730  
        FwdIt first,
719  
        FwdIt first,
731  
        FwdIt last,
720  
        FwdIt last,
732  
        std::forward_iterator_tag);
721  
        std::forward_iterator_tag);
733  
};
722  
};
734  

723  

735  
} // urls
724  
} // urls
736  
} // boost
725  
} // boost
737  

726  

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

731  

743  
//------------------------------------------------
732  
//------------------------------------------------
744  
//
733  
//
745  
// std::ranges::enable_borrowed_range
734  
// std::ranges::enable_borrowed_range
746  
//
735  
//
747  
//------------------------------------------------
736  
//------------------------------------------------
748  

737  

749  
#ifdef BOOST_URL_HAS_CONCEPTS
738  
#ifdef BOOST_URL_HAS_CONCEPTS
750  
#include <ranges>
739  
#include <ranges>
751  
namespace std::ranges {
740  
namespace std::ranges {
752  
    template<>
741  
    template<>
753  
    inline constexpr bool
742  
    inline constexpr bool
754  
        enable_borrowed_range<
743  
        enable_borrowed_range<
755  
            boost::urls::segments_ref> = true;
744  
            boost::urls::segments_ref> = true;
756  
} // std::ranges
745  
} // std::ranges
757  
#endif
746  
#endif
758  

747  

759  
#endif
748  
#endif