TLA Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
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)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 : #ifndef BOOST_URL_IMPL_SEGMENTS_BASE_HPP
12 : #define BOOST_URL_IMPL_SEGMENTS_BASE_HPP
13 :
14 : #include <boost/url/detail/segments_iter_impl.hpp>
15 : #include <boost/url/encoding_opts.hpp>
16 : #include <boost/assert.hpp>
17 : #include <iterator>
18 : #include <ostream>
19 :
20 : namespace boost {
21 : namespace urls {
22 : namespace detail {
23 : struct segments_iter_access;
24 : }
25 :
26 : class segments_base::iterator
27 : {
28 : detail::segments_iter_impl it_;
29 :
30 : friend class segments_base;
31 : friend class segments_ref;
32 : friend struct detail::segments_iter_access;
33 :
34 : iterator(detail::path_ref const&) noexcept;
35 : iterator(detail::path_ref const&, int) noexcept;
36 :
37 HIT 157 : iterator(
38 : detail::segments_iter_impl const& it) noexcept
39 157 : : it_(it)
40 : {
41 157 : }
42 :
43 : public:
44 : using value_type = segments_base::value_type;
45 : using reference = segments_base::reference;
46 : using pointer = reference;
47 : using difference_type =
48 : segments_base::difference_type;
49 : using iterator_category =
50 : std::bidirectional_iterator_tag;
51 :
52 : iterator() = default;
53 : iterator(iterator const&) = default;
54 : iterator& operator=(
55 : iterator const&) noexcept = default;
56 :
57 : reference
58 876 : operator*() const
59 : {
60 876 : encoding_opts opt;
61 876 : opt.space_as_plus = false;
62 876 : return it_.dereference().decode(opt);
63 : }
64 :
65 : // the return value is too expensive
66 : pointer operator->() const = delete;
67 :
68 : iterator&
69 852 : operator++() noexcept
70 : {
71 852 : it_.increment();
72 852 : return *this;
73 : }
74 :
75 : iterator&
76 72 : operator--() noexcept
77 : {
78 72 : it_.decrement();
79 72 : return *this;
80 : }
81 :
82 : iterator
83 48 : operator++(int) noexcept
84 : {
85 48 : auto tmp = *this;
86 48 : ++*this;
87 48 : return tmp;
88 : }
89 :
90 : iterator
91 21 : operator--(int) noexcept
92 : {
93 21 : auto tmp = *this;
94 21 : --*this;
95 21 : return tmp;
96 : }
97 :
98 : bool
99 66 : operator==(
100 : iterator const& other) const noexcept
101 : {
102 66 : return it_.equal(other.it_);
103 : }
104 :
105 : bool
106 932 : operator!=(
107 : iterator const& other) const noexcept
108 : {
109 932 : return ! it_.equal(other.it_);
110 : }
111 : };
112 :
113 : //------------------------------------------------
114 :
115 : inline
116 539 : segments_base::
117 : iterator::
118 : iterator(
119 539 : detail::path_ref const& ref) noexcept
120 539 : : it_(ref)
121 : {
122 539 : }
123 :
124 : inline
125 411 : segments_base::
126 : iterator::
127 : iterator(
128 : detail::path_ref const& ref,
129 411 : int) noexcept
130 411 : : it_(ref, 0)
131 : {
132 411 : }
133 :
134 : //------------------------------------------------
135 : //
136 : // segments_base
137 : //
138 : //------------------------------------------------
139 :
140 : inline
141 404 : segments_base::
142 : segments_base(
143 404 : detail::path_ref const& ref) noexcept
144 404 : : ref_(ref)
145 : {
146 404 : }
147 :
148 : inline
149 : pct_string_view
150 79 : segments_base::
151 : buffer() const noexcept
152 : {
153 79 : return ref_.buffer();
154 : }
155 :
156 : inline
157 : bool
158 41 : segments_base::
159 : is_absolute() const noexcept
160 : {
161 41 : return ref_.buffer().starts_with('/');
162 : }
163 :
164 : inline
165 : bool
166 81 : segments_base::
167 : empty() const noexcept
168 : {
169 81 : return ref_.nseg() == 0;
170 : }
171 :
172 : inline
173 : std::size_t
174 291 : segments_base::
175 : size() const noexcept
176 : {
177 291 : return ref_.nseg();
178 : }
179 :
180 : inline
181 : std::string
182 27 : segments_base::
183 : front() const noexcept
184 : {
185 27 : BOOST_ASSERT(! empty());
186 27 : return *begin();
187 : }
188 :
189 : inline
190 : std::string
191 20 : segments_base::
192 : back() const noexcept
193 : {
194 20 : BOOST_ASSERT(! empty());
195 20 : return *--end();
196 : }
197 :
198 : inline
199 : auto
200 539 : segments_base::
201 : begin() const noexcept ->
202 : iterator
203 : {
204 539 : return iterator(ref_);
205 : }
206 :
207 : inline
208 : auto
209 411 : segments_base::
210 : end() const noexcept ->
211 : iterator
212 : {
213 411 : return iterator(ref_, 0);
214 : }
215 :
216 : //------------------------------------------------
217 :
218 : inline
219 : std::ostream&
220 15 : operator<<(
221 : std::ostream& os,
222 : segments_base const& ps)
223 : {
224 15 : os << ps.buffer();
225 15 : return os;
226 : }
227 :
228 : } // urls
229 : } // boost
230 :
231 : #endif
|