Line data Source code
1 : //
2 : // Copyright (c) 2022 Vinnie Falco (vinnie.falco@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_GRAMMAR_STRING_VIEW_BASE_HPP
11 : #define BOOST_URL_GRAMMAR_STRING_VIEW_BASE_HPP
12 :
13 : #include <boost/url/detail/config.hpp>
14 : #include <boost/url/detail/string_view.hpp>
15 : #include <boost/core/detail/string_view.hpp>
16 : #include <cstddef>
17 : #include <iterator>
18 : #include <string>
19 : #include <type_traits>
20 : #include <utility>
21 :
22 : namespace boost {
23 : namespace urls {
24 : namespace grammar {
25 :
26 : /** Common functionality for string views
27 :
28 : This base class is used to provide common
29 : member functions for reference types that
30 : behave like string views. This cannot be
31 : instantiated directly; instead, derive
32 : from the type and provide constructors
33 : which offer any desired preconditions
34 : and invariants.
35 : */
36 : class string_view_base
37 : {
38 : protected:
39 : /** The referenced character buffer
40 : */
41 : core::string_view s_;
42 :
43 : /** Constructor
44 :
45 : @param s The string view
46 : */
47 : constexpr
48 : string_view_base(
49 : core::string_view s) noexcept
50 : : s_(s)
51 : {
52 : }
53 :
54 : /** Constructor
55 :
56 : @param data The character buffer
57 : @param size The number of characters
58 : */
59 : constexpr
60 35047 : string_view_base(
61 : char const* data,
62 : std::size_t size) noexcept
63 35047 : : s_(data, size)
64 : {
65 35047 : }
66 :
67 : /** Swap
68 :
69 : @param s The object to swap with
70 : */
71 : // VFALCO No idea why this fails in msvc
72 : /*BOOST_CXX14_CONSTEXPR*/
73 : void
74 : swap(
75 : string_view_base& s ) noexcept
76 : {
77 : std::swap(s_, s.s_);
78 : }
79 :
80 : /** Constructor
81 : */
82 16730 : string_view_base() = default;
83 :
84 : /** Constructor
85 : */
86 : string_view_base(
87 : string_view_base const&) = default;
88 :
89 : /** Assignment
90 :
91 : @param other The object to assign
92 : @return A reference to this object
93 : */
94 : string_view_base& operator=(
95 : string_view_base const& other) = default;
96 :
97 : public:
98 : /// The character traits
99 : typedef std::char_traits<char> traits_type;
100 : /// The value type
101 : typedef char value_type;
102 : /// The pointer type
103 : typedef char* pointer;
104 : /// The const pointer type
105 : typedef char const* const_pointer;
106 : /// The reference type
107 : typedef char& reference;
108 : /// The const reference type
109 : typedef char const& const_reference;
110 : /// The const iterator type
111 : typedef char const* const_iterator;
112 : /// The iterator type
113 : typedef const_iterator iterator;
114 : /// The const reverse iterator type
115 : typedef std::reverse_iterator<
116 : const_iterator> const_reverse_iterator;
117 : /// The reverse iterator type
118 : typedef const_reverse_iterator reverse_iterator;
119 : /// The size type
120 : typedef std::size_t size_type;
121 : /// The difference type
122 : typedef std::ptrdiff_t difference_type;
123 :
124 : /// A constant used to represent "no position"
125 : static constexpr std::size_t npos = core::string_view::npos;
126 :
127 : //--------------------------------------------
128 :
129 : /** Conversion
130 :
131 : @return A string view with the same contents
132 : */
133 12059 : operator
134 : core::string_view() const noexcept
135 : {
136 12059 : return s_;
137 : }
138 :
139 : /** Conversion
140 :
141 : @return A string view with the same contents
142 : */
143 : #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
144 : operator
145 : std::string_view() const noexcept
146 : {
147 : return std::string_view(s_);
148 : }
149 : #endif
150 :
151 : /** Conversion
152 :
153 : Conversion to std::string is explicit
154 : because assigning to string using an
155 : implicit constructor does not preserve
156 : capacity.
157 :
158 : @return A string with the same contents
159 : */
160 : explicit
161 47 : operator
162 : std::string() const noexcept
163 : {
164 47 : return std::string(s_);
165 : }
166 :
167 : //--------------------------------------------
168 :
169 : // iterator support
170 :
171 : /** Return an iterator to the beginning
172 :
173 : See `core::string_view::begin`
174 :
175 : @return An iterator to the beginning
176 : */
177 359 : BOOST_CONSTEXPR const_iterator begin() const noexcept
178 : {
179 359 : return s_.begin();
180 : }
181 :
182 : /** Return an iterator to the end
183 :
184 : See `core::string_view::end`
185 :
186 : @return An iterator to the end
187 : */
188 359 : BOOST_CONSTEXPR const_iterator end() const noexcept
189 : {
190 359 : return s_.end();
191 : }
192 :
193 : /** Return an iterator to the beginning
194 :
195 : See `core::string_view::cbegin`
196 :
197 : @return An iterator to the beginning
198 : */
199 : BOOST_CONSTEXPR const_iterator cbegin() const noexcept
200 : {
201 : return s_.cbegin();
202 : }
203 :
204 : /** Return an iterator to the end
205 :
206 : See `core::string_view::cend`
207 :
208 : @return An iterator to the end
209 : */
210 : BOOST_CONSTEXPR const_iterator cend() const noexcept
211 : {
212 : return s_.cend();
213 : }
214 :
215 : /** Return a reverse iterator to the end
216 :
217 : See `core::string_view::rbegin`
218 :
219 : @return A reverse iterator to the end
220 : */
221 : BOOST_URL_LIB_ARRAY_CONSTEXPR
222 : const_reverse_iterator rbegin() const noexcept
223 : {
224 : return s_.rbegin();
225 : }
226 :
227 : /** Return a reverse iterator to the beginning
228 :
229 : See `core::string_view::rend`
230 :
231 : @return A reverse iterator to the beginning
232 : */
233 : BOOST_URL_LIB_ARRAY_CONSTEXPR
234 : const_reverse_iterator rend() const noexcept
235 : {
236 : return s_.rend();
237 : }
238 :
239 : /** Return a reverse iterator to the end
240 :
241 : See `core::string_view::crbegin`
242 :
243 : @return A reverse iterator to the end
244 : */
245 : BOOST_URL_LIB_ARRAY_CONSTEXPR
246 : const_reverse_iterator crbegin() const noexcept
247 : {
248 : return s_.crbegin();
249 : }
250 :
251 : /** Return a reverse iterator to the beginning
252 :
253 : See `core::string_view::crend`
254 :
255 : @return A reverse iterator to the beginning
256 : */
257 : BOOST_URL_LIB_ARRAY_CONSTEXPR
258 : const_reverse_iterator crend() const noexcept
259 : {
260 : return s_.crend();
261 : }
262 :
263 : // capacity
264 :
265 : /** Return the size
266 :
267 : See `core::string_view::size`
268 :
269 : @return The size
270 : */
271 7265 : BOOST_CONSTEXPR size_type size() const noexcept
272 : {
273 7265 : return s_.size();
274 : }
275 :
276 : /** Return the size
277 :
278 : See `core::string_view::length`
279 :
280 : @return The size
281 : */
282 : BOOST_CONSTEXPR size_type length() const noexcept
283 : {
284 : return s_.length();
285 : }
286 :
287 : /** Return the maximum allowed size
288 :
289 : See `core::string_view::max_size`
290 :
291 : @return The maximum allowed size
292 : */
293 : BOOST_CONSTEXPR size_type max_size() const noexcept
294 : {
295 : return s_.max_size();
296 : }
297 :
298 : /** Return true if the string is empty
299 :
300 : See `core::string_view::size`
301 :
302 : @return `true` if the string is empty
303 : */
304 5022 : BOOST_CONSTEXPR bool empty() const noexcept
305 : {
306 5022 : return s_.empty();
307 : }
308 :
309 : // element access
310 :
311 : /** Access a character
312 :
313 : See `core::string_view::operator[]`
314 :
315 : @param pos The position to access
316 : @return The character at the position
317 : */
318 : BOOST_CXX14_CONSTEXPR const_reference
319 25 : operator[]( size_type pos ) const noexcept
320 : {
321 25 : return s_[pos];
322 : }
323 :
324 : /** Access a character
325 :
326 : See `core::string_view::at`
327 :
328 : @param pos The position to access
329 : @return The character at the position
330 : */
331 : BOOST_CXX14_CONSTEXPR const_reference
332 : at( size_type pos ) const
333 : {
334 : return s_.at(pos);
335 : }
336 :
337 : /** Return the first character
338 :
339 : See `core::string_view::front`
340 :
341 : @return The first character
342 : */
343 : BOOST_CXX14_CONSTEXPR const_reference
344 80 : front() const noexcept
345 : {
346 80 : return s_.front();
347 : }
348 :
349 : /** Return the last character
350 :
351 : See `core::string_view::back`
352 :
353 : @return The last character
354 : */
355 : BOOST_CXX14_CONSTEXPR const_reference
356 17 : back() const noexcept
357 : {
358 17 : return s_.back();
359 : }
360 :
361 : /** Return a pointer to the character buffer
362 :
363 : See `core::string_view::data`
364 :
365 : @return A pointer to the character buffer
366 : */
367 : BOOST_CONSTEXPR const_pointer
368 692 : data() const noexcept
369 : {
370 692 : return s_.data();
371 : }
372 :
373 : // string operations
374 :
375 : /** Copy the characters to another buffer
376 :
377 : See `core::string_view::copy`
378 :
379 : @param s The destination buffer
380 : @param n The number of characters to copy
381 : @param pos The position to start from
382 : @return The number of characters copied
383 : */
384 : BOOST_CXX14_CONSTEXPR size_type copy(
385 : char* s, size_type n, size_type pos = 0 ) const
386 : {
387 : return s_.copy(s, n, pos);
388 : }
389 :
390 : /** Return a view to part of the string
391 :
392 : See `core::string_view::substr`
393 :
394 : @param pos The position to start from
395 : @param n The number of characters
396 : @return A view to the substring
397 : */
398 10134 : BOOST_CXX14_CONSTEXPR core::string_view substr(
399 : size_type pos = 0, size_type n = core::string_view::npos ) const
400 : {
401 10134 : return s_.substr(pos, n);
402 : }
403 :
404 : // comparison
405 :
406 : /** Return the result of comparing to another string
407 :
408 : See `core::string_view::compare`
409 :
410 : @param str The string to compare
411 : @return The result of the comparison
412 : */
413 : BOOST_CXX14_CONSTEXPR int
414 : compare( core::string_view str ) const noexcept
415 : {
416 : return s_.compare(str);
417 : }
418 :
419 : /** Return the result of comparing to another string
420 :
421 : See `core::string_view::compare`
422 :
423 : @param pos1 The position to start comparing from
424 : @param n1 The number of characters to compare
425 : @param str The string to compare
426 : @return The result of the comparison
427 : */
428 : BOOST_CONSTEXPR int compare(
429 : size_type pos1, size_type n1, core::string_view str ) const
430 : {
431 : return s_.compare(pos1, n1, str);
432 : }
433 :
434 : /** Return the result of comparing to another string
435 :
436 : See `core::string_view::compare`
437 :
438 : @param pos1 The position to start comparing from
439 : @param n1 The number of characters to compare
440 : @param str The string to compare
441 : @param pos2 The position to start comparing from
442 : @param n2 The number of characters to compare
443 : @return The result of the comparison
444 : */
445 : BOOST_CONSTEXPR int compare(
446 : size_type pos1, size_type n1, core::string_view str,
447 : size_type pos2, size_type n2 ) const
448 : {
449 : return s_.compare(pos1, n1, str, pos2, n2);
450 : }
451 :
452 : /** Return the result of comparing to another string
453 :
454 : See `core::string_view::compare`
455 :
456 : @param s The string to compare
457 : @return The result of the comparison
458 : */
459 : BOOST_CONSTEXPR int compare(
460 : char const* s ) const noexcept
461 : {
462 : return s_.compare(s);
463 : }
464 :
465 : /** Return the result of comparing to another string
466 :
467 : See `core::string_view::compare`
468 :
469 : @param pos1 The position to start comparing from
470 : @param n1 The number of characters to compare
471 : @param s The string to compare
472 : @return The result of the comparison
473 : */
474 : BOOST_CONSTEXPR int compare(
475 : size_type pos1, size_type n1, char const* s ) const
476 : {
477 : return s_.compare(pos1, n1, s);
478 : }
479 :
480 : /** Return the result of comparing to another string
481 :
482 : See `core::string_view::compare`
483 :
484 : @param pos1 The position to start comparing from
485 : @param n1 The number of characters to compare
486 : @param s The string to compare
487 : @param n2 The number of characters to compare
488 : @return The result of the comparison
489 : */
490 : BOOST_CONSTEXPR int compare(
491 : size_type pos1, size_type n1,
492 : char const* s, size_type n2 ) const
493 : {
494 : return s_.compare(pos1, n1, s, n2);
495 : }
496 :
497 : // starts_with
498 :
499 : /** Return true if a matching prefix exists
500 :
501 : See `core::string_view::starts_with`
502 :
503 : @param x The string to search for
504 : @return `true` if the prefix matches
505 : */
506 : BOOST_CONSTEXPR bool starts_with(
507 : core::string_view x ) const noexcept
508 : {
509 : return s_.starts_with(x);
510 : }
511 :
512 : /** Return true if a matching prefix exists
513 :
514 : See `core::string_view::starts_with`
515 :
516 : @param x The character to search for
517 : @return `true` if the prefix matches
518 : */
519 602 : BOOST_CONSTEXPR bool starts_with(
520 : char x ) const noexcept
521 : {
522 602 : return s_.starts_with(x);
523 : }
524 :
525 : /** Return true if a matching prefix exists
526 :
527 : See `core::string_view::starts_with`
528 :
529 : @param x The string to search for
530 : @return `true` if the prefix matches
531 : */
532 235 : BOOST_CONSTEXPR bool starts_with(
533 : char const* x ) const noexcept
534 : {
535 235 : return s_.starts_with(x);
536 : }
537 :
538 : // ends_with
539 :
540 : /** Return true if a matching suffix exists
541 :
542 : See `core::string_view::ends_with`
543 :
544 : @param x The string to search for
545 : @return `true` if the suffix matches
546 : */
547 : BOOST_CONSTEXPR bool ends_with(
548 : core::string_view x ) const noexcept
549 : {
550 : return s_.ends_with(x);
551 : }
552 :
553 : /** Return true if a matching suffix exists
554 :
555 : See `core::string_view::ends_with`
556 :
557 : @param x The character to search for
558 : @return `true` if the suffix matches
559 : */
560 549 : BOOST_CONSTEXPR bool ends_with(
561 : char x ) const noexcept
562 : {
563 549 : return s_.ends_with(x);
564 : }
565 :
566 : /** Return true if a matching suffix exists
567 :
568 : See `core::string_view::ends_with`
569 :
570 : @param x The string to search for
571 : @return `true` if the suffix matches
572 : */
573 : BOOST_CONSTEXPR bool ends_with(
574 : char const* x ) const noexcept
575 : {
576 : return s_.ends_with(x);
577 : }
578 :
579 : // find
580 :
581 : /** Return the position of matching characters
582 :
583 : See `core::string_view::find`
584 :
585 : @param str The characters to search for
586 : @param pos The position to start searching from
587 : @return The position of the first match
588 : */
589 : BOOST_CONSTEXPR size_type find(
590 : core::string_view str, size_type pos = 0 ) const noexcept
591 : {
592 : return s_.find(str, pos);
593 : }
594 :
595 : /** Return the position of matching characters
596 :
597 : See `core::string_view::find`
598 :
599 : @param c The character to search for
600 : @param pos The position to start searching from
601 : @return The position of the first match
602 : */
603 10 : BOOST_CXX14_CONSTEXPR size_type find(
604 : char c, size_type pos = 0 ) const noexcept
605 : {
606 10 : return s_.find(c, pos);
607 : }
608 :
609 : /** Return the position of matching characters
610 :
611 : See `core::string_view::find`
612 :
613 : @param s The characters to search for
614 : @param pos The position to start searching from
615 : @param n The number of characters to search for
616 : @return The position of the first match
617 : */
618 : BOOST_CXX14_CONSTEXPR size_type find(
619 : char const* s, size_type pos, size_type n ) const noexcept
620 : {
621 : return s_.find(s, pos, n);
622 : }
623 :
624 : /** Return the position of matching characters
625 :
626 : See `core::string_view::find`
627 :
628 : @param s The characters to search for
629 : @param pos The position to start searching from
630 : @return The position of the first match
631 : */
632 : BOOST_CONSTEXPR size_type find(
633 : char const* s, size_type pos = 0 ) const noexcept
634 : {
635 : return s_.find(s, pos);
636 : }
637 :
638 : // rfind
639 :
640 : /** Return the position of matching characters
641 :
642 : See `core::string_view::rfind`
643 :
644 : @param str The characters to search for
645 : @param pos The position to start searching from
646 : @return The position of the first match
647 : */
648 : BOOST_CONSTEXPR size_type rfind(
649 : core::string_view str, size_type pos = core::string_view::npos ) const noexcept
650 : {
651 : return s_.rfind(str, pos);
652 : }
653 :
654 : /** Return the position of matching characters
655 :
656 : See `core::string_view::rfind`
657 :
658 : @param c The character to search for
659 : @param pos The position to start searching from
660 : @return The position of the first match
661 : */
662 : BOOST_CXX14_CONSTEXPR size_type rfind(
663 : char c, size_type pos = core::string_view::npos ) const noexcept
664 : {
665 : return s_.rfind(c, pos);
666 : }
667 :
668 : /** Return the position of matching characters
669 :
670 : See `core::string_view::rfind`
671 :
672 : @param s The characters to search for
673 : @param pos The position to start searching from
674 : @param n The number of characters to search for
675 : @return The position of the first match
676 : */
677 : BOOST_CXX14_CONSTEXPR size_type rfind(
678 : char const* s, size_type pos, size_type n ) const noexcept
679 : {
680 : return s_.rfind(s, pos, n);
681 : }
682 :
683 : /** Return the position of matching characters
684 :
685 : See `core::string_view::rfind`
686 :
687 : @param s The characters to search for
688 : @param pos The position to start searching from
689 : @return The position of the first match
690 : */
691 : BOOST_CONSTEXPR size_type rfind(
692 : char const* s, size_type pos = core::string_view::npos ) const noexcept
693 : {
694 : return s_.rfind(s, pos);
695 : }
696 :
697 : // find_first_of
698 :
699 : /** Return the position of the first match
700 :
701 : See `core::string_view::find_first_of`
702 :
703 : @param str The characters to search for
704 : @param pos The position to start searching from
705 : @return The position of the first match
706 : */
707 : BOOST_CXX14_CONSTEXPR size_type find_first_of(
708 : core::string_view str, size_type pos = 0 ) const noexcept
709 : {
710 : return s_.find_first_of(str, pos);
711 : }
712 :
713 : /** Return the position of the first match
714 :
715 : See `core::string_view::find_first_of`
716 :
717 : @param c The character to search for
718 : @param pos The position to start searching from
719 : @return The position of the first match
720 : */
721 52 : BOOST_CONSTEXPR size_type find_first_of(
722 : char c, size_type pos = 0 ) const noexcept
723 : {
724 52 : return s_.find_first_of(c, pos);
725 : }
726 :
727 : /** Return the position of the first match
728 :
729 : See `core::string_view::find_first_of`
730 :
731 : @param s The characters to search for
732 : @param pos The position to start searching from
733 : @param n The number of characters to search for
734 : @return The position of the first match
735 : */
736 : BOOST_CXX14_CONSTEXPR size_type find_first_of(
737 : char const* s, size_type pos, size_type n ) const noexcept
738 : {
739 : return s_.find_first_of(s, pos, n);
740 : }
741 :
742 : /** Return the position of the first match
743 :
744 : See `core::string_view::find_first_of`
745 :
746 : @param s The characters to search for
747 : @param pos The position to start searching from
748 : @return The position of the first match
749 : */
750 5 : BOOST_CXX14_CONSTEXPR size_type find_first_of(
751 : char const* s, size_type pos = 0 ) const noexcept
752 : {
753 5 : return s_.find_first_of(s, pos);
754 : }
755 :
756 : // find_last_of
757 :
758 : /** Return the position of the last match
759 :
760 : See `core::string_view::find_last_of`
761 :
762 : @param str The characters to search for
763 : @param pos The position to start searching from
764 : @return The position of the last match
765 : */
766 : BOOST_CXX14_CONSTEXPR size_type find_last_of(
767 : core::string_view str, size_type pos = core::string_view::npos ) const noexcept
768 : {
769 : return s_.find_last_of(str, pos);
770 : }
771 :
772 : /** Return the position of the last match
773 :
774 : See `core::string_view::find_last_of`
775 :
776 : @param c The character to search for
777 : @param pos The position to start searching from
778 : @return The position of the last match
779 : */
780 : BOOST_CONSTEXPR size_type find_last_of(
781 : char c, size_type pos = core::string_view::npos ) const noexcept
782 : {
783 : return s_.find_last_of(c, pos);
784 : }
785 :
786 : /** Return the position of the last match
787 :
788 : See `core::string_view::find_last_of`
789 :
790 : @param s The characters to search for
791 : @param pos The position to start searching from
792 : @param n The number of characters to search for
793 : @return The position of the last match
794 : */
795 : BOOST_CXX14_CONSTEXPR size_type find_last_of(
796 : char const* s, size_type pos, size_type n ) const noexcept
797 : {
798 : return s_.find_last_of(s, pos, n);
799 : }
800 :
801 : /** Return the position of the last match
802 :
803 : See `core::string_view::find_last_of`
804 :
805 : @param s The characters to search for
806 : @param pos The position to start searching from
807 : @return The position of the last match
808 : */
809 : BOOST_CXX14_CONSTEXPR size_type find_last_of(
810 : char const* s, size_type pos = core::string_view::npos ) const noexcept
811 : {
812 : return s_.find_last_of(s, pos);
813 : }
814 :
815 : // find_first_not_of
816 :
817 : /** Return the position of the first non-match
818 :
819 : See `core::string_view::find_first_not_of`
820 :
821 : @param str The characters to search for
822 : @param pos The position to start searching from
823 : @return The position of the first non-match
824 : */
825 : BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
826 : core::string_view str, size_type pos = 0 ) const noexcept
827 : {
828 : return s_.find_first_not_of(str, pos);
829 : }
830 :
831 : /** Return the position of the first non-match
832 :
833 : See `core::string_view::find_first_not_of`
834 :
835 : @param c The character to search for
836 : @param pos The position to start searching from
837 : @return The position of the first non-match
838 : */
839 : BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
840 : char c, size_type pos = 0 ) const noexcept
841 : {
842 : return s_.find_first_not_of(c, pos);
843 : }
844 :
845 : /** Return the position of the first non-match
846 :
847 : See `core::string_view::find_first_not_of`
848 :
849 : @param s The characters to search for
850 : @param pos The position to start searching from
851 : @param n The number of characters to search for
852 : @return The position of the first non-match
853 : */
854 : BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
855 : char const* s, size_type pos, size_type n ) const noexcept
856 : {
857 : return s_.find_first_not_of(s, pos, n);
858 : }
859 :
860 : /** Return the position of the first non-match
861 :
862 : See `core::string_view::find_first_not_of`
863 :
864 : @param s The characters to search for
865 : @param pos The position to start searching from
866 : @return The position of the first non-match
867 : */
868 : BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
869 : char const* s, size_type pos = 0 ) const noexcept
870 : {
871 : return s_.find_first_not_of(s, pos);
872 : }
873 :
874 : // find_last_not_of
875 :
876 : /** Return the position of the last non-match
877 :
878 : See `core::string_view::find_last_not_of`
879 :
880 : @param str The characters to search for
881 : @param pos The position to start searching from
882 : @return The position of the last non-match
883 : */
884 : BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
885 : core::string_view str, size_type pos = core::string_view::npos ) const noexcept
886 : {
887 : return s_.find_last_not_of(str, pos);
888 : }
889 :
890 : /** Return the position of the last non-match
891 :
892 : See `core::string_view::find_last_not_of`
893 :
894 : @param c The character to search for
895 : @param pos The position to start searching from
896 : @return The position of the last non-match
897 : */
898 : BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
899 : char c, size_type pos = core::string_view::npos ) const noexcept
900 : {
901 : return s_.find_last_not_of(c, pos);
902 : }
903 :
904 : /** Return the position of the last non-match
905 :
906 : See `core::string_view::find_last_not_of`
907 :
908 : @param s The characters to search for
909 : @param pos The position to start searching from
910 : @param n The number of characters to search for
911 : @return The position of the last non-match
912 : */
913 : BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
914 : char const* s, size_type pos, size_type n ) const noexcept
915 : {
916 : return s_.find_last_not_of(s, pos, n);
917 : }
918 :
919 : /** Return the position of the last non-match
920 :
921 : See `core::string_view::find_last_not_of`
922 :
923 : @param s The characters to search for
924 : @param pos The position to start searching from
925 : @return The position of the last non-match
926 : */
927 : BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
928 : char const* s, size_type pos = core::string_view::npos ) const noexcept
929 : {
930 : return s_.find_last_not_of(s, pos);
931 : }
932 :
933 : // contains
934 :
935 : /** Return true if matching characters are found
936 :
937 : See `core::string_view::contains`
938 :
939 : @param sv The string to search for
940 : @return `true` if the string contains the characters, otherwise `false`
941 : */
942 : BOOST_CONSTEXPR bool contains( core::string_view sv ) const noexcept
943 : {
944 : return s_.contains(sv);
945 : }
946 :
947 : /** Return true if matching characters are found
948 :
949 : See `core::string_view::contains`
950 :
951 : @param c The character to search for
952 : @return `true` if the string contains the character, otherwise `false`
953 : */
954 5 : BOOST_CXX14_CONSTEXPR bool contains( char c ) const noexcept
955 : {
956 5 : return s_.contains(c);
957 : }
958 :
959 : /** Return true if matching characters are found
960 :
961 : See `core::string_view::contains`
962 :
963 : @param s The string to search for
964 : @return `true` if the string contains the characters, otherwise `false`
965 : */
966 : BOOST_CONSTEXPR bool contains( char const* s ) const noexcept
967 : {
968 : return s_.contains(s);
969 : }
970 :
971 : // relational operators
972 : #ifndef BOOST_URL_DOCS
973 : private:
974 : template<class S0, class S1>
975 : using is_match = std::integral_constant<bool,
976 : std::is_convertible<S0, core::string_view>::value &&
977 : std::is_convertible<S1, core::string_view>::value && (
978 : (std::is_base_of<string_view_base,
979 : typename std::decay<S0>::type>::value &&
980 : std::is_convertible<S0 const volatile*,
981 : string_view_base const volatile*>::value) ||
982 : (std::is_base_of<string_view_base,
983 : typename std::decay<S1>::type>::value &&
984 : std::is_convertible<S1 const volatile*,
985 : string_view_base const volatile*>::value))>;
986 : public:
987 :
988 : /** Compare two string views for equality
989 :
990 : This function is only enabled if both arguments
991 : are convertible to `core::string_view` and at least
992 : one of the arguments is derived from `string_view_base`.
993 :
994 : @param s0 The first string
995 : @param s1 The second string
996 : @return `true` if the strings are equal, otherwise `false`
997 : */
998 : template<class S0, class S1>
999 3048 : BOOST_CXX14_CONSTEXPR friend auto operator==(
1000 : S0 const& s0, S1 const& s1) noexcept ->
1001 : typename std::enable_if<
1002 : is_match<S0, S1>::value, bool>::type
1003 : {
1004 3048 : return urls::detail::to_sv(s0) == urls::detail::to_sv(s1);
1005 : }
1006 :
1007 : /** Compare two string views for inequality
1008 :
1009 : This function is only enabled if both arguments
1010 : are convertible to `core::string_view` and at least
1011 : one of the arguments is derived from `string_view_base`.
1012 :
1013 : @param s0 The first string
1014 : @param s1 The second string
1015 : @return `true` if the strings are not equal, otherwise `false`
1016 : */
1017 : template<class S0, class S1>
1018 73 : BOOST_CXX14_CONSTEXPR friend auto operator!=(
1019 : S0 const& s0, S1 const& s1) noexcept ->
1020 : typename std::enable_if<
1021 : is_match<S0, S1>::value, bool>::type
1022 : {
1023 73 : return urls::detail::to_sv(s0) != urls::detail::to_sv(s1);
1024 : }
1025 :
1026 : /** Compare two string views for less than
1027 :
1028 : This function is only enabled if both arguments
1029 : are convertible to `core::string_view` and at least
1030 : one of the arguments is derived from `string_view_base`.
1031 :
1032 : @param s0 The first string
1033 : @param s1 The second string
1034 : @return `true` if the first string is less than the second, otherwise `false`
1035 : */
1036 : template<class S0, class S1>
1037 7 : BOOST_CXX14_CONSTEXPR friend auto operator<(
1038 : S0 const& s0, S1 const& s1) noexcept ->
1039 : typename std::enable_if<
1040 : is_match<S0, S1>::value, bool>::type
1041 : {
1042 7 : return urls::detail::to_sv(s0) < urls::detail::to_sv(s1);
1043 : }
1044 :
1045 : /** Compare two string views for less than or equal
1046 :
1047 : This function is only enabled if both arguments
1048 : are convertible to `core::string_view` and at least
1049 : one of the arguments is derived from `string_view_base`.
1050 :
1051 : @param s0 The first string
1052 : @param s1 The second string
1053 : @return `true` if the first string is less than or equal to the second, otherwise `false`
1054 : */
1055 : template<class S0, class S1>
1056 7 : BOOST_CXX14_CONSTEXPR friend auto operator<=(
1057 : S0 const& s0, S1 const& s1) noexcept ->
1058 : typename std::enable_if<
1059 : is_match<S0, S1>::value, bool>::type
1060 : {
1061 7 : return urls::detail::to_sv(s0) <= urls::detail::to_sv(s1);
1062 : }
1063 :
1064 : /** Compare two string views for greater than
1065 :
1066 : This function is only enabled if both arguments
1067 : are convertible to `core::string_view` and at least
1068 : one of the arguments is derived from `string_view_base`.
1069 :
1070 : @param s0 The first string
1071 : @param s1 The second string
1072 : @return `true` if the first string is greater than the second, otherwise `false`
1073 : */
1074 : template<class S0, class S1>
1075 7 : BOOST_CXX14_CONSTEXPR friend auto operator>(
1076 : S0 const& s0, S1 const& s1) noexcept ->
1077 : typename std::enable_if<
1078 : is_match<S0, S1>::value, bool>::type
1079 : {
1080 7 : return urls::detail::to_sv(s0) > urls::detail::to_sv(s1);
1081 : }
1082 :
1083 : /** Compare two string views for greater than or equal
1084 :
1085 : This function is only enabled if both arguments
1086 : are convertible to `core::string_view` and at least
1087 : one of the arguments is derived from `string_view_base`.
1088 :
1089 : @param s0 The first string
1090 : @param s1 The second string
1091 : @return `true` if the first string is greater than or equal to the second, otherwise `false`
1092 : */
1093 : template<class S0, class S1>
1094 7 : BOOST_CXX14_CONSTEXPR friend auto operator>=(
1095 : S0 const& s0, S1 const& s1) noexcept ->
1096 : typename std::enable_if<
1097 : is_match<S0, S1>::value, bool>::type
1098 : {
1099 7 : return urls::detail::to_sv(s0) >= urls::detail::to_sv(s1);
1100 : }
1101 : #endif
1102 :
1103 : //--------------------------------------------
1104 :
1105 : /** Format a string to an output stream
1106 :
1107 : @param os The output stream to write to
1108 : @param s The string to write
1109 : @return A reference to the output stream, for chaining
1110 : */
1111 : BOOST_URL_DECL
1112 : friend
1113 : std::ostream&
1114 : operator<<(
1115 : std::ostream& os,
1116 : string_view_base const& s);
1117 : };
1118 :
1119 : //------------------------------------------------
1120 :
1121 : /** Format a string to an output stream
1122 : */
1123 : BOOST_URL_DECL
1124 : std::ostream&
1125 : operator<<(
1126 : std::ostream& os,
1127 : string_view_base const& s);
1128 :
1129 : } // grammar
1130 :
1131 : #ifndef BOOST_URL_DOCS
1132 : namespace detail {
1133 : template <>
1134 : inline
1135 : core::string_view
1136 32 : to_sv(grammar::string_view_base const& s) noexcept
1137 : {
1138 32 : return s.operator core::string_view();
1139 : }
1140 : } // detail
1141 : #endif
1142 :
1143 : } // urls
1144 : } // boost
1145 :
1146 : #endif
|