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 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
|