GCC Code Coverage Report


Directory: libs/url/
File: include/boost/url/url_view.hpp
Date: 2025-11-10 19:06:22
Exec Total Coverage
Lines: 19 19 100.0%
Functions: 49 61 80.3%
Branches: 2 2 100.0%

Line Branch Exec Source
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_URL_VIEW_HPP
12 #define BOOST_URL_URL_VIEW_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/url_view_base.hpp>
16 #include <utility>
17
18 namespace boost {
19 namespace urls {
20
21 /** A non-owning reference to a valid URL
22
23 Objects of this type represent valid URL
24 strings constructed from a parsed, external
25 character buffer whose storage is managed
26 by the caller. That is, it acts like a
27 `core::string_view` in terms of ownership.
28 The caller is responsible for ensuring
29 that the lifetime of the underlying
30 character buffer extends until it is no
31 longer referenced.
32
33 @par Example 1
34 Construction from a string parses the input
35 as a <em>URI-reference</em> and throws an
36 exception on error. Upon success, the
37 constructed object points to the passed
38 character buffer; ownership is not
39 transferred.
40 @code
41 url_view u( "https://www.example.com/index.htm?text=none#a1" );
42 @endcode
43
44 @par Example 2
45 Parsing functions like @ref parse_uri_reference
46 return a `boost::system::result` containing either a valid
47 @ref url_view upon success, otherwise they
48 contain an error. The error can be converted to
49 an exception by the caller if desired:
50 @code
51 system::result< url_view > rv = parse_uri_reference( "https://www.example.com/index.htm?text=none#a1" );
52 @endcode
53
54 @par BNF
55 @code
56 URI-reference = URI / relative-ref
57
58 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
59
60 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
61 @endcode
62
63 @par Specification
64 @li <a href="https://tools.ietf.org/html/rfc3986"
65 >Uniform Resource Identifier (URI): Generic Syntax (rfc3986)</a>
66
67 @see
68 @ref parse_absolute_uri,
69 @ref parse_origin_form,
70 @ref parse_relative_ref,
71 @ref parse_uri,
72 @ref parse_uri_reference.
73 */
74 class BOOST_URL_DECL url_view
75 : public url_view_base
76 {
77 friend std::hash<url_view>;
78 friend class url_view_base;
79 friend class params_base;
80 friend class params_encoded_base;
81
82 #ifndef BOOST_URL_DOCS
83 // VFALCO docca emits this erroneously
84 friend struct detail::url_impl;
85 #endif
86
87 using url_view_base::digest;
88
89 explicit
90 3573 url_view(
91 detail::url_impl const& impl) noexcept
92 3573 : url_view_base(impl)
93 {
94 3573 }
95
96 public:
97 //--------------------------------------------
98 //
99 // Special Members
100 //
101 //--------------------------------------------
102
103 /** Destructor
104
105 Any params, segments, iterators, or
106 other views which reference the same
107 underlying character buffer remain
108 valid.
109 */
110 ~url_view() = default;
111
112 /** Constructor
113
114 Default constructed views refer to
115 a string with zero length, which
116 always remains valid. This matches
117 the grammar for a relative-ref with
118 an empty path and no query or
119 fragment.
120
121 @par Example
122 @code
123 url_view u;
124 @endcode
125
126 @par Postconditions
127 @code
128 this->empty() == true
129 @endcode
130
131 @par Complexity
132 Constant.
133
134 @par Exception Safety
135 Throws nothing.
136
137 @par BNF
138 @code
139 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
140 @endcode
141
142 @par Specification
143 <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
144 >4.2. Relative Reference (rfc3986)</a>
145 */
146 url_view() noexcept;
147
148 /** Constructor
149
150 This function constructs a URL from
151 the string `s`, which must contain a
152 valid <em>URI</em> or <em>relative-ref</em>
153 or else an exception is thrown. Upon
154 successful construction, the view
155 refers to the characters in the
156 buffer pointed to by `s`.
157 Ownership is not transferred; The caller
158 is responsible for ensuring that the
159 lifetime of the buffer extends until
160 it is no longer referenced.
161
162 @par Example
163 @code
164 url_view u( "http://www.example.com/index.htm" );
165 @endcode
166
167 @par Effects
168 @code
169 return parse_uri_reference( s ).value();
170 @endcode
171
172 @par Complexity
173 Linear in `s.size()`.
174
175 @par Exception Safety
176 Exceptions thrown on invalid input.
177
178 @throw system_error
179 The input failed to parse correctly.
180
181 @param s The string to parse.
182
183 @par BNF
184 @code
185 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
186
187 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
188 @endcode
189
190 @par Specification
191 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
192 >4.1. URI Reference</a>
193
194 @see
195 @ref parse_uri_reference.
196 */
197 url_view(core::string_view s);
198
199 /// @copydoc url_view(core::string_view)
200 template<
201 class String
202 #ifndef BOOST_URL_DOCS
203 , class = typename std::enable_if<
204 std::is_convertible<
205 String,
206 core::string_view
207 >::value &&
208 !std::is_convertible<
209 String*,
210 url_view_base*
211 >::value
212 >::type
213 #endif
214 >
215 439 url_view(
216 String const& s)
217 : url_view(
218 439 detail::to_sv(s))
219 {
220 437 }
221
222 /** Constructor
223
224 After construction, both views
225 reference the same underlying character
226 buffer. Ownership is not transferred.
227
228 @par Postconditions
229 @code
230 this->buffer().data() == other.buffer().data()
231 @endcode
232
233 @par Complexity
234 Constant.
235
236 @par Exception Safety
237 Throws nothing.
238
239 @param other The other view.
240 */
241 15770 url_view(
242 url_view const& other) noexcept
243 15770 : url_view(static_cast<
244 15770 url_view_base const&>(other))
245 {
246 15770 }
247
248 /** Constructor
249
250 After construction, both views
251 reference the same underlying character
252 buffer. Ownership is not transferred.
253
254 @par Postconditions
255 @code
256 this->buffer().data() == other.buffer().data()
257 @endcode
258
259 @par Complexity
260 Constant.
261
262 @par Exception Safety
263 Throws nothing.
264
265 @param other The other view.
266 */
267 url_view(
268 url_view_base const& other) noexcept;
269
270 /** Assignment
271
272 After assignment, both views
273 reference the same underlying character
274 buffer. Ownership is not transferred.
275
276 @par Postconditions
277 @code
278 this->buffer().data() == other.buffer().data()
279 @endcode
280
281 @par Complexity
282 Constant.
283
284 @par Exception Safety
285 Throws nothing.
286
287 @param other The other view.
288 @return A reference to this object.
289 */
290 url_view&
291 13 operator=(
292 url_view const& other) noexcept
293 {
294
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
13 if (this != &other)
295 *this = static_cast<
296 12 url_view_base const&>(other);
297 13 return *this;
298 }
299
300 /** Assignment
301
302 After assignment, both views
303 reference the same underlying character
304 buffer. Ownership is not transferred.
305
306 @par Postconditions
307 @code
308 this->buffer().data() == other.buffer().data()
309 @endcode
310
311 @par Complexity
312 Constant.
313
314 @par Exception Safety
315 Throws nothing.
316
317 @param other The other view.
318 @return A reference to this object.
319 */
320 url_view& operator=(
321 url_view_base const& other) noexcept;
322
323 //--------------------------------------------
324 //
325 // Observers
326 //
327 //--------------------------------------------
328
329 /** Return the maximum number of characters possible
330
331 This represents the largest number of
332 characters that are possible in a url,
333 not including any null terminator.
334
335 @par Complexity
336 Constant.
337
338 @par Exception Safety
339 Throws nothing.
340
341 @return The maximum number of characters possible.
342 */
343 static
344 constexpr
345 std::size_t
346 max_size() noexcept
347 {
348 return BOOST_URL_MAX_SIZE;
349 }
350 };
351
352 } // urls
353 } // boost
354
355 //------------------------------------------------
356
357 // std::hash specialization
358 #ifndef BOOST_URL_DOCS
359 namespace std {
360 template<>
361 struct hash< ::boost::urls::url_view >
362 {
363 hash() = default;
364 hash(hash const&) = default;
365 hash& operator=(hash const&) = default;
366
367 explicit
368 76 hash(std::size_t salt) noexcept
369 76 : salt_(salt)
370 {
371 76 }
372
373 std::size_t
374 304 operator()(::boost::urls::url_view const& u) const noexcept
375 {
376 304 return u.digest(salt_);
377 }
378
379 private:
380 std::size_t salt_ = 0;
381 };
382 } // std
383 #endif
384
385 #endif
386