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_IMPL_SEGMENTS_REF_HPP
11  
#ifndef BOOST_URL_IMPL_SEGMENTS_REF_HPP
12  
#define BOOST_URL_IMPL_SEGMENTS_REF_HPP
12  
#define BOOST_URL_IMPL_SEGMENTS_REF_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/detail/any_segments_iter.hpp>
15  
#include <boost/url/detail/any_segments_iter.hpp>
16  
#include <boost/url/detail/segments_iter_impl.hpp>
16  
#include <boost/url/detail/segments_iter_impl.hpp>
17  
#include <boost/url/detail/path.hpp>
17  
#include <boost/url/detail/path.hpp>
18  
#include <type_traits>
18  
#include <type_traits>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace urls {
21  
namespace urls {
22  

22  

23  
//------------------------------------------------
23  
//------------------------------------------------
24  
//
24  
//
25  
// Modifiers
25  
// Modifiers
26  
//
26  
//
27  
//------------------------------------------------
27  
//------------------------------------------------
28  

28  

29  
template<class FwdIt>
29  
template<class FwdIt>
30  
void
30  
void
31  
segments_ref::
31  
segments_ref::
32  
assign(FwdIt first, FwdIt last)
32  
assign(FwdIt first, FwdIt last)
33  
{
33  
{
34  
/*  If you get a compile error here, it
34  
/*  If you get a compile error here, it
35  
    means that the iterators you passed
35  
    means that the iterators you passed
36  
    do not meet the requirements stated
36  
    do not meet the requirements stated
37  
    in the documentation.
37  
    in the documentation.
38  
*/
38  
*/
39  
    static_assert(
39  
    static_assert(
40  
        std::is_convertible<
40  
        std::is_convertible<
41  
            typename std::iterator_traits<
41  
            typename std::iterator_traits<
42  
                FwdIt>::reference,
42  
                FwdIt>::reference,
43  
            core::string_view>::value,
43  
            core::string_view>::value,
44  
        "Type requirements not met");
44  
        "Type requirements not met");
45  

45  

46  
    u_->edit_segments(
46  
    u_->edit_segments(
47  
        begin().it_,
47  
        begin().it_,
48  
        end().it_,
48  
        end().it_,
49  
        detail::make_segments_iter(
49  
        detail::make_segments_iter(
50  
            first, last));
50  
            first, last));
51  
}
51  
}
52  

52  

53  
template<class FwdIt>
53  
template<class FwdIt>
54  
auto
54  
auto
55  
segments_ref::
55  
segments_ref::
56  
insert(
56  
insert(
57  
    iterator before,
57  
    iterator before,
58  
    FwdIt first,
58  
    FwdIt first,
59  
    FwdIt last) ->
59  
    FwdIt last) ->
60  
        iterator
60  
        iterator
61  
{
61  
{
62  
/*  If you get a compile error here, it
62  
/*  If you get a compile error here, it
63  
    means that the iterators you passed
63  
    means that the iterators you passed
64  
    do not meet the requirements stated
64  
    do not meet the requirements stated
65  
    in the documentation.
65  
    in the documentation.
66  
*/
66  
*/
67  
    static_assert(
67  
    static_assert(
68  
        std::is_convertible<
68  
        std::is_convertible<
69  
            typename std::iterator_traits<
69  
            typename std::iterator_traits<
70  
                FwdIt>::reference,
70  
                FwdIt>::reference,
71  
            core::string_view>::value,
71  
            core::string_view>::value,
72  
        "Type requirements not met");
72  
        "Type requirements not met");
73  

73  

74  
    return insert(
74  
    return insert(
75  
        before,
75  
        before,
76  
        first,
76  
        first,
77  
        last,
77  
        last,
78  
        typename std::iterator_traits<
78  
        typename std::iterator_traits<
79  
            FwdIt>::iterator_category{});
79  
            FwdIt>::iterator_category{});
80  
}
80  
}
81  

81  

82  
template<class FwdIt>
82  
template<class FwdIt>
83  
auto
83  
auto
84  
segments_ref::
84  
segments_ref::
85  
replace(
85  
replace(
86  
    iterator from,
86  
    iterator from,
87  
    iterator to,
87  
    iterator to,
88  
    FwdIt first,
88  
    FwdIt first,
89  
    FwdIt last) ->
89  
    FwdIt last) ->
90  
        iterator
90  
        iterator
91  
{
91  
{
92  
/*  If you get a compile error here, it
92  
/*  If you get a compile error here, it
93  
    means that the iterators you passed
93  
    means that the iterators you passed
94  
    do not meet the requirements stated
94  
    do not meet the requirements stated
95  
    in the documentation.
95  
    in the documentation.
96  
*/
96  
*/
97  
    static_assert(
97  
    static_assert(
98  
        std::is_convertible<
98  
        std::is_convertible<
99  
            typename std::iterator_traits<
99  
            typename std::iterator_traits<
100  
                FwdIt>::reference,
100  
                FwdIt>::reference,
101  
            core::string_view>::value,
101  
            core::string_view>::value,
102  
        "Type requirements not met");
102  
        "Type requirements not met");
103  

103  

104  
    return u_->edit_segments(
104  
    return u_->edit_segments(
105  
        from.it_,
105  
        from.it_,
106  
        to.it_,
106  
        to.it_,
107  
        detail::make_segments_iter(
107  
        detail::make_segments_iter(
108  
            first, last));
108  
            first, last));
109  
}
109  
}
110  

110  

111  
//------------------------------------------------
111  
//------------------------------------------------
112  

112  

113  
template<class FwdIt>
113  
template<class FwdIt>
114  
auto
114  
auto
115  
segments_ref::
115  
segments_ref::
116  
insert(
116  
insert(
117  
    iterator before,
117  
    iterator before,
118  
    FwdIt first,
118  
    FwdIt first,
119  
    FwdIt last,
119  
    FwdIt last,
120  
    std::forward_iterator_tag) ->
120  
    std::forward_iterator_tag) ->
121  
        iterator
121  
        iterator
122  
{
122  
{
123  
    return u_->edit_segments(
123  
    return u_->edit_segments(
124  
        before.it_,
124  
        before.it_,
125  
        before.it_,
125  
        before.it_,
126  
        detail::make_segments_iter(
126  
        detail::make_segments_iter(
127  
            first, last));
127  
            first, last));
128  
}
128  
}
129  

129  

130  
//------------------------------------------------
130  
//------------------------------------------------
131  
//
131  
//
132  
// Special Members
132  
// Special Members
133  
//
133  
//
134  
//------------------------------------------------
134  
//------------------------------------------------
135  

135  

136  
inline
136  
inline
137  
segments_ref::
137  
segments_ref::
138  
segments_ref(
138  
segments_ref(
139  
    url_base& u) noexcept
139  
    url_base& u) noexcept
140  
    : segments_base(
140  
    : segments_base(
141  
        detail::path_ref(u.impl_))
141  
        detail::path_ref(u.impl_))
142  
    , u_(&u)
142  
    , u_(&u)
143  
{
143  
{
144  
}
144  
}
145  

145  

146  
inline
146  
inline
147  
segments_ref::
147  
segments_ref::
148  
operator
148  
operator
149  
segments_view() const noexcept
149  
segments_view() const noexcept
150  
{
150  
{
151  
    return segments_view(ref_);
151  
    return segments_view(ref_);
152  
}
152  
}
153  

153  

154  
inline
154  
inline
155  
segments_ref&
155  
segments_ref&
156  
segments_ref::
156  
segments_ref::
157  
operator=(segments_ref const& other)
157  
operator=(segments_ref const& other)
158  
{
158  
{
159  
    if (!ref_.alias_of(other.ref_))
159  
    if (!ref_.alias_of(other.ref_))
160  
        assign(other.begin(), other.end());
160  
        assign(other.begin(), other.end());
161  
    return *this;
161  
    return *this;
162  
}
162  
}
163  

163  

164  
inline
164  
inline
165  
segments_ref&
165  
segments_ref&
166  
segments_ref::
166  
segments_ref::
167  
operator=(segments_view const& other)
167  
operator=(segments_view const& other)
168  
{
168  
{
169  
    assign(other.begin(), other.end());
169  
    assign(other.begin(), other.end());
170  
    return *this;
170  
    return *this;
171  
}
171  
}
172  

172  

173  
inline
173  
inline
174  
segments_ref&
174  
segments_ref&
175  
segments_ref::
175  
segments_ref::
176  
operator=(std::initializer_list<
176  
operator=(std::initializer_list<
177  
    core::string_view> init)
177  
    core::string_view> init)
178  
{
178  
{
179  
    assign(init.begin(), init.end());
179  
    assign(init.begin(), init.end());
180  
    return *this;
180  
    return *this;
181  
}
181  
}
182  

182  

183  
//------------------------------------------------
183  
//------------------------------------------------
184  
//
184  
//
185  
// Modifiers
185  
// Modifiers
186  
//
186  
//
187  
//------------------------------------------------
187  
//------------------------------------------------
188  

188  

189  
inline
189  
inline
190  
void
190  
void
191  
segments_ref::
191  
segments_ref::
192  
clear() noexcept
192  
clear() noexcept
193  
{
193  
{
194  
    erase(begin(), end());
194  
    erase(begin(), end());
195  
}
195  
}
196  

196  

197  
inline
197  
inline
198  
void
198  
void
199  
segments_ref::
199  
segments_ref::
200  
assign(std::initializer_list<
200  
assign(std::initializer_list<
201  
    core::string_view> init)
201  
    core::string_view> init)
202  
{
202  
{
203  
    assign(init.begin(), init.end());
203  
    assign(init.begin(), init.end());
204  
}
204  
}
205  

205  

206  
inline
206  
inline
207  
auto
207  
auto
208  
segments_ref::
208  
segments_ref::
209  
insert(
209  
insert(
210  
    iterator before,
210  
    iterator before,
211  
    core::string_view s) ->
211  
    core::string_view s) ->
212  
        iterator
212  
        iterator
213  
{
213  
{
214  
    return u_->edit_segments(
214  
    return u_->edit_segments(
215  
        before.it_,
215  
        before.it_,
216  
        before.it_,
216  
        before.it_,
217  
        detail::segment_iter(s));
217  
        detail::segment_iter(s));
218  
}
218  
}
219  

219  

220  
inline
220  
inline
221  
auto
221  
auto
222  
segments_ref::
222  
segments_ref::
223  
insert(
223  
insert(
224  
    iterator before,
224  
    iterator before,
225  
    std::initializer_list<
225  
    std::initializer_list<
226  
            core::string_view> init) ->
226  
            core::string_view> init) ->
227  
        iterator
227  
        iterator
228  
{
228  
{
229  
    return insert(
229  
    return insert(
230  
        before,
230  
        before,
231  
        init.begin(),
231  
        init.begin(),
232  
        init.end());
232  
        init.end());
233  
}
233  
}
234  

234  

235  
inline
235  
inline
236  
auto
236  
auto
237  
segments_ref::
237  
segments_ref::
238  
erase(
238  
erase(
239  
    iterator first,
239  
    iterator first,
240  
    iterator last) noexcept ->
240  
    iterator last) noexcept ->
241  
        iterator
241  
        iterator
242  
{
242  
{
243  
    core::string_view s;
243  
    core::string_view s;
244  
    return u_->edit_segments(
244  
    return u_->edit_segments(
245  
        first.it_,
245  
        first.it_,
246  
        last.it_,
246  
        last.it_,
247  
        detail::make_segments_encoded_iter(
247  
        detail::make_segments_encoded_iter(
248  
            &s, &s));
248  
            &s, &s));
249  
}
249  
}
250  

250  

251  
inline
251  
inline
252  
auto
252  
auto
253  
segments_ref::
253  
segments_ref::
254  
replace(
254  
replace(
255  
    iterator pos,
255  
    iterator pos,
256  
    core::string_view s) ->
256  
    core::string_view s) ->
257  
        iterator
257  
        iterator
258  
{
258  
{
259  
    return u_->edit_segments(
259  
    return u_->edit_segments(
260  
        pos.it_,
260  
        pos.it_,
261  
        std::next(pos).it_,
261  
        std::next(pos).it_,
262  
        detail::segment_iter(s));
262  
        detail::segment_iter(s));
263  
}
263  
}
264  

264  

265  
inline
265  
inline
266  
auto
266  
auto
267  
segments_ref::
267  
segments_ref::
268  
replace(
268  
replace(
269  
    iterator from,
269  
    iterator from,
270  
    iterator to,
270  
    iterator to,
271  
    core::string_view s) ->
271  
    core::string_view s) ->
272  
        iterator
272  
        iterator
273  
{
273  
{
274  
    return u_->edit_segments(
274  
    return u_->edit_segments(
275  
        from.it_,
275  
        from.it_,
276  
        to.it_,
276  
        to.it_,
277  
        detail::segment_iter(s));
277  
        detail::segment_iter(s));
278  
}
278  
}
279  

279  

280  
inline
280  
inline
281  
auto
281  
auto
282  
segments_ref::
282  
segments_ref::
283  
replace(
283  
replace(
284  
    iterator from,
284  
    iterator from,
285  
    iterator to,
285  
    iterator to,
286  
    std::initializer_list<
286  
    std::initializer_list<
287  
        core::string_view> init) ->
287  
        core::string_view> init) ->
288  
    iterator
288  
    iterator
289  
{
289  
{
290  
    return replace(
290  
    return replace(
291  
        from,
291  
        from,
292  
        to,
292  
        to,
293  
        init.begin(),
293  
        init.begin(),
294  
        init.end());
294  
        init.end());
295  
}
295  
}
296  

296  

297  
inline
297  
inline
298  
auto
298  
auto
299  
segments_ref::
299  
segments_ref::
300  
erase(
300  
erase(
301  
    iterator pos) noexcept ->
301  
    iterator pos) noexcept ->
302  
        iterator
302  
        iterator
303  
{
303  
{
304  
    return erase(pos, std::next(pos));
304  
    return erase(pos, std::next(pos));
305  
}
305  
}
306  

306  

307  
inline
307  
inline
308  
void
308  
void
309  
segments_ref::
309  
segments_ref::
310  
push_back(
310  
push_back(
311  
    core::string_view s)
311  
    core::string_view s)
312  
{
312  
{
313  
    insert(end(), s);
313  
    insert(end(), s);
314  
}
314  
}
315  

315  

316  
inline
316  
inline
317  
void
317  
void
318  
segments_ref::
318  
segments_ref::
319  
pop_back() noexcept
319  
pop_back() noexcept
320  
{
320  
{
321  
    erase(std::prev(end()));
321  
    erase(std::prev(end()));
322  
}
322  
}
323  

323  

324  
} // urls
324  
} // urls
325  
} // boost
325  
} // boost
326  

326  

327  
#endif
327  
#endif