include/boost/url/impl/segments_base.hpp

100.0% Lines (58/58) 100.0% Functions (20/20)
include/boost/url/impl/segments_base.hpp
Line TLA Hits 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 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
232