100.00% Lines (1/1) 100.00% Functions (1/1)
TLA Baseline Branch
Line Hits Code Line Hits Code
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_SEGMENTS_BASE_HPP 11   #ifndef BOOST_URL_SEGMENTS_BASE_HPP
12   #define BOOST_URL_SEGMENTS_BASE_HPP 12   #define BOOST_URL_SEGMENTS_BASE_HPP
13   13  
14   #include <boost/url/detail/config.hpp> 14   #include <boost/url/detail/config.hpp>
15   #include <boost/url/ignore_case.hpp> 15   #include <boost/url/ignore_case.hpp>
16   #include <boost/url/detail/url_impl.hpp> 16   #include <boost/url/detail/url_impl.hpp>
17   #include <iosfwd> 17   #include <iosfwd>
18   #include <string> 18   #include <string>
19   19  
20   namespace boost { 20   namespace boost {
21   namespace urls { 21   namespace urls {
22   22  
23   /** Decoded path segment helper base 23   /** Decoded path segment helper base
24   24  
25   Provides the shared decoded path-segment 25   Provides the shared decoded path-segment
26   algorithms (iteration, lookup, comparison) 26   algorithms (iteration, lookup, comparison)
27   used by @ref segments_view and 27   used by @ref segments_view and
28   @ref segments_ref. This base cannot be 28   @ref segments_ref. This base cannot be
29   instantiated directly; instead, use one of 29   instantiated directly; instead, use one of
30   the concrete containers below. 30   the concrete containers below.
31   31  
32   @par Containers 32   @par Containers
33   @li @ref segments_ref 33   @li @ref segments_ref
34   @li @ref segments_view 34   @li @ref segments_view
35   @li @ref segments_encoded_ref 35   @li @ref segments_encoded_ref
36   @li @ref segments_encoded_view 36   @li @ref segments_encoded_view
37   */ 37   */
38   class BOOST_SYMBOL_VISIBLE segments_base 38   class BOOST_SYMBOL_VISIBLE segments_base
39   { 39   {
40   detail::path_ref ref_; 40   detail::path_ref ref_;
41   41  
42   friend class url_view_base; 42   friend class url_view_base;
43   friend class segments_ref; 43   friend class segments_ref;
44   friend class segments_view; 44   friend class segments_view;
45   45  
46   segments_base( 46   segments_base(
47   detail::path_ref const& ref) noexcept; 47   detail::path_ref const& ref) noexcept;
HITCBC 48   2 segments_base() = default; 48   2 segments_base() = default;
49   segments_base( 49   segments_base(
50   segments_base const&) = default; 50   segments_base const&) = default;
51   segments_base& operator=( 51   segments_base& operator=(
52   segments_base const&) = default; 52   segments_base const&) = default;
53   53  
54   public: 54   public:
55   /** A Bidirectional iterator to a path segment 55   /** A Bidirectional iterator to a path segment
56   56  
57   Objects of this type allow iteration 57   Objects of this type allow iteration
58   through the segments in the path. 58   through the segments in the path.
59   Any percent-escapes in returned strings 59   Any percent-escapes in returned strings
60   are decoded first. 60   are decoded first.
61   The values returned are read-only; 61   The values returned are read-only;
62   changes to segments must be made 62   changes to segments must be made
63   through the container instead, if the 63   through the container instead, if the
64   container supports modification. 64   container supports modification.
65   65  
66   <br> 66   <br>
67   67  
68   The strings produced when iterators are 68   The strings produced when iterators are
69   dereferenced belong to the iterator and 69   dereferenced belong to the iterator and
70   become invalidated when that particular 70   become invalidated when that particular
71   iterator is incremented, decremented, 71   iterator is incremented, decremented,
72   or destroyed. 72   or destroyed.
73   */ 73   */
74   class iterator; 74   class iterator;
75   75  
76   /// @copydoc iterator 76   /// @copydoc iterator
77   using const_iterator = iterator; 77   using const_iterator = iterator;
78   78  
79   /** The value type 79   /** The value type
80   80  
81   Values of this type represent a segment 81   Values of this type represent a segment
82   where unique ownership is retained by 82   where unique ownership is retained by
83   making a copy. 83   making a copy.
84   84  
85   @par Example 85   @par Example
86   @code 86   @code
87   segments_base::value_type ps( url_view( "/path/to/file.txt" ).segments().back() ); 87   segments_base::value_type ps( url_view( "/path/to/file.txt" ).segments().back() );
88   @endcode 88   @endcode
89   */ 89   */
90   using value_type = std::string; 90   using value_type = std::string;
91   91  
92   /** The reference type 92   /** The reference type
93   93  
94   This is the type of value returned when 94   This is the type of value returned when
95   iterators of the view are dereferenced. 95   iterators of the view are dereferenced.
96   */ 96   */
97   using reference = std::string; 97   using reference = std::string;
98   98  
99   /// @copydoc reference 99   /// @copydoc reference
100   using const_reference = std::string; 100   using const_reference = std::string;
101   101  
102   /** An unsigned integer type used to represent size. 102   /** An unsigned integer type used to represent size.
103   */ 103   */
104   using size_type = std::size_t; 104   using size_type = std::size_t;
105   105  
106   /** A signed integer type used to represent differences. 106   /** A signed integer type used to represent differences.
107   */ 107   */
108   using difference_type = std::ptrdiff_t; 108   using difference_type = std::ptrdiff_t;
109   109  
110   //-------------------------------------------- 110   //--------------------------------------------
111   // 111   //
112   // Observers 112   // Observers
113   // 113   //
114   //-------------------------------------------- 114   //--------------------------------------------
115   115  
116   /** Return the maximum number of characters possible 116   /** Return the maximum number of characters possible
117   117  
118   This represents the largest number of 118   This represents the largest number of
119   characters that are possible in a path, 119   characters that are possible in a path,
120   not including any null terminator. 120   not including any null terminator.
121   121  
122   @par Exception Safety 122   @par Exception Safety
123   Throws nothing. 123   Throws nothing.
124   124  
125   @return The maximum number of characters possible. 125   @return The maximum number of characters possible.
126   */ 126   */
127   static 127   static
128   constexpr 128   constexpr
129   std::size_t 129   std::size_t
130   max_size() noexcept 130   max_size() noexcept
131   { 131   {
132   return BOOST_URL_MAX_SIZE; 132   return BOOST_URL_MAX_SIZE;
133   } 133   }
134   134  
135   /** Return the referenced character buffer. 135   /** Return the referenced character buffer.
136   136  
137   This function returns the character 137   This function returns the character
138   buffer referenced by the view. 138   buffer referenced by the view.
139   The returned string may contain 139   The returned string may contain
140   percent escapes. 140   percent escapes.
141   141  
142   @par Example 142   @par Example
143   @code 143   @code
144   assert( url_view( "/path/to/file.txt" ).segments().buffer() == "/path/to/file.txt" ); 144   assert( url_view( "/path/to/file.txt" ).segments().buffer() == "/path/to/file.txt" );
145   @endcode 145   @endcode
146   146  
147   @par Complexity 147   @par Complexity
148   Constant. 148   Constant.
149   149  
150   @par Exception Safety 150   @par Exception Safety
151   Throws nothing. 151   Throws nothing.
152   152  
153   @return A string containing the path. 153   @return A string containing the path.
154   */ 154   */
155   pct_string_view 155   pct_string_view
156   buffer() const noexcept; 156   buffer() const noexcept;
157   157  
158   /** Returns true if this references an absolute path. 158   /** Returns true if this references an absolute path.
159   159  
160   Absolute paths always start with a 160   Absolute paths always start with a
161   forward slash ('/'). 161   forward slash ('/').
162   162  
163   @par Example 163   @par Example
164   @code 164   @code
165   assert( url_view( "/path/to/file.txt" ).segments().is_absolute() == true ); 165   assert( url_view( "/path/to/file.txt" ).segments().is_absolute() == true );
166   @endcode 166   @endcode
167   167  
168   @par Complexity 168   @par Complexity
169   Constant. 169   Constant.
170   170  
171   @par Exception Safety 171   @par Exception Safety
172   Throws nothing. 172   Throws nothing.
173   173  
174   @return `true` if the path is absolute, otherwise `false`. 174   @return `true` if the path is absolute, otherwise `false`.
175   */ 175   */
176   bool 176   bool
177   is_absolute() const noexcept; 177   is_absolute() const noexcept;
178   178  
179   /** Return true if there are no segments 179   /** Return true if there are no segments
180   180  
181   @par Example 181   @par Example
182   @code 182   @code
183   assert( ! url_view( "/index.htm" ).segments().empty() ); 183   assert( ! url_view( "/index.htm" ).segments().empty() );
184   @endcode 184   @endcode
185   185  
186   @par Complexity 186   @par Complexity
187   Constant. 187   Constant.
188   188  
189   @par Exception Safety 189   @par Exception Safety
190   Throws nothing. 190   Throws nothing.
191   191  
192   @return `true` if there are no segments, otherwise `false`. 192   @return `true` if there are no segments, otherwise `false`.
193   */ 193   */
194   bool 194   bool
195   empty() const noexcept; 195   empty() const noexcept;
196   196  
197   /** Return the number of segments 197   /** Return the number of segments
198   198  
199   @par Example 199   @par Example
200   @code 200   @code
201   assert( url_view( "/path/to/file.txt" ).segments().size() == 3 ); 201   assert( url_view( "/path/to/file.txt" ).segments().size() == 3 );
202   @endcode 202   @endcode
203   203  
204   @par Complexity 204   @par Complexity
205   Constant. 205   Constant.
206   206  
207   @par Exception Safety 207   @par Exception Safety
208   Throws nothing. 208   Throws nothing.
209   209  
210   @return The number of segments. 210   @return The number of segments.
211   */ 211   */
212   std::size_t 212   std::size_t
213   size() const noexcept; 213   size() const noexcept;
214   214  
215   /** Return the first segment 215   /** Return the first segment
216   216  
217   This function returns a string with the 217   This function returns a string with the
218   first segment of the path without any 218   first segment of the path without any
219   leading or trailing '/' separators. 219   leading or trailing '/' separators.
220   Any percent-escapes in the string are 220   Any percent-escapes in the string are
221   decoded first. 221   decoded first.
222   222  
223   @par Preconditions 223   @par Preconditions
224   @code 224   @code
225   this->empty() == false 225   this->empty() == false
226   @endcode 226   @endcode
227   227  
228   @par Effects 228   @par Effects
229   @code 229   @code
230   return *begin(); 230   return *begin();
231   @endcode 231   @endcode
232   232  
233   @par Example 233   @par Example
234   @code 234   @code
235   assert( url_view( "/path/to/file.txt" ).segments().front() == "path" ); 235   assert( url_view( "/path/to/file.txt" ).segments().front() == "path" );
236   @endcode 236   @endcode
237   237  
238   @par Complexity 238   @par Complexity
239   Linear in `this->front().size()`. 239   Linear in `this->front().size()`.
240   240  
241   @par Exception Safety 241   @par Exception Safety
242   Calls to allocate may throw. 242   Calls to allocate may throw.
243   243  
244   @return The first segment. 244   @return The first segment.
245   */ 245   */
246   std::string 246   std::string
247   front() const; 247   front() const;
248   248  
249   /** Return the last segment 249   /** Return the last segment
250   250  
251   @par Preconditions 251   @par Preconditions
252   @code 252   @code
253   this->empty() == false 253   this->empty() == false
254   @endcode 254   @endcode
255   255  
256   @par Example 256   @par Example
257   @code 257   @code
258   assert( url_view( "/path/to/file.txt" ).segments().back() == "file.txt" ); 258   assert( url_view( "/path/to/file.txt" ).segments().back() == "file.txt" );
259   @endcode 259   @endcode
260   260  
261   @par Preconditions 261   @par Preconditions
262   @code 262   @code
263   this->empty() == false 263   this->empty() == false
264   @endcode 264   @endcode
265   265  
266   @par Effects 266   @par Effects
267   @code 267   @code
268   return *--end(); 268   return *--end();
269   @endcode 269   @endcode
270   270  
271   @par Complexity 271   @par Complexity
272   Linear in `this->back().size()`. 272   Linear in `this->back().size()`.
273   273  
274   @par Exception Safety 274   @par Exception Safety
275   Calls to allocate may throw. 275   Calls to allocate may throw.
276   276  
277   @return The last segment. 277   @return The last segment.
278   */ 278   */
279   std::string 279   std::string
280   back() const; 280   back() const;
281   281  
282   /** Return an iterator to the beginning 282   /** Return an iterator to the beginning
283   283  
284   @par Complexity 284   @par Complexity
285   Linear in `this->front().size()` or 285   Linear in `this->front().size()` or
286   constant if `this->empty()`. 286   constant if `this->empty()`.
287   287  
288   @par Exception Safety 288   @par Exception Safety
289   Throws nothing. 289   Throws nothing.
290   290  
291   @return An iterator to the first segment. 291   @return An iterator to the first segment.
292   */ 292   */
293   iterator 293   iterator
294   begin() const noexcept; 294   begin() const noexcept;
295   295  
296   /** Return an iterator to the end 296   /** Return an iterator to the end
297   297  
298   @par Complexity 298   @par Complexity
299   Constant. 299   Constant.
300   300  
301   @par Exception Safety 301   @par Exception Safety
302   Throws nothing. 302   Throws nothing.
303   303  
304   @return An iterator to one past the last segment. 304   @return An iterator to one past the last segment.
305   */ 305   */
306   iterator 306   iterator
307   end() const noexcept; 307   end() const noexcept;
308   }; 308   };
309   309  
310   //------------------------------------------------ 310   //------------------------------------------------
311   311  
312   /** Format to an output stream 312   /** Format to an output stream
313   313  
314   Any percent-escapes are emitted as-is; 314   Any percent-escapes are emitted as-is;
315   no decoding is performed. 315   no decoding is performed.
316   316  
317   @par Complexity 317   @par Complexity
318   Linear in `ps.buffer().size()`. 318   Linear in `ps.buffer().size()`.
319   319  
320   @par Effects 320   @par Effects
321   @code 321   @code
322   return os << ps.buffer(); 322   return os << ps.buffer();
323   @endcode 323   @endcode
324   324  
325   @param os The output stream to write to. 325   @param os The output stream to write to.
326   @param ps The segments to write. 326   @param ps The segments to write.
327   @return A reference to the output stream. 327   @return A reference to the output stream.
328   */ 328   */
329   std::ostream& 329   std::ostream&
330   operator<<( 330   operator<<(
331   std::ostream& os, 331   std::ostream& os,
332   segments_base const& ps); 332   segments_base const& ps);
333   333  
334   } // urls 334   } // urls
335   } // boost 335   } // boost
336   336  
337   #include <boost/url/impl/segments_base.hpp> 337   #include <boost/url/impl/segments_base.hpp>
338   338  
339   #endif 339   #endif