GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/string_view_base.hpp
Date: 2024-08-19 20:08:56
Exec Total Coverage
Lines: 54 54 100.0%
Functions: 60 60 100.0%
Branches: 0 0 -%

Line Branch Exec Source
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 constexpr
46 string_view_base(
47 core::string_view s) noexcept
48 : s_(s)
49 {
50 }
51
52 /** Constructor
53 */
54 constexpr
55 34583 string_view_base(
56 char const* data,
57 std::size_t size) noexcept
58 34583 : s_(data, size)
59 {
60 34583 }
61
62 /** Swap
63 */
64 // VFALCO No idea why this fails in msvc
65 /*BOOST_CXX14_CONSTEXPR*/ void swap(
66 string_view_base& s ) noexcept
67 {
68 std::swap(s_, s.s_);
69 }
70
71 /** Constructor
72 */
73 16491 string_view_base() = default;
74
75 /** Constructor
76 */
77 string_view_base(
78 string_view_base const&) = default;
79
80 /** Assignment
81 */
82 string_view_base& operator=(
83 string_view_base const&) = default;
84
85 public:
86 /// The character traits
87 typedef std::char_traits<char> traits_type;
88 /// The value type
89 typedef char value_type;
90 /// The pointer type
91 typedef char* pointer;
92 /// The const pointer type
93 typedef char const* const_pointer;
94 /// The reference type
95 typedef char& reference;
96 /// The const reference type
97 typedef char const& const_reference;
98 /// The const iterator type
99 typedef char const* const_iterator;
100 /// The iterator type
101 typedef const_iterator iterator;
102 /// The const reverse iterator type
103 typedef std::reverse_iterator<
104 const_iterator> const_reverse_iterator;
105 /// The reverse iterator type
106 typedef const_reverse_iterator reverse_iterator;
107 /// The size type
108 typedef std::size_t size_type;
109 /// The difference type
110 typedef std::ptrdiff_t difference_type;
111
112 /// A constant used to represent "no position"
113 static constexpr std::size_t npos = core::string_view::npos;
114
115 //--------------------------------------------
116
117 /** Conversion
118 */
119 11874 operator
120 core::string_view() const noexcept
121 {
122 11874 return s_;
123 }
124
125 /** Conversion
126 */
127 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
128 operator
129 std::string_view() const noexcept
130 {
131 return std::string_view(s_);
132 }
133 #endif
134
135 /** Conversion
136
137 Conversion to std::string is explicit
138 because assigning to string using an
139 implicit constructor does not preserve
140 capacity.
141 */
142 explicit
143 47 operator
144 std::string() const noexcept
145 {
146 47 return std::string(s_);
147 }
148
149 //--------------------------------------------
150
151 // iterator support
152
153 /** Return an iterator to the beginning
154
155 See `core::string_view::begin`
156 */
157 347 BOOST_CONSTEXPR const_iterator begin() const noexcept
158 {
159 347 return s_.begin();
160 }
161
162 /** Return an iterator to the end
163
164 See `core::string_view::end`
165 */
166 347 BOOST_CONSTEXPR const_iterator end() const noexcept
167 {
168 347 return s_.end();
169 }
170
171 /** Return an iterator to the beginning
172
173 See `core::string_view::cbegin`
174 */
175 BOOST_CONSTEXPR const_iterator cbegin() const noexcept
176 {
177 return s_.cbegin();
178 }
179
180 /** Return an iterator to the end
181
182 See `core::string_view::cend`
183 */
184 BOOST_CONSTEXPR const_iterator cend() const noexcept
185 {
186 return s_.cend();
187 }
188
189 /** Return a reverse iterator to the end
190
191 See `core::string_view::rbegin`
192 */
193 BOOST_URL_LIB_ARRAY_CONSTEXPR
194 const_reverse_iterator rbegin() const noexcept
195 {
196 return s_.rbegin();
197 }
198
199 /** Return a reverse iterator to the beginning
200
201 See `core::string_view::rend`
202 */
203 BOOST_URL_LIB_ARRAY_CONSTEXPR
204 const_reverse_iterator rend() const noexcept
205 {
206 return s_.rend();
207 }
208
209 /** Return a reverse iterator to the end
210
211 See `core::string_view::crbegin`
212 */
213 BOOST_URL_LIB_ARRAY_CONSTEXPR
214 const_reverse_iterator crbegin() const noexcept
215 {
216 return s_.crbegin();
217 }
218
219 /** Return a reverse iterator to the beginning
220
221 See `core::string_view::crend`
222 */
223 BOOST_URL_LIB_ARRAY_CONSTEXPR
224 const_reverse_iterator crend() const noexcept
225 {
226 return s_.crend();
227 }
228
229 // capacity
230
231 /** Return the size
232
233 See `core::string_view::size`
234 */
235 7203 BOOST_CONSTEXPR size_type size() const noexcept
236 {
237 7203 return s_.size();
238 }
239
240 /** Return the size
241
242 See `core::string_view::length`
243 */
244 BOOST_CONSTEXPR size_type length() const noexcept
245 {
246 return s_.length();
247 }
248
249 /** Return the maximum allowed size
250
251 See `core::string_view::max_size`
252 */
253 BOOST_CONSTEXPR size_type max_size() const noexcept
254 {
255 return s_.max_size();
256 }
257
258 /** Return true if the string is empty
259
260 See `core::string_view::size`
261 */
262 5330 BOOST_CONSTEXPR bool empty() const noexcept
263 {
264 5330 return s_.empty();
265 }
266
267 // element access
268
269 /** Access a character
270
271 See `core::string_view::operator[]`
272 */
273 BOOST_CXX14_CONSTEXPR const_reference
274 1 operator[]( size_type pos ) const noexcept
275 {
276 1 return s_[pos];
277 }
278
279 /** Access a character
280
281 See `core::string_view::at`
282 */
283 BOOST_CXX14_CONSTEXPR const_reference
284 at( size_type pos ) const
285 {
286 return s_.at(pos);
287 }
288
289 /** Return the first character
290
291 See `core::string_view::front`
292 */
293 BOOST_CXX14_CONSTEXPR const_reference
294 79 front() const noexcept
295 {
296 79 return s_.front();
297 }
298
299 /** Return the last character
300
301 See `core::string_view::back`
302 */
303 BOOST_CXX14_CONSTEXPR const_reference
304 16 back() const noexcept
305 {
306 16 return s_.back();
307 }
308
309 /** Return a pointer to the character buffer
310
311 See `core::string_view::data`
312 */
313 BOOST_CONSTEXPR const_pointer
314 667 data() const noexcept
315 {
316 667 return s_.data();
317 }
318
319 // string operations
320
321 /** Copy the characters to another buffer
322
323 See `core::string_view::copy`
324 */
325 BOOST_CXX14_CONSTEXPR size_type copy(
326 char* s, size_type n, size_type pos = 0 ) const
327 {
328 return s_.copy(s, n, pos);
329 }
330
331 /** Return a view to part of the string
332
333 See `core::string_view::substr`
334 */
335 10080 BOOST_CXX14_CONSTEXPR core::string_view substr(
336 size_type pos = 0, size_type n = core::string_view::npos ) const
337 {
338 10080 return s_.substr(pos, n);
339 }
340
341 // comparison
342
343 /** Return the result of comparing to another string
344
345 See `core::string_view::compare`
346 */
347 BOOST_CXX14_CONSTEXPR int
348 compare( core::string_view str ) const noexcept
349 {
350 return s_.compare(str);
351 }
352
353 /** Return the result of comparing to another string
354
355 See `core::string_view::compare`
356 */
357 BOOST_CONSTEXPR int compare(
358 size_type pos1, size_type n1, core::string_view str ) const
359 {
360 return s_.compare(pos1, n1, str);
361 }
362
363 /** Return the result of comparing to another string
364
365 See `core::string_view::compare`
366 */
367 BOOST_CONSTEXPR int compare(
368 size_type pos1, size_type n1, core::string_view str,
369 size_type pos2, size_type n2 ) const
370 {
371 return s_.compare(pos1, n1, str, pos2, n2);
372 }
373
374 /** Return the result of comparing to another string
375
376 See `core::string_view::compare`
377 */
378 BOOST_CONSTEXPR int compare(
379 char const* s ) const noexcept
380 {
381 return s_.compare(s);
382 }
383
384 /** Return the result of comparing to another string
385
386 See `core::string_view::compare`
387 */
388 BOOST_CONSTEXPR int compare(
389 size_type pos1, size_type n1, char const* s ) const
390 {
391 return s_.compare(pos1, n1, s);
392 }
393
394 /** Return the result of comparing to another string
395
396 See `core::string_view::compare`
397 */
398 BOOST_CONSTEXPR int compare(
399 size_type pos1, size_type n1,
400 char const* s, size_type n2 ) const
401 {
402 return s_.compare(pos1, n1, s, n2);
403 }
404
405 // starts_with
406
407 /** Return true if a matching prefix exists
408
409 See `core::string_view::starts_with`
410 */
411 BOOST_CONSTEXPR bool starts_with(
412 core::string_view x ) const noexcept
413 {
414 return s_.starts_with(x);
415 }
416
417 /** Return true if a matching prefix exists
418
419 See `core::string_view::starts_with`
420 */
421 538 BOOST_CONSTEXPR bool starts_with(
422 char x ) const noexcept
423 {
424 538 return s_.starts_with(x);
425 }
426
427 /** Return true if a matching prefix exists
428
429 See `core::string_view::starts_with`
430 */
431 232 BOOST_CONSTEXPR bool starts_with(
432 char const* x ) const noexcept
433 {
434 232 return s_.starts_with(x);
435 }
436
437 // ends_with
438
439 /** Return true if a matching suffix exists
440
441 See `core::string_view::ends_with`
442 */
443 BOOST_CONSTEXPR bool ends_with(
444 core::string_view x ) const noexcept
445 {
446 return s_.ends_with(x);
447 }
448
449 /** Return true if a matching suffix exists
450
451 See `core::string_view::ends_with`
452 */
453 521 BOOST_CONSTEXPR bool ends_with(
454 char x ) const noexcept
455 {
456 521 return s_.ends_with(x);
457 }
458
459 /** Return true if a matching suffix exists
460
461 See `core::string_view::ends_with`
462 */
463 BOOST_CONSTEXPR bool ends_with(
464 char const* x ) const noexcept
465 {
466 return s_.ends_with(x);
467 }
468
469 // find
470
471 /** Return the position of matching characters
472
473 See `core::string_view::find`
474 */
475 BOOST_CONSTEXPR size_type find(
476 core::string_view str, size_type pos = 0 ) const noexcept
477 {
478 return s_.find(str, pos);
479 }
480
481 /** Return the position of matching characters
482
483 See `core::string_view::find`
484 */
485 10 BOOST_CXX14_CONSTEXPR size_type find(
486 char c, size_type pos = 0 ) const noexcept
487 {
488 10 return s_.find(c, pos);
489 }
490
491 /** Return the position of matching characters
492
493 See `core::string_view::find`
494 */
495 BOOST_CXX14_CONSTEXPR size_type find(
496 char const* s, size_type pos, size_type n ) const noexcept
497 {
498 return s_.find(s, pos, n);
499 }
500
501 /** Return the position of matching characters
502
503 See `core::string_view::find`
504 */
505 BOOST_CONSTEXPR size_type find(
506 char const* s, size_type pos = 0 ) const noexcept
507 {
508 return s_.find(s, pos);
509 }
510
511 // rfind
512
513 /** Return the position of matching characters
514
515 See `core::string_view::rfind`
516 */
517 BOOST_CONSTEXPR size_type rfind(
518 core::string_view str, size_type pos = core::string_view::npos ) const noexcept
519 {
520 return s_.rfind(str, pos);
521 }
522
523 /** Return the position of matching characters
524
525 See `core::string_view::rfind`
526 */
527 BOOST_CXX14_CONSTEXPR size_type rfind(
528 char c, size_type pos = core::string_view::npos ) const noexcept
529 {
530 return s_.rfind(c, pos);
531 }
532
533 /** Return the position of matching characters
534
535 See `core::string_view::rfind`
536 */
537 BOOST_CXX14_CONSTEXPR size_type rfind(
538 char const* s, size_type pos, size_type n ) const noexcept
539 {
540 return s_.rfind(s, pos, n);
541 }
542
543 /** Return the position of matching characters
544
545 See `core::string_view::rfind`
546 */
547 BOOST_CONSTEXPR size_type rfind(
548 char const* s, size_type pos = core::string_view::npos ) const noexcept
549 {
550 return s_.rfind(s, pos);
551 }
552
553 // find_first_of
554
555 /** Return the position of the first match
556
557 See `core::string_view::find_first_of`
558 */
559 BOOST_CXX14_CONSTEXPR size_type find_first_of(
560 core::string_view str, size_type pos = 0 ) const noexcept
561 {
562 return s_.find_first_of(str, pos);
563 }
564
565 /** Return the position of the first match
566
567 See `core::string_view::find_first_of`
568 */
569 52 BOOST_CONSTEXPR size_type find_first_of(
570 char c, size_type pos = 0 ) const noexcept
571 {
572 52 return s_.find_first_of(c, pos);
573 }
574
575 /** Return the position of the first match
576
577 See `core::string_view::find_first_of`
578 */
579 BOOST_CXX14_CONSTEXPR size_type find_first_of(
580 char const* s, size_type pos, size_type n ) const noexcept
581 {
582 return s_.find_first_of(s, pos, n);
583 }
584
585 /** Return the position of the first match
586
587 See `core::string_view::find_first_of`
588 */
589 5 BOOST_CXX14_CONSTEXPR size_type find_first_of(
590 char const* s, size_type pos = 0 ) const noexcept
591 {
592 5 return s_.find_first_of(s, pos);
593 }
594
595 // find_last_of
596
597 /** Return the position of the last match
598
599 See `core::string_view::find_last_of`
600 */
601 BOOST_CXX14_CONSTEXPR size_type find_last_of(
602 core::string_view str, size_type pos = core::string_view::npos ) const noexcept
603 {
604 return s_.find_last_of(str, pos);
605 }
606
607 /** Return the position of the last match
608
609 See `core::string_view::find_last_of`
610 */
611 BOOST_CONSTEXPR size_type find_last_of(
612 char c, size_type pos = core::string_view::npos ) const noexcept
613 {
614 return s_.find_last_of(c, pos);
615 }
616
617 /** Return the position of the last match
618
619 See `core::string_view::find_last_of`
620 */
621 BOOST_CXX14_CONSTEXPR size_type find_last_of(
622 char const* s, size_type pos, size_type n ) const noexcept
623 {
624 return s_.find_last_of(s, pos, n);
625 }
626
627 /** Return the position of the last match
628
629 See `core::string_view::find_last_of`
630 */
631 BOOST_CXX14_CONSTEXPR size_type find_last_of(
632 char const* s, size_type pos = core::string_view::npos ) const noexcept
633 {
634 return s_.find_last_of(s, pos);
635 }
636
637 // find_first_not_of
638
639 /** Return the position of the first non-match
640
641 See `core::string_view::find_first_not_of`
642 */
643 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
644 core::string_view str, size_type pos = 0 ) const noexcept
645 {
646 return s_.find_first_not_of(str, pos);
647 }
648
649 /** Return the position of the first non-match
650
651 See `core::string_view::find_first_not_of`
652 */
653 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
654 char c, size_type pos = 0 ) const noexcept
655 {
656 return s_.find_first_not_of(c, pos);
657 }
658
659 /** Return the position of the first non-match
660
661 See `core::string_view::find_first_not_of`
662 */
663 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
664 char const* s, size_type pos, size_type n ) const noexcept
665 {
666 return s_.find_first_not_of(s, pos, n);
667 }
668
669 /** Return the position of the first non-match
670
671 See `core::string_view::find_first_not_of`
672 */
673 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
674 char const* s, size_type pos = 0 ) const noexcept
675 {
676 return s_.find_first_not_of(s, pos);
677 }
678
679 // find_last_not_of
680
681 /** Return the position of the last non-match
682
683 See `core::string_view::find_last_not_of`
684 */
685 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
686 core::string_view str, size_type pos = core::string_view::npos ) const noexcept
687 {
688 return s_.find_last_not_of(str, pos);
689 }
690
691 /** Return the position of the last non-match
692
693 See `core::string_view::find_last_not_of`
694 */
695 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
696 char c, size_type pos = core::string_view::npos ) const noexcept
697 {
698 return s_.find_last_not_of(c, pos);
699 }
700
701 /** Return the position of the last non-match
702
703 See `core::string_view::find_last_not_of`
704 */
705 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
706 char const* s, size_type pos, size_type n ) const noexcept
707 {
708 return s_.find_last_not_of(s, pos, n);
709 }
710
711 /** Return the position of the last non-match
712
713 See `core::string_view::find_last_not_of`
714 */
715 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
716 char const* s, size_type pos = core::string_view::npos ) const noexcept
717 {
718 return s_.find_last_not_of(s, pos);
719 }
720
721 // contains
722
723 /** Return true if matching characters are found
724
725 See `core::string_view::contains`
726 */
727 BOOST_CONSTEXPR bool contains( core::string_view sv ) const noexcept
728 {
729 return s_.contains(sv);
730 }
731
732 /** Return true if matching characters are found
733
734 See `core::string_view::contains`
735 */
736 5 BOOST_CXX14_CONSTEXPR bool contains( char c ) const noexcept
737 {
738 5 return s_.contains(c);
739 }
740
741 /** Return true if matching characters are found
742
743 See `core::string_view::contains`
744 */
745 BOOST_CONSTEXPR bool contains( char const* s ) const noexcept
746 {
747 return s_.contains(s);
748 }
749
750 // relational operators
751 #ifndef BOOST_URL_DOCS
752 private:
753 template<class S0, class S1>
754 using is_match = std::integral_constant<bool,
755 std::is_convertible<S0, core::string_view>::value &&
756 std::is_convertible<S1, core::string_view>::value && (
757 (std::is_base_of<string_view_base,
758 typename std::decay<S0>::type>::value &&
759 std::is_convertible<S0 const volatile*,
760 string_view_base const volatile*>::value) ||
761 (std::is_base_of<string_view_base,
762 typename std::decay<S1>::type>::value &&
763 std::is_convertible<S1 const volatile*,
764 string_view_base const volatile*>::value))>;
765 public:
766
767 /// Compare two string views for equality
768 /**
769 * This function is only enabled if both arguments
770 * are convertible to `core::string_view` and at least
771 * one of the arguments is derived from `string_view_base`.
772 */
773 template<class S0, class S1>
774 3029 BOOST_CXX14_CONSTEXPR friend auto operator==(
775 S0 const& s0, S1 const& s1) noexcept ->
776 typename std::enable_if<
777 is_match<S0, S1>::value, bool>::type
778 {
779 3029 return urls::detail::to_sv(s0) == urls::detail::to_sv(s1);
780 }
781
782 /// Compare two string views for inequality
783 /**
784 * This function is only enabled if both arguments
785 * are convertible to `core::string_view` and at least
786 * one of the arguments is derived from `string_view_base`.
787 */
788 template<class S0, class S1>
789 80 BOOST_CXX14_CONSTEXPR friend auto operator!=(
790 S0 const& s0, S1 const& s1) noexcept ->
791 typename std::enable_if<
792 is_match<S0, S1>::value, bool>::type
793 {
794 80 return urls::detail::to_sv(s0) != urls::detail::to_sv(s1);
795 }
796
797 /// Compare two string views for less than
798 /**
799 * This function is only enabled if both arguments
800 * are convertible to `core::string_view` and at least
801 * one of the arguments is derived from `string_view_base`.
802 */
803 template<class S0, class S1>
804 14 BOOST_CXX14_CONSTEXPR friend auto operator<(
805 S0 const& s0, S1 const& s1) noexcept ->
806 typename std::enable_if<
807 is_match<S0, S1>::value, bool>::type
808 {
809 14 return urls::detail::to_sv(s0) < urls::detail::to_sv(s1);
810 }
811
812 /// Compare two string views for less than or equal
813 /**
814 * This function is only enabled if both arguments
815 * are convertible to `core::string_view` and at least
816 * one of the arguments is derived from `string_view_base`.
817 */
818 template<class S0, class S1>
819 14 BOOST_CXX14_CONSTEXPR friend auto operator<=(
820 S0 const& s0, S1 const& s1) noexcept ->
821 typename std::enable_if<
822 is_match<S0, S1>::value, bool>::type
823 {
824 14 return urls::detail::to_sv(s0) <= urls::detail::to_sv(s1);
825 }
826
827 /// Compare two string views for greater than
828 /**
829 * This function is only enabled if both arguments
830 * are convertible to `core::string_view` and at least
831 * one of the arguments is derived from `string_view_base`.
832 */
833 template<class S0, class S1>
834 14 BOOST_CXX14_CONSTEXPR friend auto operator>(
835 S0 const& s0, S1 const& s1) noexcept ->
836 typename std::enable_if<
837 is_match<S0, S1>::value, bool>::type
838 {
839 14 return urls::detail::to_sv(s0) > urls::detail::to_sv(s1);
840 }
841
842 /// Compare two string views for greater than or equal
843 /**
844 * This function is only enabled if both arguments
845 * are convertible to `core::string_view` and at least
846 * one of the arguments is derived from `string_view_base`.
847 */
848 template<class S0, class S1>
849 7 BOOST_CXX14_CONSTEXPR friend auto operator>=(
850 S0 const& s0, S1 const& s1) noexcept ->
851 typename std::enable_if<
852 is_match<S0, S1>::value, bool>::type
853 {
854 7 return urls::detail::to_sv(s0) >= urls::detail::to_sv(s1);
855 }
856 #endif
857
858 //--------------------------------------------
859
860 /** Return the hash of this value
861 */
862 friend
863 std::size_t
864 hash_value(
865 string_view_base const& s) noexcept
866 {
867 return hash_value(s.s_);
868 }
869
870 /** Format a string to an output stream
871 */
872 BOOST_URL_DECL
873 friend
874 std::ostream&
875 operator<<(
876 std::ostream& os,
877 string_view_base const& s);
878 };
879
880 //------------------------------------------------
881
882 /** Format a string to an output stream
883 */
884 BOOST_URL_DECL
885 std::ostream&
886 operator<<(
887 std::ostream& os,
888 string_view_base const& s);
889
890 } // grammar
891
892 #ifndef BOOST_URL_DOCS
893 namespace detail {
894 template <>
895 inline
896 core::string_view
897 32 to_sv(grammar::string_view_base const& s) noexcept
898 {
899 32 return s.operator core::string_view();
900 }
901 } // detail
902 #endif
903
904 } // urls
905 } // boost
906
907 #endif
908