Line |
Branch |
Exec |
Source |
1 |
|
|
// |
2 |
|
|
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) |
3 |
|
|
// |
4 |
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 |
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 |
|
|
// |
7 |
|
|
// Official repository: https://github.com/boostorg/url |
8 |
|
|
// |
9 |
|
|
|
10 |
|
|
#ifndef BOOST_URL_DECODE_VIEW_HPP |
11 |
|
|
#define BOOST_URL_DECODE_VIEW_HPP |
12 |
|
|
|
13 |
|
|
#include <boost/url/detail/config.hpp> |
14 |
|
|
#include <boost/core/detail/string_view.hpp> |
15 |
|
|
#include <boost/url/encoding_opts.hpp> |
16 |
|
|
#include <boost/url/pct_string_view.hpp> |
17 |
|
|
#include <type_traits> |
18 |
|
|
#include <iterator> |
19 |
|
|
#include <iosfwd> |
20 |
|
|
|
21 |
|
|
namespace boost { |
22 |
|
|
namespace urls { |
23 |
|
|
|
24 |
|
|
//------------------------------------------------ |
25 |
|
|
|
26 |
|
|
#ifndef BOOST_URL_DOCS |
27 |
|
|
class decode_view; |
28 |
|
|
|
29 |
|
|
namespace detail { |
30 |
|
|
|
31 |
|
|
// unchecked |
32 |
|
|
template<class... Args> |
33 |
|
|
decode_view |
34 |
|
|
make_decode_view( |
35 |
|
|
Args&&... args) noexcept; |
36 |
|
|
|
37 |
|
|
} // detail |
38 |
|
|
#endif |
39 |
|
|
|
40 |
|
|
//------------------------------------------------ |
41 |
|
|
|
42 |
|
|
/** A reference to a valid, percent-encoded string |
43 |
|
|
|
44 |
|
|
These views reference strings in parts of URLs |
45 |
|
|
or other components that are percent-encoded. |
46 |
|
|
The special characters (those not in the |
47 |
|
|
allowed character set) are stored as three |
48 |
|
|
character escapes that consist of a percent |
49 |
|
|
sign ('%%') followed by a two-digit hexadecimal |
50 |
|
|
number of the corresponding unescaped character |
51 |
|
|
code, which may be part of a UTF-8 code point |
52 |
|
|
depending on the context. |
53 |
|
|
|
54 |
|
|
The view refers to the original character |
55 |
|
|
buffer and only decodes escaped sequences when |
56 |
|
|
needed. In particular these operations perform |
57 |
|
|
percent-decoding automatically without the |
58 |
|
|
need to allocate memory: |
59 |
|
|
|
60 |
|
|
@li Iteration of the string |
61 |
|
|
@li Accessing the encoded character buffer |
62 |
|
|
@li Comparison to encoded or plain strings |
63 |
|
|
|
64 |
|
|
These objects can only be constructed from |
65 |
|
|
strings that have a valid percent-encoding, |
66 |
|
|
otherwise construction fails. The caller is |
67 |
|
|
responsible for ensuring that the lifetime |
68 |
|
|
of the character buffer from which the view |
69 |
|
|
is constructed extends unmodified until the |
70 |
|
|
view is no longer accessed. |
71 |
|
|
|
72 |
|
|
@par Operators |
73 |
|
|
The following operators are supported between |
74 |
|
|
@ref decode_view and any object that is convertible |
75 |
|
|
to `core::string_view` |
76 |
|
|
|
77 |
|
|
@code |
78 |
|
|
bool operator==( decode_view, decode_view ) noexcept; |
79 |
|
|
bool operator!=( decode_view, decode_view ) noexcept; |
80 |
|
|
bool operator<=( decode_view, decode_view ) noexcept; |
81 |
|
|
bool operator< ( decode_view, decode_view ) noexcept; |
82 |
|
|
bool operator> ( decode_view, decode_view ) noexcept; |
83 |
|
|
bool operator>=( decode_view, decode_view ) noexcept; |
84 |
|
|
@endcode |
85 |
|
|
|
86 |
|
|
*/ |
87 |
|
|
class decode_view |
88 |
|
|
{ |
89 |
|
|
char const* p_ = nullptr; |
90 |
|
|
std::size_t n_ = 0; |
91 |
|
|
std::size_t dn_ = 0; |
92 |
|
|
bool space_as_plus_ = true; |
93 |
|
|
|
94 |
|
|
#ifndef BOOST_URL_DOCS |
95 |
|
|
template<class... Args> |
96 |
|
|
friend |
97 |
|
|
decode_view |
98 |
|
|
detail::make_decode_view( |
99 |
|
|
Args&&... args) noexcept; |
100 |
|
|
#endif |
101 |
|
|
|
102 |
|
|
// unchecked |
103 |
|
|
BOOST_URL_DECL |
104 |
|
|
explicit |
105 |
|
|
decode_view( |
106 |
|
|
core::string_view s, |
107 |
|
|
std::size_t n, |
108 |
|
|
encoding_opts opt) noexcept; |
109 |
|
|
|
110 |
|
|
public: |
111 |
|
|
/** The value type |
112 |
|
|
*/ |
113 |
|
|
using value_type = char; |
114 |
|
|
|
115 |
|
|
/** The reference type |
116 |
|
|
*/ |
117 |
|
|
using reference = char; |
118 |
|
|
|
119 |
|
|
/// @copydoc reference |
120 |
|
|
using const_reference = char; |
121 |
|
|
|
122 |
|
|
/** The unsigned integer type |
123 |
|
|
*/ |
124 |
|
|
using size_type = std::size_t; |
125 |
|
|
|
126 |
|
|
/** The signed integer type |
127 |
|
|
*/ |
128 |
|
|
using difference_type = std::ptrdiff_t; |
129 |
|
|
|
130 |
|
|
/** An iterator of constant, decoded characters. |
131 |
|
|
|
132 |
|
|
This iterator is used to access the encoded |
133 |
|
|
string as a bidirectional range of characters |
134 |
|
|
with percent-decoding applied. Escape sequences |
135 |
|
|
are not decoded until the iterator is |
136 |
|
|
dereferenced. |
137 |
|
|
*/ |
138 |
|
|
#ifdef BOOST_URL_DOCS |
139 |
|
|
using iterator = __see_below__ |
140 |
|
|
#else |
141 |
|
|
|
142 |
|
|
/** An iterator of constant, decoded characters. |
143 |
|
|
|
144 |
|
|
This iterator is used to access the encoded |
145 |
|
|
string as a bidirectional range of characters |
146 |
|
|
with percent-decoding applied. Escape sequences |
147 |
|
|
are not decoded until the iterator is |
148 |
|
|
dereferenced. |
149 |
|
|
*/ |
150 |
|
|
class iterator; |
151 |
|
|
#endif |
152 |
|
|
|
153 |
|
|
/// @copydoc iterator |
154 |
|
|
using const_iterator = iterator; |
155 |
|
|
|
156 |
|
|
//-------------------------------------------- |
157 |
|
|
// |
158 |
|
|
// Special Members |
159 |
|
|
// |
160 |
|
|
//-------------------------------------------- |
161 |
|
|
|
162 |
|
|
/** Constructor |
163 |
|
|
|
164 |
|
|
Default-constructed views represent |
165 |
|
|
empty strings. |
166 |
|
|
|
167 |
|
|
@par Example |
168 |
|
|
@code |
169 |
|
|
decode_view ds; |
170 |
|
|
@endcode |
171 |
|
|
|
172 |
|
|
@par Postconditions |
173 |
|
|
@code |
174 |
|
|
this->empty() == true |
175 |
|
|
@endcode |
176 |
|
|
|
177 |
|
|
@par Complexity |
178 |
|
|
Constant. |
179 |
|
|
|
180 |
|
|
@par Exception Safety |
181 |
|
|
Throws nothing. |
182 |
|
|
*/ |
183 |
|
|
decode_view() noexcept = default; |
184 |
|
|
|
185 |
|
|
/** Constructor |
186 |
|
|
|
187 |
|
|
This constructs a view from the character |
188 |
|
|
buffer `s`, which must remain valid and |
189 |
|
|
unmodified until the view is no longer |
190 |
|
|
accessed. |
191 |
|
|
|
192 |
|
|
@par Example |
193 |
|
|
@code |
194 |
|
|
decode_view ds( "Program%20Files" ); |
195 |
|
|
@endcode |
196 |
|
|
|
197 |
|
|
@par Postconditions |
198 |
|
|
@code |
199 |
|
|
this->encoded() == s |
200 |
|
|
@endcode |
201 |
|
|
|
202 |
|
|
@par Complexity |
203 |
|
|
Linear in `s.size()`. |
204 |
|
|
|
205 |
|
|
@par Exception Safety |
206 |
|
|
Exceptions thrown on invalid input. |
207 |
|
|
|
208 |
|
|
@throw system_error |
209 |
|
|
The string contains an invalid percent encoding. |
210 |
|
|
|
211 |
|
|
@param s A percent-encoded string that has |
212 |
|
|
already been validated. |
213 |
|
|
|
214 |
|
|
@param opt The options for decoding. If |
215 |
|
|
this parameter is omitted, the default |
216 |
|
|
options are used. |
217 |
|
|
*/ |
218 |
|
|
explicit |
219 |
|
3773 |
decode_view( |
220 |
|
|
pct_string_view s, |
221 |
|
|
encoding_opts opt = {}) noexcept |
222 |
|
3773 |
: decode_view( |
223 |
|
|
detail::to_sv(s), |
224 |
|
|
s.decoded_size(), |
225 |
|
3773 |
opt) |
226 |
|
|
{ |
227 |
|
3773 |
} |
228 |
|
|
|
229 |
|
|
//-------------------------------------------- |
230 |
|
|
// |
231 |
|
|
// Observers |
232 |
|
|
// |
233 |
|
|
//-------------------------------------------- |
234 |
|
|
|
235 |
|
|
/** Return true if the string is empty |
236 |
|
|
|
237 |
|
|
@par Example |
238 |
|
|
@code |
239 |
|
|
assert( decode_view( "" ).empty() ); |
240 |
|
|
@endcode |
241 |
|
|
|
242 |
|
|
@par Complexity |
243 |
|
|
Constant. |
244 |
|
|
|
245 |
|
|
@par Exception Safety |
246 |
|
|
Throws nothing. |
247 |
|
|
*/ |
248 |
|
|
bool |
249 |
|
15 |
empty() const noexcept |
250 |
|
|
{ |
251 |
|
15 |
return n_ == 0; |
252 |
|
|
} |
253 |
|
|
|
254 |
|
|
/** Return the number of decoded characters |
255 |
|
|
|
256 |
|
|
@par Example |
257 |
|
|
@code |
258 |
|
|
assert( decode_view( "Program%20Files" ).size() == 13 ); |
259 |
|
|
@endcode |
260 |
|
|
|
261 |
|
|
@par Effects |
262 |
|
|
@code |
263 |
|
|
return std::distance( this->begin(), this->end() ); |
264 |
|
|
@endcode |
265 |
|
|
|
266 |
|
|
@par Complexity |
267 |
|
|
Constant. |
268 |
|
|
|
269 |
|
|
@par Exception Safety |
270 |
|
|
Throws nothing. |
271 |
|
|
*/ |
272 |
|
|
size_type |
273 |
|
3948 |
size() const noexcept |
274 |
|
|
{ |
275 |
|
3948 |
return dn_; |
276 |
|
|
} |
277 |
|
|
|
278 |
|
|
/** Return an iterator to the beginning |
279 |
|
|
|
280 |
|
|
@par Example |
281 |
|
|
@code |
282 |
|
|
auto it = this->begin(); |
283 |
|
|
@endcode |
284 |
|
|
|
285 |
|
|
@par Complexity |
286 |
|
|
Constant. |
287 |
|
|
|
288 |
|
|
@par Exception Safety |
289 |
|
|
Throws nothing. |
290 |
|
|
*/ |
291 |
|
|
iterator |
292 |
|
|
begin() const noexcept; |
293 |
|
|
|
294 |
|
|
/** Return an iterator to the end |
295 |
|
|
|
296 |
|
|
@par Example |
297 |
|
|
@code |
298 |
|
|
auto it = this->end(); |
299 |
|
|
@endcode |
300 |
|
|
|
301 |
|
|
@par Complexity |
302 |
|
|
Constant. |
303 |
|
|
|
304 |
|
|
@par Exception Safety |
305 |
|
|
Throws nothing. |
306 |
|
|
*/ |
307 |
|
|
iterator |
308 |
|
|
end() const noexcept; |
309 |
|
|
|
310 |
|
|
/** Return the first character |
311 |
|
|
|
312 |
|
|
@par Example |
313 |
|
|
@code |
314 |
|
|
assert( decode_view( "Program%20Files" ).front() == 'P' ); |
315 |
|
|
@endcode |
316 |
|
|
|
317 |
|
|
@par Preconditions |
318 |
|
|
@code |
319 |
|
|
not this->empty() |
320 |
|
|
@endcode |
321 |
|
|
|
322 |
|
|
@par Complexity |
323 |
|
|
Constant. |
324 |
|
|
|
325 |
|
|
@par Exception Safety |
326 |
|
|
Throws nothing. |
327 |
|
|
*/ |
328 |
|
|
reference |
329 |
|
|
front() const noexcept; |
330 |
|
|
|
331 |
|
|
/** Return the last character |
332 |
|
|
|
333 |
|
|
@par Example |
334 |
|
|
@code |
335 |
|
|
assert( decode_view( "Program%20Files" ).back() == 's' ); |
336 |
|
|
@endcode |
337 |
|
|
|
338 |
|
|
@par Preconditions |
339 |
|
|
@code |
340 |
|
|
not this->empty() |
341 |
|
|
@endcode |
342 |
|
|
|
343 |
|
|
@par Complexity |
344 |
|
|
Constant. |
345 |
|
|
|
346 |
|
|
@par Exception Safety |
347 |
|
|
Throws nothing. |
348 |
|
|
*/ |
349 |
|
|
reference |
350 |
|
|
back() const noexcept; |
351 |
|
|
|
352 |
|
|
/** Checks if the string begins with the given prefix |
353 |
|
|
|
354 |
|
|
@par Example |
355 |
|
|
@code |
356 |
|
|
assert( decode_view( "Program%20Files" ).starts_with("Program") ); |
357 |
|
|
@endcode |
358 |
|
|
|
359 |
|
|
@par Complexity |
360 |
|
|
Linear. |
361 |
|
|
|
362 |
|
|
@par Exception Safety |
363 |
|
|
Throws nothing. |
364 |
|
|
*/ |
365 |
|
|
BOOST_URL_DECL |
366 |
|
|
bool |
367 |
|
|
starts_with( core::string_view s ) const noexcept; |
368 |
|
|
|
369 |
|
|
/** Checks if the string ends with the given prefix |
370 |
|
|
|
371 |
|
|
@par Example |
372 |
|
|
@code |
373 |
|
|
assert( decode_view( "Program%20Files" ).ends_with("Files") ); |
374 |
|
|
@endcode |
375 |
|
|
|
376 |
|
|
@par Complexity |
377 |
|
|
Linear. |
378 |
|
|
|
379 |
|
|
@par Exception Safety |
380 |
|
|
Throws nothing. |
381 |
|
|
*/ |
382 |
|
|
BOOST_URL_DECL |
383 |
|
|
bool |
384 |
|
|
ends_with( core::string_view s ) const noexcept; |
385 |
|
|
|
386 |
|
|
/** Checks if the string begins with the given prefix |
387 |
|
|
|
388 |
|
|
@par Example |
389 |
|
|
@code |
390 |
|
|
assert( decode_view( "Program%20Files" ).starts_with('P') ); |
391 |
|
|
@endcode |
392 |
|
|
|
393 |
|
|
@par Complexity |
394 |
|
|
Constant. |
395 |
|
|
|
396 |
|
|
@par Exception Safety |
397 |
|
|
Throws nothing. |
398 |
|
|
*/ |
399 |
|
|
BOOST_URL_DECL |
400 |
|
|
bool |
401 |
|
|
starts_with( char ch ) const noexcept; |
402 |
|
|
|
403 |
|
|
/** Checks if the string ends with the given prefix |
404 |
|
|
|
405 |
|
|
@par Example |
406 |
|
|
@code |
407 |
|
|
assert( decode_view( "Program%20Files" ).ends_with('s') ); |
408 |
|
|
@endcode |
409 |
|
|
|
410 |
|
|
@par Complexity |
411 |
|
|
Constant. |
412 |
|
|
|
413 |
|
|
@par Exception Safety |
414 |
|
|
Throws nothing. |
415 |
|
|
*/ |
416 |
|
|
BOOST_URL_DECL |
417 |
|
|
bool |
418 |
|
|
ends_with( char ch ) const noexcept; |
419 |
|
|
|
420 |
|
|
/** Finds the first occurrence of character in this view |
421 |
|
|
|
422 |
|
|
@par Complexity |
423 |
|
|
Linear. |
424 |
|
|
|
425 |
|
|
@par Exception Safety |
426 |
|
|
Throws nothing. |
427 |
|
|
*/ |
428 |
|
|
BOOST_URL_DECL |
429 |
|
|
const_iterator |
430 |
|
|
find( char ch ) const noexcept; |
431 |
|
|
|
432 |
|
|
/** Finds the first occurrence of character in this view |
433 |
|
|
|
434 |
|
|
@par Complexity |
435 |
|
|
Linear. |
436 |
|
|
|
437 |
|
|
@par Exception Safety |
438 |
|
|
Throws nothing. |
439 |
|
|
*/ |
440 |
|
|
BOOST_URL_DECL |
441 |
|
|
const_iterator |
442 |
|
|
rfind( char ch ) const noexcept; |
443 |
|
|
|
444 |
|
|
/** Remove the first characters |
445 |
|
|
|
446 |
|
|
@par Example |
447 |
|
|
@code |
448 |
|
|
decode_view d( "Program%20Files" ); |
449 |
|
|
d.remove_prefix( 8 ); |
450 |
|
|
assert( d == "Files" ); |
451 |
|
|
@endcode |
452 |
|
|
|
453 |
|
|
@par Preconditions |
454 |
|
|
@code |
455 |
|
|
not this->empty() |
456 |
|
|
@endcode |
457 |
|
|
|
458 |
|
|
@par Complexity |
459 |
|
|
Linear. |
460 |
|
|
*/ |
461 |
|
|
BOOST_URL_DECL |
462 |
|
|
void |
463 |
|
|
remove_prefix( size_type n ); |
464 |
|
|
|
465 |
|
|
/** Remove the last characters |
466 |
|
|
|
467 |
|
|
@par Example |
468 |
|
|
@code |
469 |
|
|
decode_view d( "Program%20Files" ); |
470 |
|
|
d.remove_prefix( 6 ); |
471 |
|
|
assert( d == "Program" ); |
472 |
|
|
@endcode |
473 |
|
|
|
474 |
|
|
@par Preconditions |
475 |
|
|
@code |
476 |
|
|
not this->empty() |
477 |
|
|
@endcode |
478 |
|
|
|
479 |
|
|
@par Complexity |
480 |
|
|
Linear. |
481 |
|
|
*/ |
482 |
|
|
BOOST_URL_DECL |
483 |
|
|
void |
484 |
|
|
remove_suffix( size_type n ); |
485 |
|
|
|
486 |
|
|
/** Return the decoding options |
487 |
|
|
*/ |
488 |
|
|
encoding_opts |
489 |
|
|
options() const noexcept |
490 |
|
|
{ |
491 |
|
|
encoding_opts opt; |
492 |
|
|
opt.space_as_plus = space_as_plus_; |
493 |
|
|
return opt; |
494 |
|
|
} |
495 |
|
|
|
496 |
|
|
//-------------------------------------------- |
497 |
|
|
// |
498 |
|
|
// Comparison |
499 |
|
|
// |
500 |
|
|
//-------------------------------------------- |
501 |
|
|
|
502 |
|
|
/** Return the result of comparing to another string |
503 |
|
|
|
504 |
|
|
The length of the sequences to compare is the smaller of |
505 |
|
|
`size()` and `other.size()`. |
506 |
|
|
|
507 |
|
|
The function compares the two strings as if by calling |
508 |
|
|
`char_traits<char>::compare(to_string().data(), v.data(), rlen)`. |
509 |
|
|
This means the comparison is performed with |
510 |
|
|
percent-decoding applied to the current string. |
511 |
|
|
|
512 |
|
|
@param other string to compare |
513 |
|
|
|
514 |
|
|
@return Negative value if this string is less than the other |
515 |
|
|
character sequence, zero if the both character sequences are |
516 |
|
|
equal, positive value if this string is greater than the other |
517 |
|
|
character sequence |
518 |
|
|
*/ |
519 |
|
|
BOOST_URL_DECL |
520 |
|
|
int |
521 |
|
|
compare(core::string_view other) const noexcept; |
522 |
|
|
|
523 |
|
|
/** Return the result of comparing to another string |
524 |
|
|
|
525 |
|
|
The length of the sequences to compare is the smaller of |
526 |
|
|
`size()` and `other.size()`. |
527 |
|
|
|
528 |
|
|
The function compares the two strings as if by calling |
529 |
|
|
`char_traits<char>::compare(to_string().data(), v.to_string().data(), rlen)`. |
530 |
|
|
This means the comparison is performed with |
531 |
|
|
percent-decoding applied to the current string. |
532 |
|
|
|
533 |
|
|
@param other string to compare |
534 |
|
|
|
535 |
|
|
@return Negative value if this string is less than the other |
536 |
|
|
character sequence, zero if the both character sequences are |
537 |
|
|
equal, positive value if this string is greater than the other |
538 |
|
|
character sequence |
539 |
|
|
*/ |
540 |
|
|
BOOST_URL_DECL |
541 |
|
|
int |
542 |
|
|
compare(decode_view other) const noexcept; |
543 |
|
|
|
544 |
|
|
//-------------------------------------------- |
545 |
|
|
|
546 |
|
|
// relational operators |
547 |
|
|
#ifndef BOOST_URL_DOCS |
548 |
|
|
private: |
549 |
|
|
template<class S0, class S1> |
550 |
|
|
using is_match = std::integral_constant<bool, |
551 |
|
|
// both decode_view or convertible to core::string_view |
552 |
|
|
( |
553 |
|
|
std::is_same<typename std::decay<S0>::type, decode_view>::value || |
554 |
|
|
std::is_convertible<S0, core::string_view>::value) && |
555 |
|
|
( |
556 |
|
|
std::is_same<typename std::decay<S1>::type, decode_view>::value || |
557 |
|
|
std::is_convertible<S1, core::string_view>::value) && |
558 |
|
|
// not both are convertible to string view |
559 |
|
|
( |
560 |
|
|
!std::is_convertible<S0, core::string_view>::value || |
561 |
|
|
!std::is_convertible<S1, core::string_view>::value)>; |
562 |
|
|
|
563 |
|
|
static |
564 |
|
|
int |
565 |
|
316 |
decode_compare(decode_view s0, decode_view s1) noexcept |
566 |
|
|
{ |
567 |
|
316 |
return s0.compare(s1); |
568 |
|
|
} |
569 |
|
|
|
570 |
|
|
template <class S> |
571 |
|
|
static |
572 |
|
|
int |
573 |
|
5571 |
decode_compare(decode_view s0, S const& s1) noexcept |
574 |
|
|
{ |
575 |
|
5571 |
return s0.compare(s1); |
576 |
|
|
} |
577 |
|
|
|
578 |
|
|
template <class S> |
579 |
|
|
static |
580 |
|
|
int |
581 |
|
|
decode_compare(S const& s0, decode_view s1) noexcept |
582 |
|
|
{ |
583 |
|
|
return -s1.compare(s0); |
584 |
|
|
} |
585 |
|
|
public: |
586 |
|
|
|
587 |
|
|
/// Compare two decode views for equality |
588 |
|
|
/** |
589 |
|
|
* This function is only enabled if both types are |
590 |
|
|
* decode_view or convertible to `core::string_view`, |
591 |
|
|
* but not both are convertible to `core::string_view` |
592 |
|
|
*/ |
593 |
|
|
template<class S0, class S1> |
594 |
|
3319 |
BOOST_CXX14_CONSTEXPR friend auto operator==( |
595 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
596 |
|
|
typename std::enable_if< |
597 |
|
|
is_match<S0, S1>::value, bool>::type |
598 |
|
|
{ |
599 |
|
3319 |
return decode_compare(s0, s1) == 0; |
600 |
|
|
} |
601 |
|
|
|
602 |
|
|
/// Compare two decode views for inequality |
603 |
|
|
/** |
604 |
|
|
* This function is only enabled if both types are |
605 |
|
|
* decode_view or convertible to `core::string_view`, |
606 |
|
|
* but not both are convertible to `core::string_view` |
607 |
|
|
*/ |
608 |
|
|
template<class S0, class S1> |
609 |
|
747 |
BOOST_CXX14_CONSTEXPR friend auto operator!=( |
610 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
611 |
|
|
typename std::enable_if< |
612 |
|
|
is_match<S0, S1>::value, bool>::type |
613 |
|
|
{ |
614 |
|
747 |
return decode_compare(s0, s1) != 0; |
615 |
|
|
} |
616 |
|
|
|
617 |
|
|
/// Compare two decode views for less than |
618 |
|
|
/** |
619 |
|
|
* This function is only enabled if both types are |
620 |
|
|
* decode_view or convertible to `core::string_view`, |
621 |
|
|
* but not both are convertible to `core::string_view` |
622 |
|
|
*/ |
623 |
|
|
template<class S0, class S1> |
624 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator<( |
625 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
626 |
|
|
typename std::enable_if< |
627 |
|
|
is_match<S0, S1>::value, bool>::type |
628 |
|
|
{ |
629 |
|
16 |
return decode_compare(s0, s1) < 0; |
630 |
|
|
} |
631 |
|
|
|
632 |
|
|
/// Compare two decode views for less than or equal |
633 |
|
|
/** |
634 |
|
|
* This function is only enabled if both types are |
635 |
|
|
* decode_view or convertible to `core::string_view`, |
636 |
|
|
* but not both are convertible to `core::string_view` |
637 |
|
|
*/ |
638 |
|
|
template<class S0, class S1> |
639 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator<=( |
640 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
641 |
|
|
typename std::enable_if< |
642 |
|
|
is_match<S0, S1>::value, bool>::type |
643 |
|
|
{ |
644 |
|
16 |
return decode_compare(s0, s1) <= 0; |
645 |
|
|
} |
646 |
|
|
|
647 |
|
|
/// Compare two decode views for greater than |
648 |
|
|
/** |
649 |
|
|
* This function is only enabled if both types are |
650 |
|
|
* decode_view or convertible to `core::string_view`, |
651 |
|
|
* but not both are convertible to `core::string_view` |
652 |
|
|
*/ |
653 |
|
|
template<class S0, class S1> |
654 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator>( |
655 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
656 |
|
|
typename std::enable_if< |
657 |
|
|
is_match<S0, S1>::value, bool>::type |
658 |
|
|
{ |
659 |
|
16 |
return decode_compare(s0, s1) > 0; |
660 |
|
|
} |
661 |
|
|
|
662 |
|
|
/// Compare two decode views for greater than or equal |
663 |
|
|
/** |
664 |
|
|
* This function is only enabled if both types are |
665 |
|
|
* decode_view or convertible to `core::string_view`, |
666 |
|
|
* but not both are convertible to `core::string_view` |
667 |
|
|
*/ |
668 |
|
|
template<class S0, class S1> |
669 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator>=( |
670 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
671 |
|
|
typename std::enable_if< |
672 |
|
|
is_match<S0, S1>::value, bool>::type |
673 |
|
|
{ |
674 |
|
16 |
return decode_compare(s0, s1) >= 0; |
675 |
|
|
} |
676 |
|
|
#endif |
677 |
|
|
|
678 |
|
|
/** Format the string with percent-decoding applied to the output stream |
679 |
|
|
|
680 |
|
|
This hidden friend function serializes the decoded view |
681 |
|
|
to the output stream. |
682 |
|
|
|
683 |
|
|
@return A reference to the output stream, for chaining |
684 |
|
|
|
685 |
|
|
@param os The output stream to write to |
686 |
|
|
|
687 |
|
|
@param s The decoded view to write |
688 |
|
|
*/ |
689 |
|
|
friend |
690 |
|
|
std::ostream& |
691 |
|
2 |
operator<<( |
692 |
|
|
std::ostream& os, |
693 |
|
|
decode_view const& s) |
694 |
|
|
{ |
695 |
|
|
// hidden friend |
696 |
|
2 |
s.write(os); |
697 |
|
2 |
return os; |
698 |
|
|
} |
699 |
|
|
|
700 |
|
|
private: |
701 |
|
|
BOOST_URL_DECL |
702 |
|
|
void |
703 |
|
|
write(std::ostream& os) const; |
704 |
|
|
}; |
705 |
|
|
|
706 |
|
|
/** Format the string with percent-decoding applied to the output stream |
707 |
|
|
|
708 |
|
|
This function serializes the decoded view |
709 |
|
|
to the output stream. |
710 |
|
|
|
711 |
|
|
@return A reference to the output stream, for chaining |
712 |
|
|
|
713 |
|
|
@param os The output stream to write to |
714 |
|
|
|
715 |
|
|
@param s The decoded view to write |
716 |
|
|
*/ |
717 |
|
|
inline |
718 |
|
|
std::ostream& |
719 |
|
|
operator<<( |
720 |
|
|
std::ostream& os, |
721 |
|
|
decode_view const& s); |
722 |
|
|
|
723 |
|
|
//------------------------------------------------ |
724 |
|
|
|
725 |
|
|
inline |
726 |
|
|
decode_view |
727 |
|
3697 |
pct_string_view::operator*() const noexcept |
728 |
|
|
{ |
729 |
|
3697 |
return decode_view(*this); |
730 |
|
|
} |
731 |
|
|
|
732 |
|
|
#ifndef BOOST_URL_DOCS |
733 |
|
|
namespace detail { |
734 |
|
|
template<class... Args> |
735 |
|
|
decode_view |
736 |
|
|
make_decode_view( |
737 |
|
|
Args&&... args) noexcept |
738 |
|
|
{ |
739 |
|
|
return decode_view( |
740 |
|
|
std::forward<Args>(args)...); |
741 |
|
|
} |
742 |
|
|
} // detail |
743 |
|
|
#endif |
744 |
|
|
|
745 |
|
|
//------------------------------------------------ |
746 |
|
|
|
747 |
|
|
} // urls |
748 |
|
|
} // boost |
749 |
|
|
|
750 |
|
|
#include <boost/url/impl/decode_view.hpp> |
751 |
|
|
|
752 |
|
|
#endif |
753 |
|
|
|