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_ENCODED_BASE_HPP
11  
#ifndef BOOST_URL_IMPL_SEGMENTS_ENCODED_BASE_HPP
12  
#define BOOST_URL_IMPL_SEGMENTS_ENCODED_BASE_HPP
12  
#define BOOST_URL_IMPL_SEGMENTS_ENCODED_BASE_HPP
13  

13  

14  
#include <boost/url/detail/segments_iter_impl.hpp>
14  
#include <boost/url/detail/segments_iter_impl.hpp>
15  
#include <boost/assert.hpp>
15  
#include <boost/assert.hpp>
16  
#include <ostream>
16  
#include <ostream>
17  

17  

18  
namespace boost {
18  
namespace boost {
19  
namespace urls {
19  
namespace urls {
20  
namespace detail {
20  
namespace detail {
21  
struct segments_iter_access;
21  
struct segments_iter_access;
22  
}
22  
}
23  

23  

24  
class segments_encoded_base::iterator
24  
class segments_encoded_base::iterator
25  
{
25  
{
26  
    detail::segments_iter_impl it_;
26  
    detail::segments_iter_impl it_;
27  

27  

28  
    friend class url_base;
28  
    friend class url_base;
29  
    friend class segments_encoded_base;
29  
    friend class segments_encoded_base;
30  
    friend class segments_encoded_ref;
30  
    friend class segments_encoded_ref;
31  
    friend struct detail::segments_iter_access;
31  
    friend struct detail::segments_iter_access;
32  

32  

33  
    iterator(detail::path_ref const&) noexcept;
33  
    iterator(detail::path_ref const&) noexcept;
34  
    iterator(detail::path_ref const&, int) noexcept;
34  
    iterator(detail::path_ref const&, int) noexcept;
35  

35  

36  
    iterator(
36  
    iterator(
37  
        detail::segments_iter_impl const& it) noexcept
37  
        detail::segments_iter_impl const& it) noexcept
38  
        : it_(it)
38  
        : it_(it)
39  
    {
39  
    {
40  
    }
40  
    }
41  

41  

42  
public:
42  
public:
43  
    using value_type =
43  
    using value_type =
44  
        segments_encoded_base::value_type;
44  
        segments_encoded_base::value_type;
45  
    using reference =
45  
    using reference =
46  
        segments_encoded_base::reference;
46  
        segments_encoded_base::reference;
47  
    using pointer = reference;
47  
    using pointer = reference;
48  
    using difference_type = std::ptrdiff_t;
48  
    using difference_type = std::ptrdiff_t;
49  
    using iterator_category =
49  
    using iterator_category =
50  
        std::bidirectional_iterator_tag;
50  
        std::bidirectional_iterator_tag;
51  

51  

52  
    iterator() = default;
52  
    iterator() = default;
53  
    iterator(iterator const&) = default;
53  
    iterator(iterator const&) = default;
54  
    iterator& operator=(
54  
    iterator& operator=(
55  
        iterator const&) = default;
55  
        iterator const&) = default;
56  

56  

57  
    reference
57  
    reference
58  
    operator*() const noexcept
58  
    operator*() const noexcept
59  
    {
59  
    {
60  
        return it_.dereference();
60  
        return it_.dereference();
61  
    }
61  
    }
62  

62  

63  
    pointer
63  
    pointer
64  
    operator->() const noexcept
64  
    operator->() const noexcept
65  
    {
65  
    {
66  
        return it_.dereference();
66  
        return it_.dereference();
67  
    }
67  
    }
68  

68  

69  
    iterator&
69  
    iterator&
70  
    operator++() noexcept
70  
    operator++() noexcept
71  
    {
71  
    {
72  
        it_.increment();
72  
        it_.increment();
73  
        return *this;
73  
        return *this;
74  
    }
74  
    }
75  

75  

76  
    iterator&
76  
    iterator&
77  
    operator--() noexcept
77  
    operator--() noexcept
78  
    {
78  
    {
79  
        it_.decrement();
79  
        it_.decrement();
80  
        return *this;
80  
        return *this;
81  
    }
81  
    }
82  

82  

83  
    iterator
83  
    iterator
84  
    operator++(int) noexcept
84  
    operator++(int) noexcept
85  
    {
85  
    {
86  
        auto tmp = *this;
86  
        auto tmp = *this;
87  
        ++*this;
87  
        ++*this;
88  
        return tmp;
88  
        return tmp;
89  
    }
89  
    }
90  

90  

91  
    iterator
91  
    iterator
92  
    operator--(int) noexcept
92  
    operator--(int) noexcept
93  
    {
93  
    {
94  
        auto tmp = *this;
94  
        auto tmp = *this;
95  
        --*this;
95  
        --*this;
96  
        return tmp;
96  
        return tmp;
97  
    }
97  
    }
98  

98  

99  
    bool
99  
    bool
100  
    operator==(
100  
    operator==(
101  
        iterator const& other) const noexcept
101  
        iterator const& other) const noexcept
102  
    {
102  
    {
103  
        return it_.equal(other.it_);
103  
        return it_.equal(other.it_);
104  
    }
104  
    }
105  

105  

106  
    bool
106  
    bool
107  
    operator!=(
107  
    operator!=(
108  
        iterator const& other) const noexcept
108  
        iterator const& other) const noexcept
109  
    {
109  
    {
110  
        return ! it_.equal(other.it_);
110  
        return ! it_.equal(other.it_);
111  
    }
111  
    }
112  
};
112  
};
113  

113  

114  
//------------------------------------------------
114  
//------------------------------------------------
115  

115  

116  
inline
116  
inline
117  
segments_encoded_base::
117  
segments_encoded_base::
118  
iterator::
118  
iterator::
119  
iterator(
119  
iterator(
120  
    detail::path_ref const& ref) noexcept
120  
    detail::path_ref const& ref) noexcept
121  
    : it_(ref)
121  
    : it_(ref)
122  
{
122  
{
123  
}
123  
}
124  

124  

125  
inline
125  
inline
126  
segments_encoded_base::
126  
segments_encoded_base::
127  
iterator::
127  
iterator::
128  
iterator(
128  
iterator(
129  
    detail::path_ref const& ref,
129  
    detail::path_ref const& ref,
130  
    int) noexcept
130  
    int) noexcept
131  
    : it_(ref, 0)
131  
    : it_(ref, 0)
132  
{
132  
{
133  
}
133  
}
134  

134  

135  
//------------------------------------------------
135  
//------------------------------------------------
136  
//
136  
//
137  
// segments_encoded_base
137  
// segments_encoded_base
138  
//
138  
//
139  
//------------------------------------------------
139  
//------------------------------------------------
140  

140  

141  
inline
141  
inline
142  
segments_encoded_base::
142  
segments_encoded_base::
143  
segments_encoded_base(
143  
segments_encoded_base(
144  
    detail::path_ref const& ref) noexcept
144  
    detail::path_ref const& ref) noexcept
145  
    : ref_(ref)
145  
    : ref_(ref)
146  
{
146  
{
147  
}
147  
}
148  

148  

149  
//------------------------------------------------
149  
//------------------------------------------------
150  
//
150  
//
151  
// Observers
151  
// Observers
152  
//
152  
//
153  
//------------------------------------------------
153  
//------------------------------------------------
154  

154  

155  
inline
155  
inline
156  
pct_string_view
156  
pct_string_view
157  
segments_encoded_base::
157  
segments_encoded_base::
158  
buffer() const noexcept
158  
buffer() const noexcept
159  
{
159  
{
160  
    return ref_.buffer();
160  
    return ref_.buffer();
161  
}
161  
}
162  

162  

163  
inline
163  
inline
164  
bool
164  
bool
165  
segments_encoded_base::
165  
segments_encoded_base::
166  
is_absolute() const noexcept
166  
is_absolute() const noexcept
167  
{
167  
{
168  
    return ref_.buffer().starts_with('/');
168  
    return ref_.buffer().starts_with('/');
169  
}
169  
}
170  

170  

171  
inline
171  
inline
172  
bool
172  
bool
173  
segments_encoded_base::
173  
segments_encoded_base::
174  
empty() const noexcept
174  
empty() const noexcept
175  
{
175  
{
176  
    return ref_.nseg() == 0;
176  
    return ref_.nseg() == 0;
177  
}
177  
}
178  

178  

179  
inline
179  
inline
180  
std::size_t
180  
std::size_t
181  
segments_encoded_base::
181  
segments_encoded_base::
182  
size() const noexcept
182  
size() const noexcept
183  
{
183  
{
184  
    return ref_.nseg();
184  
    return ref_.nseg();
185  
}
185  
}
186  

186  

187  
inline
187  
inline
188  
pct_string_view
188  
pct_string_view
189  
segments_encoded_base::
189  
segments_encoded_base::
190  
front() const noexcept
190  
front() const noexcept
191  
{
191  
{
192  
    BOOST_ASSERT(! empty());
192  
    BOOST_ASSERT(! empty());
193  
    return *begin();
193  
    return *begin();
194  
}
194  
}
195  

195  

196  
inline
196  
inline
197  
pct_string_view
197  
pct_string_view
198  
segments_encoded_base::
198  
segments_encoded_base::
199  
back() const noexcept
199  
back() const noexcept
200  
{
200  
{
201  
    BOOST_ASSERT(! empty());
201  
    BOOST_ASSERT(! empty());
202  
    return *--end();
202  
    return *--end();
203  
}
203  
}
204  

204  

205  
inline
205  
inline
206  
auto
206  
auto
207  
segments_encoded_base::
207  
segments_encoded_base::
208  
begin() const noexcept ->
208  
begin() const noexcept ->
209  
    iterator
209  
    iterator
210  
{
210  
{
211  
    return iterator(ref_);
211  
    return iterator(ref_);
212  
}
212  
}
213  

213  

214  
inline
214  
inline
215  
auto
215  
auto
216  
segments_encoded_base::
216  
segments_encoded_base::
217  
end() const noexcept ->
217  
end() const noexcept ->
218  
    iterator
218  
    iterator
219  
{
219  
{
220  
    return iterator(ref_, 0);
220  
    return iterator(ref_, 0);
221  
}
221  
}
222  

222  

223  
//------------------------------------------------
223  
//------------------------------------------------
224  

224  

225  
inline
225  
inline
226  
std::ostream&
226  
std::ostream&
227  
operator<<(
227  
operator<<(
228  
    std::ostream& os,
228  
    std::ostream& os,
229  
    segments_encoded_base const& ps)
229  
    segments_encoded_base const& ps)
230  
{
230  
{
231  
    os << ps.buffer();
231  
    os << ps.buffer();
232  
    return os;
232  
    return os;
233  
}
233  
}
234  

234  

235  
} // urls
235  
} // urls
236  
} // boost
236  
} // boost
237  

237  

238  
#endif
238  
#endif