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 1826 iterator(
38 detail::segments_iter_impl const& it) noexcept
39 1826 : it_(it)
40 {
41 1826 }
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 8096 operator*() const
59 {
60 8096 encoding_opts opt;
61 8096 opt.space_as_plus = false;
62 8096 return it_.dereference().decode(opt);
63 }
64
65 // the return value is too expensive
66 pointer operator->() const = delete;
67
68 iterator&
69 8693 operator++() noexcept
70 {
71 8693 it_.increment();
72 8693 return *this;
73 }
74
75 iterator&
76 250 operator--() noexcept
77 {
78 250 it_.decrement();
79 250 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 13872 operator!=(
107 iterator const& other) const noexcept
108 {
109 13872 return ! it_.equal(other.it_);
110 }
111 };
112
113 //------------------------------------------------
114
115 inline
116 7187 segments_base::
117 iterator::
118 iterator(
119 7187 detail::path_ref const& ref) noexcept
120 7187 : it_(ref)
121 {
122 7187 }
123
124 inline
125 14603 segments_base::
126 iterator::
127 iterator(
128 detail::path_ref const& ref,
129 14603 int) noexcept
130 14603 : it_(ref, 0)
131 {
132 14603 }
133
134 //------------------------------------------------
135 //
136 // segments_base
137 //
138 //------------------------------------------------
139
140 inline
141 7009 segments_base::
142 segments_base(
143 7009 detail::path_ref const& ref) noexcept
144 7009 : ref_(ref)
145 {
146 7009 }
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 1893 segments_base::
167 empty() const noexcept
168 {
169 1893 return ref_.nseg() == 0;
170 }
171
172 inline
173 std::size_t
174 708 segments_base::
175 size() const noexcept
176 {
177 708 return ref_.nseg();
178 }
179
180 inline
181 std::string
182 29 segments_base::
183 front() const
184 {
185 29 BOOST_ASSERT(! empty());
186 29 return *begin();
187 }
188
189 inline
190 std::string
191 22 segments_base::
192 back() const
193 {
194 22 BOOST_ASSERT(! empty());
195 22 return *--end();
196 }
197
198 inline
199 auto
200 7187 segments_base::
201 begin() const noexcept ->
202 iterator
203 {
204 7187 return iterator(ref_);
205 }
206
207 inline
208 auto
209 14603 segments_base::
210 end() const noexcept ->
211 iterator
212 {
213 14603 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