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 |
|
|
class iterator; |
142 |
|
|
#endif |
143 |
|
|
|
144 |
|
|
/// @copydoc iterator |
145 |
|
|
using const_iterator = iterator; |
146 |
|
|
|
147 |
|
|
//-------------------------------------------- |
148 |
|
|
// |
149 |
|
|
// Special Members |
150 |
|
|
// |
151 |
|
|
//-------------------------------------------- |
152 |
|
|
|
153 |
|
|
/** Constructor |
154 |
|
|
|
155 |
|
|
Default-constructed views represent |
156 |
|
|
empty strings. |
157 |
|
|
|
158 |
|
|
@par Example |
159 |
|
|
@code |
160 |
|
|
decode_view ds; |
161 |
|
|
@endcode |
162 |
|
|
|
163 |
|
|
@par Postconditions |
164 |
|
|
@code |
165 |
|
|
this->empty() == true |
166 |
|
|
@endcode |
167 |
|
|
|
168 |
|
|
@par Complexity |
169 |
|
|
Constant. |
170 |
|
|
|
171 |
|
|
@par Exception Safety |
172 |
|
|
Throws nothing. |
173 |
|
|
*/ |
174 |
|
|
decode_view() noexcept = default; |
175 |
|
|
|
176 |
|
|
/** Constructor |
177 |
|
|
|
178 |
|
|
This constructs a view from the character |
179 |
|
|
buffer `s`, which must remain valid and |
180 |
|
|
unmodified until the view is no longer |
181 |
|
|
accessed. |
182 |
|
|
|
183 |
|
|
@par Example |
184 |
|
|
@code |
185 |
|
|
decode_view ds( "Program%20Files" ); |
186 |
|
|
@endcode |
187 |
|
|
|
188 |
|
|
@par Postconditions |
189 |
|
|
@code |
190 |
|
|
this->encoded() == s |
191 |
|
|
@endcode |
192 |
|
|
|
193 |
|
|
@par Complexity |
194 |
|
|
Linear in `s.size()`. |
195 |
|
|
|
196 |
|
|
@par Exception Safety |
197 |
|
|
Exceptions thrown on invalid input. |
198 |
|
|
|
199 |
|
|
@throw system_error |
200 |
|
|
The string contains an invalid percent encoding. |
201 |
|
|
|
202 |
|
|
@param s A percent-encoded string that has |
203 |
|
|
already been validated. |
204 |
|
|
|
205 |
|
|
@param opt The options for decoding. If |
206 |
|
|
this parameter is omitted, the default |
207 |
|
|
options are used. |
208 |
|
|
*/ |
209 |
|
|
explicit |
210 |
|
3773 |
decode_view( |
211 |
|
|
pct_string_view s, |
212 |
|
|
encoding_opts opt = {}) noexcept |
213 |
|
3773 |
: decode_view( |
214 |
|
|
detail::to_sv(s), |
215 |
|
|
s.decoded_size(), |
216 |
|
3773 |
opt) |
217 |
|
|
{ |
218 |
|
3773 |
} |
219 |
|
|
|
220 |
|
|
//-------------------------------------------- |
221 |
|
|
// |
222 |
|
|
// Observers |
223 |
|
|
// |
224 |
|
|
//-------------------------------------------- |
225 |
|
|
|
226 |
|
|
/** Return true if the string is empty |
227 |
|
|
|
228 |
|
|
@par Example |
229 |
|
|
@code |
230 |
|
|
assert( decode_view( "" ).empty() ); |
231 |
|
|
@endcode |
232 |
|
|
|
233 |
|
|
@par Complexity |
234 |
|
|
Constant. |
235 |
|
|
|
236 |
|
|
@par Exception Safety |
237 |
|
|
Throws nothing. |
238 |
|
|
*/ |
239 |
|
|
bool |
240 |
|
15 |
empty() const noexcept |
241 |
|
|
{ |
242 |
|
15 |
return n_ == 0; |
243 |
|
|
} |
244 |
|
|
|
245 |
|
|
/** Return the number of decoded characters |
246 |
|
|
|
247 |
|
|
@par Example |
248 |
|
|
@code |
249 |
|
|
assert( decode_view( "Program%20Files" ).size() == 13 ); |
250 |
|
|
@endcode |
251 |
|
|
|
252 |
|
|
@par Effects |
253 |
|
|
@code |
254 |
|
|
return std::distance( this->begin(), this->end() ); |
255 |
|
|
@endcode |
256 |
|
|
|
257 |
|
|
@par Complexity |
258 |
|
|
Constant. |
259 |
|
|
|
260 |
|
|
@par Exception Safety |
261 |
|
|
Throws nothing. |
262 |
|
|
*/ |
263 |
|
|
size_type |
264 |
|
3948 |
size() const noexcept |
265 |
|
|
{ |
266 |
|
3948 |
return dn_; |
267 |
|
|
} |
268 |
|
|
|
269 |
|
|
/** Return an iterator to the beginning |
270 |
|
|
|
271 |
|
|
@par Example |
272 |
|
|
@code |
273 |
|
|
auto it = this->begin(); |
274 |
|
|
@endcode |
275 |
|
|
|
276 |
|
|
@par Complexity |
277 |
|
|
Constant. |
278 |
|
|
|
279 |
|
|
@par Exception Safety |
280 |
|
|
Throws nothing. |
281 |
|
|
*/ |
282 |
|
|
iterator |
283 |
|
|
begin() const noexcept; |
284 |
|
|
|
285 |
|
|
/** Return an iterator to the end |
286 |
|
|
|
287 |
|
|
@par Example |
288 |
|
|
@code |
289 |
|
|
auto it = this->end(); |
290 |
|
|
@endcode |
291 |
|
|
|
292 |
|
|
@par Complexity |
293 |
|
|
Constant. |
294 |
|
|
|
295 |
|
|
@par Exception Safety |
296 |
|
|
Throws nothing. |
297 |
|
|
*/ |
298 |
|
|
iterator |
299 |
|
|
end() const noexcept; |
300 |
|
|
|
301 |
|
|
/** Return the first character |
302 |
|
|
|
303 |
|
|
@par Example |
304 |
|
|
@code |
305 |
|
|
assert( decode_view( "Program%20Files" ).front() == 'P' ); |
306 |
|
|
@endcode |
307 |
|
|
|
308 |
|
|
@par Preconditions |
309 |
|
|
@code |
310 |
|
|
not this->empty() |
311 |
|
|
@endcode |
312 |
|
|
|
313 |
|
|
@par Complexity |
314 |
|
|
Constant. |
315 |
|
|
|
316 |
|
|
@par Exception Safety |
317 |
|
|
Throws nothing. |
318 |
|
|
*/ |
319 |
|
|
reference |
320 |
|
|
front() const noexcept; |
321 |
|
|
|
322 |
|
|
/** Return the last character |
323 |
|
|
|
324 |
|
|
@par Example |
325 |
|
|
@code |
326 |
|
|
assert( decode_view( "Program%20Files" ).back() == 's' ); |
327 |
|
|
@endcode |
328 |
|
|
|
329 |
|
|
@par Preconditions |
330 |
|
|
@code |
331 |
|
|
not this->empty() |
332 |
|
|
@endcode |
333 |
|
|
|
334 |
|
|
@par Complexity |
335 |
|
|
Constant. |
336 |
|
|
|
337 |
|
|
@par Exception Safety |
338 |
|
|
Throws nothing. |
339 |
|
|
*/ |
340 |
|
|
reference |
341 |
|
|
back() const noexcept; |
342 |
|
|
|
343 |
|
|
/** Checks if the string begins with the given prefix |
344 |
|
|
|
345 |
|
|
@par Example |
346 |
|
|
@code |
347 |
|
|
assert( decode_view( "Program%20Files" ).starts_with("Program") ); |
348 |
|
|
@endcode |
349 |
|
|
|
350 |
|
|
@par Complexity |
351 |
|
|
Linear. |
352 |
|
|
|
353 |
|
|
@par Exception Safety |
354 |
|
|
Throws nothing. |
355 |
|
|
*/ |
356 |
|
|
BOOST_URL_DECL |
357 |
|
|
bool |
358 |
|
|
starts_with( core::string_view s ) const noexcept; |
359 |
|
|
|
360 |
|
|
/** Checks if the string ends with the given prefix |
361 |
|
|
|
362 |
|
|
@par Example |
363 |
|
|
@code |
364 |
|
|
assert( decode_view( "Program%20Files" ).ends_with("Files") ); |
365 |
|
|
@endcode |
366 |
|
|
|
367 |
|
|
@par Complexity |
368 |
|
|
Linear. |
369 |
|
|
|
370 |
|
|
@par Exception Safety |
371 |
|
|
Throws nothing. |
372 |
|
|
*/ |
373 |
|
|
BOOST_URL_DECL |
374 |
|
|
bool |
375 |
|
|
ends_with( core::string_view s ) const noexcept; |
376 |
|
|
|
377 |
|
|
/** Checks if the string begins with the given prefix |
378 |
|
|
|
379 |
|
|
@par Example |
380 |
|
|
@code |
381 |
|
|
assert( decode_view( "Program%20Files" ).starts_with('P') ); |
382 |
|
|
@endcode |
383 |
|
|
|
384 |
|
|
@par Complexity |
385 |
|
|
Constant. |
386 |
|
|
|
387 |
|
|
@par Exception Safety |
388 |
|
|
Throws nothing. |
389 |
|
|
*/ |
390 |
|
|
BOOST_URL_DECL |
391 |
|
|
bool |
392 |
|
|
starts_with( char ch ) const noexcept; |
393 |
|
|
|
394 |
|
|
/** Checks if the string ends with the given prefix |
395 |
|
|
|
396 |
|
|
@par Example |
397 |
|
|
@code |
398 |
|
|
assert( decode_view( "Program%20Files" ).ends_with('s') ); |
399 |
|
|
@endcode |
400 |
|
|
|
401 |
|
|
@par Complexity |
402 |
|
|
Constant. |
403 |
|
|
|
404 |
|
|
@par Exception Safety |
405 |
|
|
Throws nothing. |
406 |
|
|
*/ |
407 |
|
|
BOOST_URL_DECL |
408 |
|
|
bool |
409 |
|
|
ends_with( char ch ) const noexcept; |
410 |
|
|
|
411 |
|
|
/** Finds the first occurrence of character in this view |
412 |
|
|
|
413 |
|
|
@par Complexity |
414 |
|
|
Linear. |
415 |
|
|
|
416 |
|
|
@par Exception Safety |
417 |
|
|
Throws nothing. |
418 |
|
|
*/ |
419 |
|
|
BOOST_URL_DECL |
420 |
|
|
const_iterator |
421 |
|
|
find( char ch ) const noexcept; |
422 |
|
|
|
423 |
|
|
/** Finds the first occurrence of character in this view |
424 |
|
|
|
425 |
|
|
@par Complexity |
426 |
|
|
Linear. |
427 |
|
|
|
428 |
|
|
@par Exception Safety |
429 |
|
|
Throws nothing. |
430 |
|
|
*/ |
431 |
|
|
BOOST_URL_DECL |
432 |
|
|
const_iterator |
433 |
|
|
rfind( char ch ) const noexcept; |
434 |
|
|
|
435 |
|
|
/** Remove the first characters |
436 |
|
|
|
437 |
|
|
@par Example |
438 |
|
|
@code |
439 |
|
|
decode_view d( "Program%20Files" ); |
440 |
|
|
d.remove_prefix( 8 ); |
441 |
|
|
assert( d == "Files" ); |
442 |
|
|
@endcode |
443 |
|
|
|
444 |
|
|
@par Preconditions |
445 |
|
|
@code |
446 |
|
|
not this->empty() |
447 |
|
|
@endcode |
448 |
|
|
|
449 |
|
|
@par Complexity |
450 |
|
|
Linear. |
451 |
|
|
*/ |
452 |
|
|
BOOST_URL_DECL |
453 |
|
|
void |
454 |
|
|
remove_prefix( size_type n ); |
455 |
|
|
|
456 |
|
|
/** Remove the last characters |
457 |
|
|
|
458 |
|
|
@par Example |
459 |
|
|
@code |
460 |
|
|
decode_view d( "Program%20Files" ); |
461 |
|
|
d.remove_prefix( 6 ); |
462 |
|
|
assert( d == "Program" ); |
463 |
|
|
@endcode |
464 |
|
|
|
465 |
|
|
@par Preconditions |
466 |
|
|
@code |
467 |
|
|
not this->empty() |
468 |
|
|
@endcode |
469 |
|
|
|
470 |
|
|
@par Complexity |
471 |
|
|
Linear. |
472 |
|
|
*/ |
473 |
|
|
BOOST_URL_DECL |
474 |
|
|
void |
475 |
|
|
remove_suffix( size_type n ); |
476 |
|
|
|
477 |
|
|
/** Return the decoding options |
478 |
|
|
*/ |
479 |
|
|
encoding_opts |
480 |
|
|
options() const noexcept |
481 |
|
|
{ |
482 |
|
|
encoding_opts opt; |
483 |
|
|
opt.space_as_plus = space_as_plus_; |
484 |
|
|
return opt; |
485 |
|
|
} |
486 |
|
|
|
487 |
|
|
//-------------------------------------------- |
488 |
|
|
// |
489 |
|
|
// Comparison |
490 |
|
|
// |
491 |
|
|
//-------------------------------------------- |
492 |
|
|
|
493 |
|
|
/** Return the result of comparing to another string |
494 |
|
|
|
495 |
|
|
The length of the sequences to compare is the smaller of |
496 |
|
|
`size()` and `other.size()`. |
497 |
|
|
|
498 |
|
|
The function compares the two strings as if by calling |
499 |
|
|
`char_traits<char>::compare(to_string().data(), v.data(), rlen)`. |
500 |
|
|
This means the comparison is performed with |
501 |
|
|
percent-decoding applied to the current string. |
502 |
|
|
|
503 |
|
|
@param other string to compare |
504 |
|
|
|
505 |
|
|
@return Negative value if this string is less than the other |
506 |
|
|
character sequence, zero if the both character sequences are |
507 |
|
|
equal, positive value if this string is greater than the other |
508 |
|
|
character sequence |
509 |
|
|
*/ |
510 |
|
|
BOOST_URL_DECL |
511 |
|
|
int |
512 |
|
|
compare(core::string_view other) const noexcept; |
513 |
|
|
|
514 |
|
|
/** Return the result of comparing to another string |
515 |
|
|
|
516 |
|
|
The length of the sequences to compare is the smaller of |
517 |
|
|
`size()` and `other.size()`. |
518 |
|
|
|
519 |
|
|
The function compares the two strings as if by calling |
520 |
|
|
`char_traits<char>::compare(to_string().data(), v.to_string().data(), rlen)`. |
521 |
|
|
This means the comparison is performed with |
522 |
|
|
percent-decoding applied to the current string. |
523 |
|
|
|
524 |
|
|
@param other string to compare |
525 |
|
|
|
526 |
|
|
@return Negative value if this string is less than the other |
527 |
|
|
character sequence, zero if the both character sequences are |
528 |
|
|
equal, positive value if this string is greater than the other |
529 |
|
|
character sequence |
530 |
|
|
*/ |
531 |
|
|
BOOST_URL_DECL |
532 |
|
|
int |
533 |
|
|
compare(decode_view other) const noexcept; |
534 |
|
|
|
535 |
|
|
//-------------------------------------------- |
536 |
|
|
|
537 |
|
|
// relational operators |
538 |
|
|
#ifndef BOOST_URL_DOCS |
539 |
|
|
private: |
540 |
|
|
template<class S0, class S1> |
541 |
|
|
using is_match = std::integral_constant<bool, |
542 |
|
|
// both decode_view or convertible to core::string_view |
543 |
|
|
( |
544 |
|
|
std::is_same<typename std::decay<S0>::type, decode_view>::value || |
545 |
|
|
std::is_convertible<S0, core::string_view>::value) && |
546 |
|
|
( |
547 |
|
|
std::is_same<typename std::decay<S1>::type, decode_view>::value || |
548 |
|
|
std::is_convertible<S1, core::string_view>::value) && |
549 |
|
|
// not both are convertible to string view |
550 |
|
|
( |
551 |
|
|
!std::is_convertible<S0, core::string_view>::value || |
552 |
|
|
!std::is_convertible<S1, core::string_view>::value)>; |
553 |
|
|
|
554 |
|
|
static |
555 |
|
|
int |
556 |
|
316 |
decode_compare(decode_view s0, decode_view s1) noexcept |
557 |
|
|
{ |
558 |
|
316 |
return s0.compare(s1); |
559 |
|
|
} |
560 |
|
|
|
561 |
|
|
template <class S> |
562 |
|
|
static |
563 |
|
|
int |
564 |
|
5571 |
decode_compare(decode_view s0, S const& s1) noexcept |
565 |
|
|
{ |
566 |
|
5571 |
return s0.compare(s1); |
567 |
|
|
} |
568 |
|
|
|
569 |
|
|
template <class S> |
570 |
|
|
static |
571 |
|
|
int |
572 |
|
|
decode_compare(S const& s0, decode_view s1) noexcept |
573 |
|
|
{ |
574 |
|
|
return -s1.compare(s0); |
575 |
|
|
} |
576 |
|
|
public: |
577 |
|
|
|
578 |
|
|
template<class S0, class S1> |
579 |
|
3319 |
BOOST_CXX14_CONSTEXPR friend auto operator==( |
580 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
581 |
|
|
typename std::enable_if< |
582 |
|
|
is_match<S0, S1>::value, bool>::type |
583 |
|
|
{ |
584 |
|
3319 |
return decode_compare(s0, s1) == 0; |
585 |
|
|
} |
586 |
|
|
|
587 |
|
|
template<class S0, class S1> |
588 |
|
747 |
BOOST_CXX14_CONSTEXPR friend auto operator!=( |
589 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
590 |
|
|
typename std::enable_if< |
591 |
|
|
is_match<S0, S1>::value, bool>::type |
592 |
|
|
{ |
593 |
|
747 |
return decode_compare(s0, s1) != 0; |
594 |
|
|
} |
595 |
|
|
|
596 |
|
|
template<class S0, class S1> |
597 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator<( |
598 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
599 |
|
|
typename std::enable_if< |
600 |
|
|
is_match<S0, S1>::value, bool>::type |
601 |
|
|
{ |
602 |
|
16 |
return decode_compare(s0, s1) < 0; |
603 |
|
|
} |
604 |
|
|
|
605 |
|
|
template<class S0, class S1> |
606 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator<=( |
607 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
608 |
|
|
typename std::enable_if< |
609 |
|
|
is_match<S0, S1>::value, bool>::type |
610 |
|
|
{ |
611 |
|
16 |
return decode_compare(s0, s1) <= 0; |
612 |
|
|
} |
613 |
|
|
|
614 |
|
|
template<class S0, class S1> |
615 |
|
16 |
BOOST_CXX14_CONSTEXPR friend auto operator>( |
616 |
|
|
S0 const& s0, S1 const& s1) noexcept -> |
617 |
|
|
typename std::enable_if< |
618 |
|
|
is_match<S0, S1>::value, bool>::type |
619 |
|
|
{ |
620 |
|
16 |
return decode_compare(s0, s1) > 0; |
621 |
|
|
} |
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 |
|
|
#endif |
632 |
|
|
|
633 |
|
|
// hidden friend |
634 |
|
|
friend |
635 |
|
|
std::ostream& |
636 |
|
2 |
operator<<( |
637 |
|
|
std::ostream& os, |
638 |
|
|
decode_view const& s) |
639 |
|
|
{ |
640 |
|
|
// hidden friend |
641 |
|
2 |
s.write(os); |
642 |
|
2 |
return os; |
643 |
|
|
} |
644 |
|
|
|
645 |
|
|
private: |
646 |
|
|
BOOST_URL_DECL |
647 |
|
|
void |
648 |
|
|
write(std::ostream& os) const; |
649 |
|
|
}; |
650 |
|
|
|
651 |
|
|
/** Format the string with percent-decoding applied to the output stream |
652 |
|
|
|
653 |
|
|
This function serializes the decoded view |
654 |
|
|
to the output stream. |
655 |
|
|
|
656 |
|
|
@return A reference to the output stream, for chaining |
657 |
|
|
|
658 |
|
|
@param os The output stream to write to |
659 |
|
|
|
660 |
|
|
@param s The decoded view to write |
661 |
|
|
*/ |
662 |
|
|
inline |
663 |
|
|
std::ostream& |
664 |
|
|
operator<<( |
665 |
|
|
std::ostream& os, |
666 |
|
|
decode_view const& s); |
667 |
|
|
|
668 |
|
|
//------------------------------------------------ |
669 |
|
|
|
670 |
|
|
inline |
671 |
|
|
decode_view |
672 |
|
3697 |
pct_string_view::operator*() const noexcept |
673 |
|
|
{ |
674 |
|
3697 |
return decode_view(*this); |
675 |
|
|
} |
676 |
|
|
|
677 |
|
|
#ifndef BOOST_URL_DOCS |
678 |
|
|
namespace detail { |
679 |
|
|
template<class... Args> |
680 |
|
|
decode_view |
681 |
|
|
make_decode_view( |
682 |
|
|
Args&&... args) noexcept |
683 |
|
|
{ |
684 |
|
|
return decode_view( |
685 |
|
|
std::forward<Args>(args)...); |
686 |
|
|
} |
687 |
|
|
} // detail |
688 |
|
|
#endif |
689 |
|
|
|
690 |
|
|
//------------------------------------------------ |
691 |
|
|
|
692 |
|
|
} // urls |
693 |
|
|
} // boost |
694 |
|
|
|
695 |
|
|
#include <boost/url/impl/decode_view.hpp> |
696 |
|
|
|
697 |
|
|
#endif |
698 |
|
|
|