GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/string_view_base.hpp
Date: 2024-02-29 20:02: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 34240 string_view_base(
56 char const* data,
57 std::size_t size) noexcept
58 34240 : s_(data, size)
59 {
60 34240 }
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 16381 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 11741 operator
120 core::string_view() const noexcept
121 {
122 11741 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 #ifdef __cpp_lib_array_constexpr
194 constexpr
195 #endif
196 const_reverse_iterator rbegin() const noexcept
197 {
198 return s_.rbegin();
199 }
200
201 /** Return a reverse iterator to the beginning
202
203 See `core::string_view::rend`
204 */
205 #ifdef __cpp_lib_array_constexpr
206 constexpr
207 #endif
208 const_reverse_iterator rend() const noexcept
209 {
210 return s_.rend();
211 }
212
213 /** Return a reverse iterator to the end
214
215 See `core::string_view::crbegin`
216 */
217 #ifdef __cpp_lib_array_constexpr
218 constexpr
219 #endif
220 const_reverse_iterator crbegin() const noexcept
221 {
222 return s_.crbegin();
223 }
224
225 /** Return a reverse iterator to the beginning
226
227 See `core::string_view::crend`
228 */
229 #ifdef __cpp_lib_array_constexpr
230 constexpr
231 #endif
232 const_reverse_iterator crend() const noexcept
233 {
234 return s_.crend();
235 }
236
237 // capacity
238
239 /** Return the size
240
241 See `core::string_view::size`
242 */
243 7158 BOOST_CONSTEXPR size_type size() const noexcept
244 {
245 7158 return s_.size();
246 }
247
248 /** Return the size
249
250 See `core::string_view::length`
251 */
252 BOOST_CONSTEXPR size_type length() const noexcept
253 {
254 return s_.length();
255 }
256
257 /** Return the maximum allowed size
258
259 See `core::string_view::max_size`
260 */
261 BOOST_CONSTEXPR size_type max_size() const noexcept
262 {
263 return s_.max_size();
264 }
265
266 /** Return true if the string is empty
267
268 See `core::string_view::size`
269 */
270 5321 BOOST_CONSTEXPR bool empty() const noexcept
271 {
272 5321 return s_.empty();
273 }
274
275 // element access
276
277 /** Access a character
278
279 See `core::string_view::operator[]`
280 */
281 BOOST_CXX14_CONSTEXPR const_reference
282 1 operator[]( size_type pos ) const noexcept
283 {
284 1 return s_[pos];
285 }
286
287 /** Access a character
288
289 See `core::string_view::at`
290 */
291 BOOST_CXX14_CONSTEXPR const_reference
292 at( size_type pos ) const
293 {
294 return s_.at(pos);
295 }
296
297 /** Return the first character
298
299 See `core::string_view::front`
300 */
301 BOOST_CXX14_CONSTEXPR const_reference
302 79 front() const noexcept
303 {
304 79 return s_.front();
305 }
306
307 /** Return the last character
308
309 See `core::string_view::back`
310 */
311 BOOST_CXX14_CONSTEXPR const_reference
312 16 back() const noexcept
313 {
314 16 return s_.back();
315 }
316
317 /** Return a pointer to the character buffer
318
319 See `core::string_view::data`
320 */
321 BOOST_CONSTEXPR const_pointer
322 587 data() const noexcept
323 {
324 587 return s_.data();
325 }
326
327 // string operations
328
329 /** Copy the characters to another buffer
330
331 See `core::string_view::copy`
332 */
333 BOOST_CXX14_CONSTEXPR size_type copy(
334 char* s, size_type n, size_type pos = 0 ) const
335 {
336 return s_.copy(s, n, pos);
337 }
338
339 /** Return a view to part of the string
340
341 See `core::string_view::substr`
342 */
343 10060 BOOST_CXX14_CONSTEXPR core::string_view substr(
344 size_type pos = 0, size_type n = core::string_view::npos ) const
345 {
346 10060 return s_.substr(pos, n);
347 }
348
349 // comparison
350
351 /** Return the result of comparing to another string
352
353 See `core::string_view::compare`
354 */
355 BOOST_CXX14_CONSTEXPR int
356 compare( core::string_view str ) const noexcept
357 {
358 return s_.compare(str);
359 }
360
361 /** Return the result of comparing to another string
362
363 See `core::string_view::compare`
364 */
365 BOOST_CONSTEXPR int compare(
366 size_type pos1, size_type n1, core::string_view str ) const
367 {
368 return s_.compare(pos1, n1, str);
369 }
370
371 /** Return the result of comparing to another string
372
373 See `core::string_view::compare`
374 */
375 BOOST_CONSTEXPR int compare(
376 size_type pos1, size_type n1, core::string_view str,
377 size_type pos2, size_type n2 ) const
378 {
379 return s_.compare(pos1, n1, str, pos2, n2);
380 }
381
382 /** Return the result of comparing to another string
383
384 See `core::string_view::compare`
385 */
386 BOOST_CONSTEXPR int compare(
387 char const* s ) const noexcept
388 {
389 return s_.compare(s);
390 }
391
392 /** Return the result of comparing to another string
393
394 See `core::string_view::compare`
395 */
396 BOOST_CONSTEXPR int compare(
397 size_type pos1, size_type n1, char const* s ) const
398 {
399 return s_.compare(pos1, n1, s);
400 }
401
402 /** Return the result of comparing to another string
403
404 See `core::string_view::compare`
405 */
406 BOOST_CONSTEXPR int compare(
407 size_type pos1, size_type n1,
408 char const* s, size_type n2 ) const
409 {
410 return s_.compare(pos1, n1, s, n2);
411 }
412
413 // starts_with
414
415 /** Return true if a matching prefix exists
416
417 See `core::string_view::starts_with`
418 */
419 BOOST_CONSTEXPR bool starts_with(
420 core::string_view x ) const noexcept
421 {
422 return s_.starts_with(x);
423 }
424
425 /** Return true if a matching prefix exists
426
427 See `core::string_view::starts_with`
428 */
429 528 BOOST_CONSTEXPR bool starts_with(
430 char x ) const noexcept
431 {
432 528 return s_.starts_with(x);
433 }
434
435 /** Return true if a matching prefix exists
436
437 See `core::string_view::starts_with`
438 */
439 232 BOOST_CONSTEXPR bool starts_with(
440 char const* x ) const noexcept
441 {
442 232 return s_.starts_with(x);
443 }
444
445 // ends_with
446
447 /** Return true if a matching suffix exists
448
449 See `core::string_view::ends_with`
450 */
451 BOOST_CONSTEXPR bool ends_with(
452 core::string_view x ) const noexcept
453 {
454 return s_.ends_with(x);
455 }
456
457 /** Return true if a matching suffix exists
458
459 See `core::string_view::ends_with`
460 */
461 513 BOOST_CONSTEXPR bool ends_with(
462 char x ) const noexcept
463 {
464 513 return s_.ends_with(x);
465 }
466
467 /** Return true if a matching suffix exists
468
469 See `core::string_view::ends_with`
470 */
471 BOOST_CONSTEXPR bool ends_with(
472 char const* x ) const noexcept
473 {
474 return s_.ends_with(x);
475 }
476
477 // find
478
479 /** Return the position of matching characters
480
481 See `core::string_view::find`
482 */
483 BOOST_CONSTEXPR size_type find(
484 core::string_view str, size_type pos = 0 ) const noexcept
485 {
486 return s_.find(str, pos);
487 }
488
489 /** Return the position of matching characters
490
491 See `core::string_view::find`
492 */
493 10 BOOST_CXX14_CONSTEXPR size_type find(
494 char c, size_type pos = 0 ) const noexcept
495 {
496 10 return s_.find(c, pos);
497 }
498
499 /** Return the position of matching characters
500
501 See `core::string_view::find`
502 */
503 BOOST_CXX14_CONSTEXPR size_type find(
504 char const* s, size_type pos, size_type n ) const noexcept
505 {
506 return s_.find(s, pos, n);
507 }
508
509 /** Return the position of matching characters
510
511 See `core::string_view::find`
512 */
513 BOOST_CONSTEXPR size_type find(
514 char const* s, size_type pos = 0 ) const noexcept
515 {
516 return s_.find(s, pos);
517 }
518
519 // rfind
520
521 /** Return the position of matching characters
522
523 See `core::string_view::rfind`
524 */
525 BOOST_CONSTEXPR size_type rfind(
526 core::string_view str, size_type pos = core::string_view::npos ) const noexcept
527 {
528 return s_.rfind(str, pos);
529 }
530
531 /** Return the position of matching characters
532
533 See `core::string_view::rfind`
534 */
535 BOOST_CXX14_CONSTEXPR size_type rfind(
536 char c, size_type pos = core::string_view::npos ) const noexcept
537 {
538 return s_.rfind(c, pos);
539 }
540
541 /** Return the position of matching characters
542
543 See `core::string_view::rfind`
544 */
545 BOOST_CXX14_CONSTEXPR size_type rfind(
546 char const* s, size_type pos, size_type n ) const noexcept
547 {
548 return s_.rfind(s, pos, n);
549 }
550
551 /** Return the position of matching characters
552
553 See `core::string_view::rfind`
554 */
555 BOOST_CONSTEXPR size_type rfind(
556 char const* s, size_type pos = core::string_view::npos ) const noexcept
557 {
558 return s_.rfind(s, pos);
559 }
560
561 // find_first_of
562
563 /** Return the position of the first match
564
565 See `core::string_view::find_first_of`
566 */
567 BOOST_CXX14_CONSTEXPR size_type find_first_of(
568 core::string_view str, size_type pos = 0 ) const noexcept
569 {
570 return s_.find_first_of(str, pos);
571 }
572
573 /** Return the position of the first match
574
575 See `core::string_view::find_first_of`
576 */
577 52 BOOST_CONSTEXPR size_type find_first_of(
578 char c, size_type pos = 0 ) const noexcept
579 {
580 52 return s_.find_first_of(c, pos);
581 }
582
583 /** Return the position of the first match
584
585 See `core::string_view::find_first_of`
586 */
587 BOOST_CXX14_CONSTEXPR size_type find_first_of(
588 char const* s, size_type pos, size_type n ) const noexcept
589 {
590 return s_.find_first_of(s, pos, n);
591 }
592
593 /** Return the position of the first match
594
595 See `core::string_view::find_first_of`
596 */
597 5 BOOST_CXX14_CONSTEXPR size_type find_first_of(
598 char const* s, size_type pos = 0 ) const noexcept
599 {
600 5 return s_.find_first_of(s, pos);
601 }
602
603 // find_last_of
604
605 /** Return the position of the last match
606
607 See `core::string_view::find_last_of`
608 */
609 BOOST_CXX14_CONSTEXPR size_type find_last_of(
610 core::string_view str, size_type pos = core::string_view::npos ) const noexcept
611 {
612 return s_.find_last_of(str, pos);
613 }
614
615 /** Return the position of the last match
616
617 See `core::string_view::find_last_of`
618 */
619 BOOST_CONSTEXPR size_type find_last_of(
620 char c, size_type pos = core::string_view::npos ) const noexcept
621 {
622 return s_.find_last_of(c, pos);
623 }
624
625 /** Return the position of the last match
626
627 See `core::string_view::find_last_of`
628 */
629 BOOST_CXX14_CONSTEXPR size_type find_last_of(
630 char const* s, size_type pos, size_type n ) const noexcept
631 {
632 return s_.find_last_of(s, pos, n);
633 }
634
635 /** Return the position of the last match
636
637 See `core::string_view::find_last_of`
638 */
639 BOOST_CXX14_CONSTEXPR size_type find_last_of(
640 char const* s, size_type pos = core::string_view::npos ) const noexcept
641 {
642 return s_.find_last_of(s, pos);
643 }
644
645 // find_first_not_of
646
647 /** Return the position of the first non-match
648
649 See `core::string_view::find_first_not_of`
650 */
651 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
652 core::string_view str, size_type pos = 0 ) const noexcept
653 {
654 return s_.find_first_not_of(str, pos);
655 }
656
657 /** Return the position of the first non-match
658
659 See `core::string_view::find_first_not_of`
660 */
661 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
662 char c, size_type pos = 0 ) const noexcept
663 {
664 return s_.find_first_not_of(c, pos);
665 }
666
667 /** Return the position of the first non-match
668
669 See `core::string_view::find_first_not_of`
670 */
671 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
672 char const* s, size_type pos, size_type n ) const noexcept
673 {
674 return s_.find_first_not_of(s, pos, n);
675 }
676
677 /** Return the position of the first non-match
678
679 See `core::string_view::find_first_not_of`
680 */
681 BOOST_CXX14_CONSTEXPR size_type find_first_not_of(
682 char const* s, size_type pos = 0 ) const noexcept
683 {
684 return s_.find_first_not_of(s, pos);
685 }
686
687 // find_last_not_of
688
689 /** Return the position of the last non-match
690
691 See `core::string_view::find_last_not_of`
692 */
693 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
694 core::string_view str, size_type pos = core::string_view::npos ) const noexcept
695 {
696 return s_.find_last_not_of(str, pos);
697 }
698
699 /** Return the position of the last non-match
700
701 See `core::string_view::find_last_not_of`
702 */
703 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
704 char c, size_type pos = core::string_view::npos ) const noexcept
705 {
706 return s_.find_last_not_of(c, pos);
707 }
708
709 /** Return the position of the last non-match
710
711 See `core::string_view::find_last_not_of`
712 */
713 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
714 char const* s, size_type pos, size_type n ) const noexcept
715 {
716 return s_.find_last_not_of(s, pos, n);
717 }
718
719 /** Return the position of the last non-match
720
721 See `core::string_view::find_last_not_of`
722 */
723 BOOST_CXX14_CONSTEXPR size_type find_last_not_of(
724 char const* s, size_type pos = core::string_view::npos ) const noexcept
725 {
726 return s_.find_last_not_of(s, pos);
727 }
728
729 // contains
730
731 /** Return true if matching characters are found
732
733 See `core::string_view::contains`
734 */
735 BOOST_CONSTEXPR bool contains( core::string_view sv ) const noexcept
736 {
737 return s_.contains(sv);
738 }
739
740 /** Return true if matching characters are found
741
742 See `core::string_view::contains`
743 */
744 5 BOOST_CXX14_CONSTEXPR bool contains( char c ) const noexcept
745 {
746 5 return s_.contains(c);
747 }
748
749 /** Return true if matching characters are found
750
751 See `core::string_view::contains`
752 */
753 BOOST_CONSTEXPR bool contains( char const* s ) const noexcept
754 {
755 return s_.contains(s);
756 }
757
758 // relational operators
759 #ifndef BOOST_URL_DOCS
760 private:
761 template<class S0, class S1>
762 using is_match = std::integral_constant<bool,
763 std::is_convertible<S0, core::string_view>::value &&
764 std::is_convertible<S1, core::string_view>::value && (
765 (std::is_base_of<string_view_base,
766 typename std::decay<S0>::type>::value &&
767 std::is_convertible<S0 const volatile*,
768 string_view_base const volatile*>::value) ||
769 (std::is_base_of<string_view_base,
770 typename std::decay<S1>::type>::value &&
771 std::is_convertible<S1 const volatile*,
772 string_view_base const volatile*>::value))>;
773 public:
774
775 template<class S0, class S1>
776 3017 BOOST_CXX14_CONSTEXPR friend auto operator==(
777 S0 const& s0, S1 const& s1) noexcept ->
778 typename std::enable_if<
779 is_match<S0, S1>::value, bool>::type
780 {
781 3017 return urls::detail::to_sv(s0) == urls::detail::to_sv(s1);
782 }
783
784 template<class S0, class S1>
785 80 BOOST_CXX14_CONSTEXPR friend auto operator!=(
786 S0 const& s0, S1 const& s1) noexcept ->
787 typename std::enable_if<
788 is_match<S0, S1>::value, bool>::type
789 {
790 80 return urls::detail::to_sv(s0) != urls::detail::to_sv(s1);
791 }
792
793 template<class S0, class S1>
794 14 BOOST_CXX14_CONSTEXPR friend auto operator<(
795 S0 const& s0, S1 const& s1) noexcept ->
796 typename std::enable_if<
797 is_match<S0, S1>::value, bool>::type
798 {
799 14 return urls::detail::to_sv(s0) < urls::detail::to_sv(s1);
800 }
801
802 template<class S0, class S1>
803 14 BOOST_CXX14_CONSTEXPR friend auto operator<=(
804 S0 const& s0, S1 const& s1) noexcept ->
805 typename std::enable_if<
806 is_match<S0, S1>::value, bool>::type
807 {
808 14 return urls::detail::to_sv(s0) <= urls::detail::to_sv(s1);
809 }
810
811 template<class S0, class S1>
812 14 BOOST_CXX14_CONSTEXPR friend auto operator>(
813 S0 const& s0, S1 const& s1) noexcept ->
814 typename std::enable_if<
815 is_match<S0, S1>::value, bool>::type
816 {
817 14 return urls::detail::to_sv(s0) > urls::detail::to_sv(s1);
818 }
819
820 template<class S0, class S1>
821 7 BOOST_CXX14_CONSTEXPR friend auto operator>=(
822 S0 const& s0, S1 const& s1) noexcept ->
823 typename std::enable_if<
824 is_match<S0, S1>::value, bool>::type
825 {
826 7 return urls::detail::to_sv(s0) >= urls::detail::to_sv(s1);
827 }
828 #endif
829
830 //--------------------------------------------
831
832 /** Return the hash of this value
833 */
834 friend
835 std::size_t
836 hash_value(
837 string_view_base const& s) noexcept
838 {
839 return hash_value(s.s_);
840 }
841
842 BOOST_URL_DECL
843 friend
844 std::ostream&
845 operator<<(
846 std::ostream& os,
847 string_view_base const& s);
848 };
849
850 //------------------------------------------------
851
852 /** Format a string to an output stream
853 */
854 BOOST_URL_DECL
855 std::ostream&
856 operator<<(
857 std::ostream& os,
858 string_view_base const& s);
859
860 } // grammar
861
862 #ifndef BOOST_URL_DOCS
863 namespace detail {
864 template <>
865 inline
866 core::string_view
867 32 to_sv(grammar::string_view_base const& s) noexcept
868 {
869 32 return s.operator core::string_view();
870 }
871 } // detail
872 #endif
873
874 } // urls
875 } // boost
876
877 #endif
878