DAW string_view
daw_string_view2.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/string_view
7//
8
9#pragma once
10
12
13#include <daw/daw_algorithm.h>
14#include <daw/daw_cpp_feature_check.h>
15#include <daw/daw_exception.h>
16#include <daw/daw_fnv1a_hash.h>
17#include <daw/daw_generic_hash.h>
18#include <daw/daw_logic.h>
19#include <daw/daw_math.h>
20#include <daw/daw_move.h>
21#include <daw/daw_swap.h>
22#include <daw/daw_traits.h>
23#include <daw/impl/daw_string_impl.h>
24#include <daw/iterator/daw_back_inserter.h>
25#include <daw/iterator/daw_iterator.h>
26
27#include <ciso646>
28#include <cstddef>
29#include <cstdint>
30#include <cstdlib>
31#include <iterator>
32#include <limits>
33#include <stdexcept>
34
35#include <vector>
36
40#define DAW_REQ_UNARY_PRED( Pred, Type ) \
41 std::enable_if_t<traits::is_unary_predicate_v<Pred, Type>, std::nullptr_t> = \
42 nullptr
43
47#define DAW_REQ_CONTIG_CHAR_RANGE( Range, CharT ) \
48 std::enable_if_t<sv2_details::is_string_view_like<Range, CharT>::value, \
49 std::nullptr_t> = nullptr
50
53#define DAW_REQ_CHAR_PTR( Pointer ) \
54 std::enable_if_t<sv2_details::is_char_pointer_v<Pointer, const_pointer>, \
55 std::nullptr_t> = nullptr
56
59#define DAW_REQ_CONTIG_CHAR_RANGE_CTOR( Type ) \
60 std::enable_if_t< \
61 sv2_details::is_contigious_range_constructible<Type, CharT>::value, \
62 std::nullptr_t> = nullptr
63
64namespace daw {
65 /*inline*/ namespace sv2 {
68 struct nodiscard_t {};
69 inline constexpr nodiscard_t nodiscard = nodiscard_t{ };
70
73 template<typename CharT, CharT... needles>
74 struct any_of_t {
75 inline constexpr bool operator( )( CharT c ) const {
76 return ( ( c == needles ) | ... );
77 }
78 };
79
80 template<auto needle, auto... needles>
81 inline static constexpr any_of_t<decltype( needle ), needle, needles...>
83
86 template<typename CharT, CharT... needles>
87 struct none_of_t {
88 inline constexpr bool operator( )( CharT c ) const {
89 return ( ( c != needles ) & ... );
90 }
91 };
92
93 template<auto needle, auto... needles>
94 inline static constexpr none_of_t<decltype( needle ), needle, needles...>
96
97 namespace sv2_details {
98 template<typename T>
99 constexpr std::size_t find_predicate_result_size( T const & ) {
100 return 1;
101 }
102
103 template<typename T>
104 using has_datasize_test = typename std::remove_reference<
105 decltype( std::data( std::declval<T const &>( ) ) +
106 std::size( std::declval<T const &>( ) ) )>::type;
107
108 template<typename T>
109 using is_sv2_test = typename T::i_am_a_daw_string_view2;
110
111 template<typename T>
112 using is_sv2_t = daw::is_detected<is_sv2_test, T>;
113
114 template<typename T, typename CharT>
115 struct is_string_view_like
116 : std::conjunction<daw::is_detected<has_datasize_test, T>,
117 daw::not_trait<is_sv2_t<T>>> {};
118
119 static_assert( daw::is_detected_v<has_datasize_test, std::string> );
120 static_assert( daw::not_trait<is_sv2_t<std::string>>::value );
121 static_assert( is_string_view_like<std::string, char>::value );
122
123 template<typename T, typename CharT>
124 struct is_contigious_range_constructible
125 : std::is_constructible<T, CharT *, std::size_t> {};
126
127 template<typename T, typename PointerType>
128 inline constexpr bool is_char_pointer_v =
129 std::is_pointer_v<T> and std::is_convertible_v<T, PointerType>;
130
131 } // namespace sv2_details
132
136 template<typename CharT, string_view_bounds_type BoundsType>
138 using value_type = CharT;
139 using pointer = CharT *;
140 using const_pointer = std::add_const_t<CharT> *;
141 using reference = std::add_lvalue_reference_t<CharT>;
143 std::add_lvalue_reference_t<std::add_const_t<CharT>>;
146 using reverse_iterator = std::reverse_iterator<iterator>;
147 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
148 using size_type = std::size_t;
149 using difference_type = std::ptrdiff_t;
150
153
154 private:
155 static constexpr auto bp_eq = []( CharT l, CharT r ) noexcept {
156 return l == r;
157 };
158
159 template<string_view_bounds_type B>
160 static constexpr bool is_last_a_pointer_v =
161 B == string_view_bounds_type::pointer;
162
163 using last_type = std::conditional_t<is_last_a_pointer_v<BoundsType>,
164 const_pointer, size_type>;
165 static inline constexpr last_type default_last = [] {
166 if constexpr( is_last_a_pointer_v<BoundsType> ) {
167 return nullptr;
168 } else {
169 return 0;
170 }
171 }( );
172 using last_difference_type =
173 std::conditional_t<is_last_a_pointer_v<BoundsType>, difference_type,
174 size_type>;
175
176 template<string_view_bounds_type Bounds, typename LastType>
177 DAW_ATTRIB_INLINE static constexpr last_type
178 make_last( const_pointer f, LastType l ) noexcept {
179 if constexpr( std::is_pointer_v<LastType> ) {
180 if constexpr( is_last_a_pointer_v<Bounds> ) {
181 (void)f;
182 return l;
183 } else {
184 return static_cast<last_type>( l - f );
185 }
186 } else {
187 if constexpr( is_last_a_pointer_v<Bounds> ) {
188 return f + static_cast<difference_type>( l );
189 } else {
190 (void)f;
191 return static_cast<size_type>( l );
192 }
193 }
194 }
195
196 template<string_view_bounds_type Bounds>
197 DAW_ATTRIB_INLINE constexpr const_pointer last_pointer( ) const {
198 if constexpr( is_last_a_pointer_v<Bounds> ) {
199 return m_last;
200 } else {
201 return m_first + static_cast<difference_type>( m_last );
202 }
203 }
204
205 template<string_view_bounds_type Bounds>
206 DAW_ATTRIB_INLINE static constexpr size_type size( const_pointer f,
207 last_type l ) {
208 if constexpr( is_last_a_pointer_v<Bounds> ) {
209 return static_cast<size_type>( l - f );
210 } else {
211 (void)f;
212 return l;
213 }
214 }
215
216 template<string_view_bounds_type Bounds>
217 DAW_ATTRIB_INLINE constexpr void dec_front( size_type n ) {
218 if constexpr( is_last_a_pointer_v<Bounds> ) {
219 m_first += static_cast<difference_type>( n );
220 } else {
221 m_first += static_cast<difference_type>( n );
222 m_last -= n;
223 }
224 }
225
226 template<string_view_bounds_type Bounds>
227 DAW_ATTRIB_INLINE constexpr void dec_back( size_type n ) {
228 if constexpr( is_last_a_pointer_v<Bounds> ) {
229 m_last -= static_cast<difference_type>( n );
230 } else {
231 m_last -= n;
232 }
233 }
234
235 const_pointer m_first = nullptr;
236 last_type m_last = default_last;
237
238 public:
239 static constexpr size_type const npos =
240 ( std::numeric_limits<size_type>::max )( );
241
242 //******************************
243 // Constructors
244 //******************************
245
249 constexpr basic_string_view( ) noexcept = default;
250
254 constexpr basic_string_view( std::nullptr_t ) noexcept
255 : m_first( nullptr )
256 , m_last( make_last<BoundsType>( nullptr, nullptr ) ) {}
257
260 constexpr basic_string_view( std::nullptr_t,
261 size_type n ) noexcept = delete;
262
268 constexpr basic_string_view( const_pointer s, size_type count ) noexcept
269 : m_first( s )
270 , m_last( make_last<BoundsType>( s, count ) ) {}
271
278 template<typename CharPtr, DAW_REQ_CHAR_PTR( CharPtr )>
279 constexpr basic_string_view( CharPtr s ) noexcept
280 : m_first( s )
281 , m_last(
282 make_last<BoundsType>( s, details::strlen<size_type>( s ) ) ) {}
283
291 template<string_view_bounds_type B>
293 size_type count ) noexcept
294 : m_first( sv.data( ) )
295 , m_last( make_last<BoundsType>( sv.data( ),
296 ( std::min )( sv.size( ), count ) ) ) {
297 }
298
304 template<typename StringView,
305 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
306 constexpr basic_string_view( StringView &&sv ) noexcept
307 : m_first( std::data( sv ) )
308 , m_last( make_last<BoundsType>( m_first, std::size( sv ) ) ) {}
309
317 template<typename StringView,
318 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
319 constexpr basic_string_view( StringView &&sv, size_type count ) noexcept
320 : m_first( std::data( sv ) )
321 , m_last( make_last<BoundsType>(
322 m_first, ( std::min )( std::size( sv ), count ) ) ) {}
323
330 template<std::size_t N>
331 constexpr basic_string_view( CharT const ( &string_literal )[N] ) noexcept
332 : m_first( string_literal )
333 , m_last( make_last<BoundsType>( string_literal, N - 1 ) ) {}
334
345 : m_first( first )
346 , m_last( make_last<BoundsType>( first, last ) ) {}
347
348 //******************************
349 // Conversions
350 //******************************
351
354 template<typename T, DAW_REQ_CONTIG_CHAR_RANGE_CTOR( T )>
355 explicit constexpr operator T( ) const
356 noexcept( std::is_nothrow_constructible_v<T, CharT *, size_type> ) {
357 return T{ data( ), size( ) };
358 }
359
360 //******************************
361 // Iterator Support
362 //******************************
363
366 [[nodiscard]] constexpr const_iterator begin( ) const {
367 return m_first;
368 }
369
372 [[nodiscard]] constexpr const_iterator cbegin( ) const {
373 return m_first;
374 }
375
380 [[nodiscard]] constexpr reverse_iterator rbegin( ) const {
381 return const_reverse_iterator( end( ) );
382 }
383
388 [[nodiscard]] constexpr const_reverse_iterator crbegin( ) const {
389 return const_reverse_iterator( cend( ) );
390 }
391
396 [[nodiscard]] constexpr const_iterator end( ) const {
397 return last_pointer<BoundsType>( );
398 }
399
404 [[nodiscard]] constexpr const_iterator cend( ) const {
405 return last_pointer<BoundsType>( );
406 }
407
415 [[nodiscard]] constexpr reverse_iterator rend( ) const {
416 return const_reverse_iterator( begin( ) );
417 }
418
426 [[nodiscard]] constexpr const_reverse_iterator crend( ) const {
427 return const_reverse_iterator( cbegin( ) );
428 }
429
430 //******************************
431 // Capacity
432 //******************************
433
436 [[nodiscard]] constexpr size_type size( ) const {
437 return size<BoundsType>( m_first, m_last );
438 }
439
442 [[nodiscard]] constexpr size_type length( ) const {
443 return size( );
444 }
445
448 [[nodiscard]] constexpr bool empty( ) const {
449 return size( ) == 0;
450 }
451
452 //******************************
453 // Element Access
454 //******************************
455
459 [[nodiscard]] constexpr const_pointer data( ) const {
460 return m_first;
461 }
462
467 [[nodiscard]] constexpr const_pointer data_end( ) const {
468 return end( );
469 }
470
476 [[nodiscard]] constexpr const_reference
477 operator[]( size_type pos ) const {
478 return m_first[pos];
479 }
480
485 [[nodiscard]] constexpr const_reference at( size_type pos ) const {
486 daw::exception::precondition_check<std::out_of_range>(
487 pos < size( ), "Attempt to access basic_string_view past end" );
488 return operator[]( pos );
489 }
490
494 [[nodiscard]] constexpr const_reference front( ) const {
495 return *m_first;
496 }
497
501 [[nodiscard]] constexpr const_reference back( ) const {
502 return *std::prev( end( ) );
503 }
504 //******************************
505 // Modifiers
506 //******************************
507
510 constexpr void clear( ) {
511 m_last = make_last<BoundsType>( nullptr, size_type{0} );
512 }
513
517 constexpr void reset( ) {
518 m_first = nullptr;
519 m_last = make_last<BoundsType>( nullptr, size_type{0} );
520 }
521
525 constexpr void remove_prefix( size_type n ) {
526 dec_front<BoundsType>( ( std::min )( n, size( ) ) );
527 }
528
532 constexpr void remove_prefix( ) {
533 dec_front<BoundsType>( ( std::min )( size_type{ 1U }, size( ) ) );
534 }
535
538 constexpr void remove_suffix( size_type n ) {
539 dec_back<BoundsType>( ( std::min )( n, size( ) ) );
540 }
541
543 constexpr void remove_suffix( ) {
544 dec_back<BoundsType>( ( std::min )( size_type{ 1U }, size( ) ) );
545 }
546
549 [[nodiscard]] constexpr CharT pop_front( ) {
550 auto result = front( );
551 remove_prefix( 1U );
552 return result;
553 }
554
561 basic_string_view result = substr( 0, count );
562 remove_prefix( count );
563 return result;
564 }
565
573 [[nodiscard]] constexpr basic_string_view
575 auto pos = find( where );
576 auto result = pop_front( pos );
577 return result;
578 }
579
584 [[nodiscard]] constexpr basic_string_view pop_front_until( CharT where,
585 nodiscard_t ) {
586 auto pos = find( where );
587 auto result = pop_front( pos );
588 return result;
589 }
590
595 [[nodiscard]] constexpr basic_string_view
597 auto pos = find( where );
598 auto result = pop_front( pos );
599 remove_prefix( where.size( ) );
600 return result;
601 }
602
607 [[nodiscard]] constexpr basic_string_view pop_front_until( CharT where ) {
608 auto pos = find( where );
609 auto result = pop_front( pos );
610 remove_prefix( );
611 return result;
612 }
613
624 template<typename UnaryPredicate,
625 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
626 [[nodiscard]] constexpr basic_string_view
627 pop_front_until( UnaryPredicate pred, nodiscard_t ) {
628
629 auto pos = find_first_of_if( DAW_MOVE( pred ) );
630 return pop_front( pos );
631 }
632
643 template<typename UnaryPredicate,
644 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
645 [[nodiscard]] constexpr basic_string_view
646 pop_front_until( UnaryPredicate pred ) {
647 auto result = pop_front_until( pred, nodiscard );
648 remove_prefix( sv2_details::find_predicate_result_size( pred ) );
649 return result;
650 }
651 //*****************************************************************************
652 //*****************************************************************************
653 //*****************************************************************************
654
655 [[nodiscard]] constexpr CharT pop_back( ) {
656 auto result = back( );
657 remove_suffix( );
658 return result;
659 }
660
666 count = ( std::min )( count, size( ) );
667 basic_string_view result = substr( size( ) - count, npos );
668 remove_suffix( count );
669 return result;
670 }
671
676 [[nodiscard]] constexpr basic_string_view
678 auto pos = rfind( where );
679 if( pos == npos ) {
680 auto result{ *this };
681 remove_prefix( npos );
682 return result;
683 }
684 return substr( pos + where.size( ) );
685 }
686
691 [[nodiscard]] constexpr basic_string_view pop_back_until( CharT where,
692 nodiscard_t ) {
693 auto pos = rfind( where );
694 if( pos == npos ) {
695 auto result{ *this };
696 remove_prefix( npos );
697 return result;
698 }
699 return substr( pos + where.size( ) );
700 }
701
707 [[nodiscard]] constexpr basic_string_view
709 auto pos = rfind( where );
710 if( pos == npos ) {
711 auto result{ *this };
712 remove_prefix( npos );
713 return result;
714 }
715 auto result = substr( pos + where.size( ) );
716 remove_suffix( size( ) - pos );
717 return result;
718 }
719
725 [[nodiscard]] constexpr basic_string_view pop_back_until( CharT where ) {
726 auto pos = rfind( where );
727 if( pos == npos ) {
728 auto result{ *this };
729 remove_prefix( npos );
730 return result;
731 }
732 auto result = substr( pos + 1 );
733 remove_suffix( size( ) - pos );
734 return result;
735 }
736
745 template<typename UnaryPredicate,
746 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
747 [[nodiscard]] constexpr basic_string_view
748 pop_back_until( UnaryPredicate pred ) {
749
750 auto pos = find_last_of_if( DAW_MOVE( pred ) );
751 if( pos == npos ) {
752 auto result = *this;
753 remove_prefix( npos );
754 return result;
755 }
756 auto result =
757 substr( pos + sv2_details::find_predicate_result_size( pred ) );
758 remove_suffix( size( ) - pos );
759 return result;
760 }
761
767 [[nodiscard]] constexpr basic_string_view
769 auto pos = find( where );
770 if( pos == npos ) {
772 }
773 auto result = pop_front( pos );
774 remove_prefix( where.size( ) );
775 return result;
776 }
777
783 [[nodiscard]] constexpr basic_string_view
785 auto pos = rfind( where );
786 if( pos == npos ) {
788 }
789 auto result = substr( pos + where.size( ) );
790 remove_suffix( size( ) - pos );
791 return result;
792 }
793
799 constexpr basic_string_view &remove_prefix_until( CharT where ) {
800 auto pos = find( where );
801 remove_prefix( pos );
802 remove_prefix( 1 );
803 return *this;
804 }
805
810 constexpr basic_string_view &remove_prefix_until( CharT where,
811 nodiscard_t ) {
812 auto pos = find( where );
813 dec_front<BoundsType>( ( std::min )( size( ), pos ) );
814 return *this;
815 }
816
822 constexpr basic_string_view &
824 auto pos = find( where );
825 dec_front<BoundsType>( ( std::min )( size( ), pos + where.size( ) ) );
826 return *this;
827 }
828
835 nodiscard_t ) {
836 auto pos = find( where );
837 dec_front<BoundsType>( ( std::min )( size( ), pos ) );
838 return *this;
839 }
840
846 template<typename UnaryPredicate,
847 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
848 constexpr basic_string_view &remove_prefix_until( UnaryPredicate pred ) {
849 auto pos = find_first_of_if( pred );
850 dec_front<BoundsType>( ( std::min )(
851 size( ), pos + sv2_details::find_predicate_result_size( pred ) ) );
852 return *this;
853 }
854
859 template<typename UnaryPredicate,
860 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
861 constexpr basic_string_view &remove_prefix_until( UnaryPredicate pred,
862 nodiscard_t ) {
863 auto pos = find_if( pred );
864 dec_front<BoundsType>( ( std::min )( size( ), pos ) );
865 return *this;
866 }
867
872 constexpr void resize( size_type new_size ) {
873 daw::exception::precondition_check<std::out_of_range>( new_size <=
874 size( ) );
875 m_last = make_last<BoundsType>(
876 m_first,
877 std::next( m_first, static_cast<difference_type>( new_size ) ) );
878 }
879
880 constexpr size_type copy( pointer dest, size_type count,
881 size_type pos ) const {
882 daw::exception::precondition_check<std::out_of_range>(
883 pos <= size( ), "Attempt to access basic_string_view past end" );
884
885 size_type const rlen = ( std::min )( count, size( ) - pos );
886 if( rlen > 0 ) {
887 auto const f =
888 std::next( begin( ), static_cast<difference_type>( pos ) );
889 auto const l = std::next( f, static_cast<difference_type>( rlen ) );
890 daw::algorithm::copy( f, l, dest );
891 }
892 return rlen;
893 }
894
895 constexpr size_type copy( pointer dest, size_type count ) const {
896 return copy( dest, count, 0 );
897 }
898
899 [[nodiscard]] constexpr basic_string_view
900 substr( size_type pos, size_type count ) const {
901 daw::exception::precondition_check<std::out_of_range>(
902 pos <= size( ), "Attempt to access basic_string_view past end" );
903 auto const rcount =
904 static_cast<size_type>( ( std::min )( count, size( ) - pos ) );
905 return { m_first + pos, m_first + pos + rcount };
906 }
907
908 [[nodiscard]] constexpr basic_string_view substr( ) const {
909 return substr( 0, npos );
910 }
911
912 [[nodiscard]] constexpr basic_string_view substr( size_type pos ) const {
913 return substr( pos, npos );
914 }
915
916 public:
917 template<typename Compare = std::less<void>, string_view_bounds_type BL,
918 string_view_bounds_type BR>
919 [[nodiscard]] static constexpr int
921 basic_string_view<CharT, BR> rhs, Compare cmp = Compare{ } ) {
922 constexpr auto const str_compare = []( CharT const *p0, CharT const *p1,
923 size_type len, Compare &c ) {
924 auto const last = p0 + len;
925 while( p0 != last ) {
926 if( c( *p0, *p1 ) ) {
927 return -1;
928 }
929 if( c( *p1, *p0 ) ) {
930 return 1;
931 }
932 ++p0;
933 ++p1;
934 }
935 return 0;
936 };
937
938 int const ret =
939 str_compare( lhs.data( ), rhs.data( ),
940 ( std::min )( lhs.size( ), rhs.size( ) ), cmp );
941 if( ret == 0 ) {
942 if( lhs.size( ) < rhs.size( ) ) {
943 return -1;
944 }
945 if( rhs.size( ) < lhs.size( ) ) {
946 return 1;
947 }
948 }
949 return ret;
950 }
951
952 template<typename Compare = std::less<>, string_view_bounds_type B>
954 Compare cmp = Compare{ } ) const {
955 return compare(
956 *this, basic_string_view( std::data( rhs ), std::size( rhs ) ), cmp );
957 }
958
959 template<typename Compare = std::less<>, typename StringView,
960 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
961 [[nodiscard]] constexpr int compare( StringView &&rhs,
962 Compare cmp = Compare{ } ) const {
963 return compare(
964 *this, basic_string_view( std::data( rhs ), std::size( rhs ) ), cmp );
965 }
966
967 template<typename Compare = std::less<>, std::size_t N>
968 [[nodiscard]] constexpr int compare( CharT const ( &rhs )[N],
969 Compare cmp = Compare{ } ) const {
970 return compare( *this, basic_string_view( rhs, N - 1 ), cmp );
971 }
972
973 template<typename Compare = std::less<>>
974 constexpr int compare( size_type pos1, size_type count1,
976 Compare cmp = Compare{ } ) const {
977 return compare( substr( pos1, count1 ), v, cmp );
978 }
979
980 template<typename Compare = std::less<>, string_view_bounds_type Bounds>
981 [[nodiscard]] constexpr int compare( size_type pos1, size_type count1,
983 size_type pos2, size_type count2,
984 Compare cmp = Compare{ } ) const {
985 return compare( substr( pos1, count1 ), v.substr( pos2, count2 ), cmp );
986 }
987
988 template<typename Compare = std::less<>>
989 [[nodiscard]] constexpr int compare( size_type pos1, size_type count1,
991 Compare cmp = Compare{ } ) const {
992 return compare( substr( pos1, count1 ),
994 }
995
996 template<typename Compare = std::less<>>
997 [[nodiscard]] constexpr int compare( size_type pos1, size_type count1,
998 const_pointer s, size_type count2,
999 Compare cmp = Compare{ } ) const {
1000 return compare( substr( pos1, count1 ),
1002 cmp );
1003 }
1004
1005 template<string_view_bounds_type Bounds>
1006 [[nodiscard]] constexpr size_type
1008
1009 if( size( ) < v.size( ) ) {
1010 return npos;
1011 }
1012 if( v.empty( ) ) {
1013 return pos;
1014 }
1015 auto result =
1016 details::search( begin( ) + pos, end( ), v.begin( ), v.end( ) );
1017 if( end( ) == result ) {
1018 return npos;
1019 }
1020 return static_cast<size_type>( result - begin( ) );
1021 }
1022
1023 template<string_view_bounds_type Bounds>
1024 [[nodiscard]] constexpr size_type
1026 return find( v, 0 );
1027 }
1028
1029 [[nodiscard]] constexpr size_type find( CharT c, size_type pos ) const {
1030 return find(
1031 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1 ), pos );
1032 }
1033
1034 [[nodiscard]] constexpr size_type find( CharT c ) const {
1035 return find( c, 0 );
1036 }
1037
1039 size_type count ) const {
1040 return find( basic_string_view<CharT, BoundsType>( s, count ), pos );
1041 }
1042
1044 size_type pos ) const {
1045 return find( basic_string_view<CharT, BoundsType>( s ), pos );
1046 }
1047
1048 [[nodiscard]] constexpr size_type find( const_pointer s ) const {
1049 return find( basic_string_view<CharT, BoundsType>( s ), 0 );
1050 }
1051
1052 template<string_view_bounds_type Bounds>
1053 [[nodiscard]] constexpr size_type
1055
1056 if( size( ) < v.size( ) ) {
1057 return npos;
1058 }
1059 pos = ( std::min )( pos, size( ) - v.size( ) );
1060 if( v.empty( ) ) {
1061 return pos;
1062 }
1063 const_iterator cur =
1064 std::next( begin( ), static_cast<difference_type>( pos ) );
1065 while( true ) {
1066 if( details::compare( cur, v.begin( ), v.size( ) ) == 0 ) {
1067 return static_cast<size_type>( cur - begin( ) );
1068 }
1069 if( cur == begin( ) ) {
1070 return npos;
1071 }
1072 --cur;
1073 }
1074 }
1075
1077 size_type count ) const {
1078 return rfind( basic_string_view<CharT, BoundsType>( s, count ), pos );
1079 }
1080
1081 template<string_view_bounds_type Bounds>
1082 [[nodiscard]] constexpr size_type
1084 return rfind( v, npos );
1085 }
1086
1087 [[nodiscard]] constexpr size_type rfind( CharT c, size_type pos ) const {
1088 return rfind(
1089 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1 ), pos );
1090 }
1091
1092 [[nodiscard]] constexpr size_type rfind( CharT c ) const {
1093 return rfind(
1094 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1 ),
1095 npos );
1096 }
1097
1099 size_type pos ) const {
1100 return rfind( basic_string_view<CharT, BoundsType>( s ), pos );
1101 }
1102
1103 [[nodiscard]] constexpr size_type rfind( const_pointer s ) const {
1104 return rfind( basic_string_view<CharT, BoundsType>( s ), npos );
1105 }
1106
1111 template<string_view_bounds_type Bounds>
1112 [[nodiscard]] constexpr size_type
1114 if( pos >= size( ) or v.empty( ) ) {
1115 return npos;
1116 }
1117 auto const iter = details::find_first_of( begin( ) + pos, end( ),
1118 v.begin( ), v.end( ), bp_eq );
1119
1120 if( end( ) == iter ) {
1121 return npos;
1122 }
1123 return static_cast<size_type>( std::distance( begin( ), iter ) );
1124 }
1125
1129 template<string_view_bounds_type Bounds>
1130 [[nodiscard]] constexpr size_type
1132 return find_first_of( v, 0 );
1133 }
1134
1136 size_type pos ) const {
1137 return find_first_of( basic_string_view<CharT, BoundsType>( str ),
1138 pos );
1139 }
1140
1141 [[nodiscard]] constexpr size_type
1143 return find_first_of( basic_string_view<CharT, BoundsType>( str ), 0 );
1144 }
1145
1146 template<string_view_bounds_type Bounds>
1147 [[nodiscard]] constexpr size_type
1149 if( pos + v.size( ) >= size( ) or v.empty( ) ) {
1150 return npos;
1151 }
1152 auto const iter =
1153 details::search( begin( ) + pos, end( ), v.begin( ), v.end( ) );
1154 if( cend( ) == iter ) {
1155 return npos;
1156 }
1157 return static_cast<size_type>( std::distance( begin( ), iter ) );
1158 }
1159
1160 template<string_view_bounds_type Bounds>
1161 [[nodiscard]] constexpr size_type
1163 return search( v, 0 );
1164 }
1165
1166 [[nodiscard]] constexpr size_t search( const_pointer str,
1167 size_type pos ) const {
1168 return search( basic_string_view<CharT, BoundsType>( str ), pos );
1169 }
1170
1171 [[nodiscard]] constexpr size_t search( const_pointer str ) const {
1172 return search( basic_string_view<CharT, BoundsType>( str ), 0 );
1173 }
1174
1175 template<string_view_bounds_type Bounds>
1176 [[nodiscard]] constexpr size_type
1178 if( pos + v.size( ) >= size( ) or v.empty( ) ) {
1179 return npos;
1180 }
1181 auto last_pos = pos;
1182 auto fpos = search( v, pos );
1183 while( fpos != npos ) {
1184 last_pos = fpos;
1185 fpos = search( v, fpos );
1186 if( fpos == last_pos ) {
1187 break;
1188 }
1189 }
1190 return last_pos;
1191 }
1192
1193 template<string_view_bounds_type Bounds>
1194 [[nodiscard]] constexpr size_type
1196 return search_last( v, 0 );
1197 }
1198
1199 [[nodiscard]] constexpr size_t search_last( const_pointer str,
1200 size_type pos ) const {
1201 return search_last( basic_string_view<CharT, BoundsType>( str ), pos );
1202 }
1203
1204 [[nodiscard]] constexpr size_t search_last( const_pointer str ) const {
1205 return search_last( basic_string_view<CharT, BoundsType>( str ), 0 );
1206 }
1207
1208 template<typename UnaryPredicate,
1209 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1210 [[nodiscard]] constexpr size_type
1211 find_first_of_if( UnaryPredicate pred, size_type pos ) const {
1212
1213 (void)traits::is_unary_predicate_test<UnaryPredicate, CharT>( );
1214
1215 if( pos >= size( ) ) {
1216 return npos;
1217 }
1218 auto const iter =
1219 details::find_first_of_if( cbegin( ) + pos, cend( ), pred );
1220 if( cend( ) == iter ) {
1221 return npos;
1222 }
1223 return static_cast<size_type>( iter - cbegin( ) );
1224 }
1225
1226 template<typename UnaryPredicate,
1227 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1228 [[nodiscard]] constexpr size_type
1229 find_first_of_if( UnaryPredicate pred ) const {
1230 return find_first_of_if( pred, 0 );
1231 }
1232
1233 template<typename UnaryPredicate,
1234 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1235 [[nodiscard]] constexpr size_type
1236 find_first_not_of_if( UnaryPredicate pred, size_type pos ) const {
1237
1238 traits::is_unary_predicate_test<UnaryPredicate, CharT>( );
1239
1240 if( pos >= size( ) ) {
1241 return npos;
1242 }
1243 auto const iter =
1244 details::find_first_not_of_if( begin( ) + pos, end( ), pred );
1245 if( end( ) == iter ) {
1246 return npos;
1247 }
1248 return static_cast<size_type>( std::distance( begin( ), iter ) );
1249 }
1250
1251 template<typename UnaryPredicate,
1252 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1253 [[nodiscard]] constexpr size_type
1254 find_first_not_of_if( UnaryPredicate pred ) const {
1255 return find_first_not_of_if( pred, 0 );
1256 }
1257
1258 [[nodiscard]] constexpr size_type find_first_of( CharT c,
1259 size_type pos ) const {
1260 return find_first_of(
1261 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1U ),
1262 pos );
1263 }
1264
1265 [[nodiscard]] constexpr size_type find_first_of( CharT c ) const {
1266 return find_first_of(
1267 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1U ), 0 );
1268 }
1269
1270 [[nodiscard]] constexpr size_type
1272 return find_first_of( basic_string_view<CharT, BoundsType>( s, count ),
1273 pos );
1274 }
1275
1276 private:
1277 [[nodiscard]] constexpr size_type
1278 reverse_distance( const_reverse_iterator first,
1279 const_reverse_iterator last ) const {
1280 // Portability note here: std::distance is not NOEXCEPT, but
1281 // calling it with a string_view::reverse_iterator will not
1282 // throw.
1283 return ( size( ) - 1u ) -
1284 static_cast<size_t>( std::distance( first, last ) );
1285 }
1286
1287 public:
1288 template<string_view_bounds_type Bounds>
1289 [[nodiscard]] constexpr size_type
1291 if( s.empty( ) ) {
1292 return npos;
1293 }
1294 if( pos >= size( ) ) {
1295 pos = 0;
1296 } else {
1297 pos = size( ) - ( pos + 1U );
1298 }
1299 auto haystack = substr( pos );
1300 auto iter = daw::algorithm::find_first_of(
1301 haystack.rbegin( ), haystack.rend( ), s.rbegin( ), s.rend( ) );
1302 return iter == rend( ) ? npos : reverse_distance( rbegin( ), iter );
1303 }
1304
1305 template<string_view_bounds_type Bounds>
1306 [[nodiscard]] constexpr size_type
1308 return find_last_of( s, npos );
1309 }
1310
1311 [[nodiscard]] constexpr size_type find_last_of( CharT c,
1312 size_type pos ) const {
1313 return find_last_of( basic_string_view( std::addressof( c ), 1 ), pos );
1314 }
1315
1316 [[nodiscard]] constexpr size_type find_last_of( CharT c ) const {
1317 return find_last_of( basic_string_view( std::addressof( c ), 1 ),
1318 npos );
1319 }
1320
1321 template<size_type N>
1322 [[nodiscard]] constexpr size_type find_last_of( CharT const ( &s )[N],
1323 size_type pos ) {
1324 return find_last_of( basic_string_view<CharT, BoundsType>( s, N - 1 ),
1325 pos );
1326 }
1327
1328 template<size_type N>
1329 [[nodiscard]] constexpr size_type find_last_of( CharT const ( &s )[N] ) {
1330 return find_last_of( basic_string_view<CharT, BoundsType>( s, N - 1 ),
1331 npos );
1332 }
1333
1334 [[nodiscard]] constexpr size_type
1336 return find_last_of( basic_string_view<CharT, BoundsType>( s, count ),
1337 pos );
1338 }
1339
1341 size_type pos ) const {
1342 return find_last_of( basic_string_view<CharT, BoundsType>( s ), pos );
1343 }
1344
1346 return find_last_of( basic_string_view<CharT, BoundsType>( s ), npos );
1347 }
1348
1349 template<typename UnaryPredicate,
1350 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1351 [[nodiscard]] constexpr size_type find_last_of_if( UnaryPredicate pred,
1352 size_type pos ) const {
1353
1354 (void)traits::is_unary_predicate_test<UnaryPredicate, CharT>( );
1355
1356 auto haystack = substr( 0, pos );
1357 auto iter = daw::algorithm::find_if( haystack.crbegin( ),
1358 haystack.crend( ), pred );
1359 return iter == crend( ) ? npos : reverse_distance( crbegin( ), iter );
1360 }
1361
1362 template<typename UnaryPredicate,
1363 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1364 [[nodiscard]] constexpr size_type
1365 find_last_of_if( UnaryPredicate pred ) const {
1366 return find_last_of_if( pred, npos );
1367 }
1368
1369 template<string_view_bounds_type Bounds>
1370 [[nodiscard]] constexpr size_type
1372 size_type pos ) const {
1373 if( pos >= size( ) ) {
1374 return npos;
1375 }
1376 if( v.empty( ) ) {
1377 return pos;
1378 }
1379
1380 auto haystack = substr( pos );
1381 const_iterator iter = details::find_first_not_of(
1382 haystack.begin( ), haystack.end( ), v.begin( ),
1383 std::next( v.begin( ), static_cast<ptrdiff_t>( v.size( ) ) ), bp_eq );
1384 if( end( ) == iter ) {
1385 return npos;
1386 }
1387
1388 return static_cast<size_type>( std::distance( begin( ), iter ) );
1389 }
1390
1391 template<string_view_bounds_type Bounds>
1392 [[nodiscard]] constexpr size_type
1394 return find_first_not_of( v, 0 );
1395 }
1396
1397 [[nodiscard]] constexpr size_type
1398 find_first_not_of( CharT c, size_type pos ) const {
1399 return find_first_not_of(
1400 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1U ),
1401 pos );
1402 }
1403
1404 [[nodiscard]] constexpr size_type find_first_not_of( CharT c ) const {
1405 return find_first_not_of(
1406 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1U ), 0 );
1407 }
1408
1409 [[nodiscard]] constexpr size_type
1411 size_type count ) const {
1412 return find_first_not_of(
1413 basic_string_view<CharT, BoundsType>( s, count ), pos );
1414 }
1415
1416 [[nodiscard]] constexpr size_type
1418 return find_first_not_of( basic_string_view<CharT, BoundsType>( s ),
1419 pos );
1420 }
1421
1422 template<size_type N>
1423 [[nodiscard]] constexpr size_type
1424 find_first_not_of( CharT const( &&s )[N], size_type pos ) const {
1425 return find_first_not_of(
1426 basic_string_view<CharT, BoundsType>( s, N - 1 ), pos );
1427 }
1428
1429 [[nodiscard]] constexpr size_type
1431 return find_first_not_of( basic_string_view<CharT, BoundsType>( s ),
1432 0 );
1433 }
1434
1435 template<size_type N>
1436 [[nodiscard]] constexpr size_type
1437 find_first_not_of( CharT const( &&s )[N] ) const {
1438 return find_first_not_of(
1439 basic_string_view<CharT, BoundsType>( s, N - 1 ), 0 );
1440 }
1441
1442 template<typename UnaryPredicate,
1443 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1444 [[nodiscard]] constexpr size_type
1445 find_last_not_of_if( UnaryPredicate pred, size_type pos ) const {
1446
1447 if( empty( ) ) {
1448 return npos;
1449 }
1450 if( pos > size( ) ) {
1451 pos = size( ) - 1;
1452 }
1453 for( auto n = static_cast<difference_type>( pos ); n >= 0; --n ) {
1454 if( not pred( m_first[n] ) ) {
1455 return static_cast<size_type>( n );
1456 }
1457 }
1458 return npos;
1459 }
1460
1461 template<typename UnaryPredicate,
1462 DAW_REQ_UNARY_PRED( UnaryPredicate, CharT )>
1463 [[nodiscard]] constexpr size_type
1464 find_last_not_of_if( UnaryPredicate pred ) const {
1465 return find_last_not_of_if( pred, npos );
1466 }
1467
1468 template<string_view_bounds_type Bounds>
1469 [[nodiscard]] constexpr size_type
1471 size_type pos ) const {
1472
1473 if( empty( ) ) {
1474 return npos;
1475 }
1476 if( pos > size( ) ) {
1477 pos = size( ) - 1;
1478 }
1479 if( v.empty( ) ) {
1480 return pos;
1481 }
1482 for( auto n = static_cast<difference_type>( pos ); n >= 0; --n ) {
1483 if( v.find( m_first[n] ) == npos ) {
1484 return static_cast<size_type>( n );
1485 }
1486 }
1487 return npos;
1488 }
1489
1490 template<string_view_bounds_type Bounds>
1491 [[nodiscard]] constexpr size_type
1493 return find_last_not_of( v, npos );
1494 }
1495
1496 [[nodiscard]] constexpr size_type
1497 find_last_not_of( CharT c, size_type pos ) const {
1498 return find_last_not_of(
1499 basic_string_view<CharT, BoundsType>( std::addressof( c ), 1U ),
1500 pos );
1501 }
1502
1503 [[nodiscard]] constexpr size_type find_last_not_of( CharT c ) const {
1504 return find_last_not_of( c, npos );
1505 }
1506
1507 [[nodiscard]] constexpr size_type
1509 size_type count ) const {
1510 return find_last_not_of(
1511 basic_string_view<CharT, BoundsType>( s, count ), pos );
1512 }
1513
1514 [[nodiscard]] constexpr size_type
1516 return find_last_not_of( basic_string_view<CharT, BoundsType>( s ),
1517 pos );
1518 }
1519
1520 [[nodiscard]] constexpr size_type
1522 return find_last_not_of( basic_string_view<CharT, BoundsType>( s ),
1523 npos );
1524 }
1525
1526 [[nodiscard]] constexpr bool starts_with( CharT c ) const {
1527 if( empty( ) ) {
1528 return false;
1529 }
1530 return front( ) == c;
1531 }
1532
1533 template<string_view_bounds_type Bounds>
1534 [[nodiscard]] constexpr bool
1536 if( s.size( ) > size( ) ) {
1537 return false;
1538 }
1539 auto lhs = begin( );
1540 while( not s.empty( ) ) {
1541 if( *lhs++ != s.front( ) ) {
1542 return false;
1543 }
1544 s.remove_prefix( );
1545 }
1546 return true;
1547 }
1548
1549 [[nodiscard]] constexpr bool starts_with( const_pointer s ) const {
1550 return starts_with( basic_string_view<CharT, BoundsType>( s ) );
1551 }
1552
1553 [[nodiscard]] constexpr bool ends_with( CharT c ) const {
1554 if( empty( ) ) {
1555 return false;
1556 }
1557 return back( ) == c;
1558 }
1559
1560 template<string_view_bounds_type Bounds>
1561 [[nodiscard]] constexpr bool
1563 if( s.size( ) > size( ) ) {
1564 return false;
1565 }
1566 auto lhs = rbegin( );
1567 while( not s.empty( ) ) {
1568 if( *lhs++ != s.back( ) ) {
1569 return false;
1570 }
1571 s.remove_suffix( );
1572 }
1573 return true;
1574 }
1575
1576 [[nodiscard]] constexpr bool ends_with( const_pointer s ) const {
1577 return ends_with( basic_string_view<CharT, BoundsType>( s ) );
1578 }
1579
1580 [[nodiscard]] constexpr bool
1582 return compare( rhs ) == 0;
1583 }
1584
1585 template<typename StringView,
1586 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
1587 [[nodiscard]] friend constexpr bool
1588 operator==( StringView &&lhs, basic_string_view rhs ) noexcept {
1589 return basic_string_view( std::data( lhs ), std::size( lhs ) )
1590 .compare( rhs ) == 0;
1591 }
1592
1593 [[nodiscard]] friend constexpr bool
1595 return basic_string_view( lhs ).compare( rhs ) == 0;
1596 }
1597
1598 [[nodiscard]] constexpr bool
1600 return compare( rhs ) != 0;
1601 }
1602
1603 [[nodiscard]] friend constexpr bool
1605 return basic_string_view( lhs ).compare( rhs ) != 0;
1606 }
1607
1608 template<typename StringView,
1609 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
1610 [[nodiscard]] friend constexpr bool
1611 operator!=( StringView &&lhs, basic_string_view rhs ) noexcept {
1612 return basic_string_view( std::data( lhs ), std::size( lhs ) )
1613 .compare( rhs ) != 0;
1614 }
1615
1616 [[nodiscard]] constexpr bool operator<( basic_string_view rhs ) noexcept {
1617 return compare( rhs ) < 0;
1618 }
1619
1620 [[nodiscard]] friend constexpr bool
1621 operator<( const_pointer lhs, basic_string_view rhs ) noexcept {
1622 return basic_string_view( lhs ).compare( rhs ) < 0;
1623 }
1624
1625 template<typename StringView,
1626 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
1627 [[nodiscard]] friend constexpr bool
1628 operator<( StringView &&lhs, basic_string_view rhs ) noexcept {
1629 return basic_string_view( std::data( lhs ), std::size( lhs ) )
1630 .compare( rhs ) < 0;
1631 }
1632
1633 [[nodiscard]] constexpr bool
1634 operator<=( basic_string_view rhs ) noexcept {
1635 return compare( rhs ) <= 0;
1636 }
1637
1638 [[nodiscard]] friend constexpr bool
1639 operator<=( const_pointer lhs, basic_string_view rhs ) noexcept {
1640 return basic_string_view( lhs ).compare( rhs ) <= 0;
1641 }
1642
1643 template<typename StringView,
1644 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
1645 [[nodiscard]] friend constexpr bool
1646 operator<=( StringView &&lhs, basic_string_view rhs ) noexcept {
1647 return basic_string_view( std::data( lhs ), std::size( lhs ) )
1648 .compare( rhs ) <= 0;
1649 }
1650
1651 [[nodiscard]] constexpr bool operator>( basic_string_view rhs ) noexcept {
1652 return compare( rhs ) > 0;
1653 }
1654
1655 [[nodiscard]] friend constexpr bool
1657 return basic_string_view( lhs ).compare( rhs ) > 0;
1658 }
1659
1660 template<typename StringView,
1661 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
1662 [[nodiscard]] friend constexpr bool
1663 operator>( StringView &&lhs, basic_string_view rhs ) noexcept {
1664 return basic_string_view( std::data( lhs ), std::size( lhs ) )
1665 .compare( rhs ) > 0;
1666 }
1667
1668 [[nodiscard]] constexpr bool
1670 return compare( rhs ) >= 0;
1671 }
1672
1673 [[nodiscard]] friend constexpr bool
1675 return basic_string_view( lhs ).compare( rhs ) >= 0;
1676 }
1677
1678 template<typename StringView,
1679 DAW_REQ_CONTIG_CHAR_RANGE( StringView, CharT )>
1680 [[nodiscard]] friend constexpr bool
1681 operator>=( StringView &&lhs, basic_string_view rhs ) noexcept {
1682 return basic_string_view( std::data( lhs ), std::size( lhs ) )
1683 .compare( rhs ) >= 0;
1684 }
1685
1686 private:
1687 struct is_space {
1688 inline constexpr bool operator( )( CharT c ) const noexcept {
1689 return daw::nsc_or( c == CharT( ' ' ), c == CharT( '\t' ),
1690 c == CharT( '\n' ), c == CharT( '\v' ),
1691 c == CharT( '\f' ), c == CharT( '\r' ) );
1692 }
1693 };
1694
1695 public:
1696 template<typename UnaryPred, DAW_REQ_UNARY_PRED( UnaryPred, CharT )>
1697 constexpr void remove_prefix_while( UnaryPred is_whitespace ) noexcept {
1698 auto const last_pos = find_first_not_of_if( is_whitespace );
1699 remove_prefix( last_pos );
1700 }
1701
1702 constexpr void trim_prefix( ) noexcept {
1703 remove_prefix_while( is_space{ } );
1704 }
1705
1706 constexpr basic_string_view trim_prefix_copy( ) const noexcept {
1707 auto result = *this;
1708 result.remove_prefix_while( is_space{ } );
1709 return result;
1710 }
1711
1712 template<typename UnaryPred, DAW_REQ_UNARY_PRED( UnaryPred, CharT )>
1713 constexpr void remove_suffix_while( UnaryPred is_whitespace ) noexcept {
1714 auto pos = find_last_not_of_if( is_whitespace );
1715 resize( pos + 1U );
1716 }
1717
1718 constexpr void trim_suffix( ) noexcept {
1719 remove_suffix_while( is_space{ } );
1720 }
1721
1722 constexpr basic_string_view trim_suffix_copy( ) const noexcept {
1723 auto result = *this;
1724 result = remove_suffix_while( is_space{ } );
1725 return result;
1726 }
1727
1728 constexpr void trim( ) noexcept {
1729 trim_prefix( is_space{ } );
1730 trim_suffix( is_space{ } );
1731 }
1732
1733 constexpr basic_string_view trim_copy( ) const noexcept {
1734 auto result = trim_prefix_copy( );
1735 result.trim_suffix( );
1736 return result;
1737 }
1738 }; // basic_string_view
1739
1740 // CTAD
1741 template<typename CharT>
1742 basic_string_view( CharT const *s, std::size_t count )
1744
1745 template<typename CharT, std::size_t N>
1746 basic_string_view( CharT const ( &/*string_literal*/ )[N] )
1748 //
1749 //
1750 namespace string_view_literals {
1751 [[nodiscard]] constexpr string_view
1752 operator"" _sv( char const *str, std::size_t len ) noexcept {
1753 return string_view{ str, len };
1754 }
1755
1756#if defined( __cpp_char8_t )
1757 [[nodiscard]] constexpr u8string_view
1758 operator"" _sv( char8_t const *str, std::size_t len ) noexcept {
1759 return u8string_view{ str, len };
1760 }
1761#endif
1762
1763 [[nodiscard]] constexpr u16string_view
1764 operator"" _sv( char16_t const *str, std::size_t len ) noexcept {
1765 return u16string_view{ str, len };
1766 }
1767
1768 [[nodiscard]] constexpr u32string_view
1769 operator"" _sv( char32_t const *str, std::size_t len ) noexcept {
1770 return u32string_view{ str, len };
1771 }
1772
1773 [[nodiscard]] constexpr wstring_view
1774 operator"" _sv( wchar_t const *str, std::size_t len ) noexcept {
1775 return wstring_view{ str, len };
1776 }
1777 } // namespace string_view_literals
1778 } // namespace sv2
1779} // namespace daw
1780
1781namespace std {
1782 template<typename CharT, daw::sv2::string_view_bounds_type Bounds>
1783 struct hash<daw::sv2::basic_string_view<CharT, Bounds>> {
1784 [[nodiscard]] constexpr size_t
1786 return daw::fnv1a_hash( s.data( ), s.size( ) );
1787 }
1788 };
1789} // namespace std
1790
1791#undef DAW_REQ_UNARY_PRED
1792#undef DAW_REQ_CONTIG_CHAR_RANGE
1793#undef DAW_REQ_CONTIG_CHAR_RANGE
1794#undef DAW_REQ_CONTIG_CHAR_RANGE_CTOR
#define DAW_REQ_UNARY_PRED(Pred, Type)
Require Pred to be a Unary Predicate.
Definition: daw_string_view2.h:40
#define DAW_REQ_CONTIG_CHAR_RANGE(Range, CharT)
Require a contiguous character range.
Definition: daw_string_view2.h:47
static constexpr none_of_t< decltype(needle), needle, needles... > none_of
Definition: daw_string_view2.h:95
constexpr nodiscard_t nodiscard
Definition: daw_string_view2.h:69
static constexpr any_of_t< decltype(needle), needle, needles... > any_of
Definition: daw_string_view2.h:82
basic_string_view< char16_t > u16string_view
Definition: daw_string_view2_fwd.h:47
@ size
Store the end of range as a size_type. This is optimal for where calls to size( ) or remove_suffix li...
basic_string_view(CharT const (&)[N]) -> basic_string_view< CharT, default_string_view_bounds_type >
Definition: daw_string_view2.h:64
Definition: daw_string_view2.h:1781
A predicate type used in the find based routine to return true when the element is one of the specifi...
Definition: daw_string_view2.h:74
The class template basic_string_view describes an object that can refer to a constant contiguous sequ...
Definition: daw_string_view2.h:137
constexpr size_type find_first_of(const_pointer str) const
Definition: daw_string_view2.h:1142
constexpr size_type find_last_not_of(CharT c, size_type pos) const
Definition: daw_string_view2.h:1497
constexpr size_type find(basic_string_view< CharT, Bounds > v) const
Definition: daw_string_view2.h:1025
constexpr size_type find_last_of_if(UnaryPredicate pred) const
Definition: daw_string_view2.h:1365
constexpr const_iterator cbegin() const
Returns an iterator to the first character of the view.
Definition: daw_string_view2.h:372
constexpr size_type find(const_pointer s) const
Definition: daw_string_view2.h:1048
constexpr basic_string_view(std::nullptr_t, size_type n) noexcept=delete
Prevents nullptr literals and a size_type to construct a string_view.
constexpr size_type length() const
Returns the number of CharT elements in the view.
Definition: daw_string_view2.h:442
constexpr void trim_suffix() noexcept
Definition: daw_string_view2.h:1718
constexpr bool ends_with(const_pointer s) const
Definition: daw_string_view2.h:1576
constexpr size_type find_last_of(CharT const (&s)[N])
Definition: daw_string_view2.h:1329
constexpr size_type find_last_not_of(const_pointer s, size_type pos) const
Definition: daw_string_view2.h:1515
std::ptrdiff_t difference_type
Definition: daw_string_view2.h:149
constexpr basic_string_view substr(size_type pos) const
Definition: daw_string_view2.h:912
std::reverse_iterator< iterator > reverse_iterator
Definition: daw_string_view2.h:146
constexpr const_pointer data() const
Returns a pointer to the underlying character range corresponding to the values of the view.
Definition: daw_string_view2.h:459
constexpr void resize(size_type new_size)
Set the size of the range.
Definition: daw_string_view2.h:872
constexpr bool empty() const
Checks if the view has no characters.
Definition: daw_string_view2.h:448
constexpr size_type find_first_of(basic_string_view< CharT, Bounds > v) const
Find the first item in v that is in string from beginning.
Definition: daw_string_view2.h:1131
constexpr void remove_prefix(size_type n)
Increment the data( ) pointer by n. If string_view is empty, it does nothing.
Definition: daw_string_view2.h:525
CharT value_type
Definition: daw_string_view2.h:138
std::add_lvalue_reference_t< std::add_const_t< CharT > > const_reference
Definition: daw_string_view2.h:143
constexpr size_type find_first_not_of(const_pointer s, size_type pos) const
Definition: daw_string_view2.h:1417
constexpr basic_string_view(StringView &&sv, size_type count) noexcept
Construct a string_view from a type that forms a contiguous range of characters.
Definition: daw_string_view2.h:319
constexpr size_type find_last_of(CharT c) const
Definition: daw_string_view2.h:1316
constexpr void remove_prefix()
Increment the data( ) pointer by 1. If string_view is empty, it does nothing.
Definition: daw_string_view2.h:532
constexpr size_type rfind(const_pointer s, size_type pos) const
Definition: daw_string_view2.h:1098
constexpr size_type find_first_not_of(CharT const(&&s)[N], size_type pos) const
Definition: daw_string_view2.h:1424
constexpr bool operator>=(basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1669
constexpr size_type find_last_of_if(UnaryPredicate pred, size_type pos) const
Definition: daw_string_view2.h:1351
std::size_t size_type
Definition: daw_string_view2.h:148
constexpr basic_string_view pop_front_until(basic_string_view where)
Searches for where, returns substring between front and where, then pops off the substring and the wh...
Definition: daw_string_view2.h:596
constexpr size_t search(const_pointer str, size_type pos) const
Definition: daw_string_view2.h:1166
constexpr size_type find_first_not_of(basic_string_view< CharT, Bounds > v, size_type pos) const
Definition: daw_string_view2.h:1371
constexpr friend bool operator!=(StringView &&lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1611
constexpr bool operator>(basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1651
constexpr void remove_suffix()
Decrement the size( ) by 1 if size( ) > 0.
Definition: daw_string_view2.h:543
constexpr void trim() noexcept
Definition: daw_string_view2.h:1728
constexpr basic_string_view & remove_prefix_until(basic_string_view where, nodiscard_t)
searches for where, and disregards everything prior to where
Definition: daw_string_view2.h:834
constexpr void remove_suffix(size_type n)
Decrement the size( ) by n. If string_view is empty, it does nothing.
Definition: daw_string_view2.h:538
constexpr const_iterator begin() const
Returns an iterator to the first character of the view.
Definition: daw_string_view2.h:366
constexpr basic_string_view pop_back_until(UnaryPredicate pred)
searches for last position UnaryPredicate would be true, returns substring between pred and end,...
Definition: daw_string_view2.h:748
constexpr const_reverse_iterator crbegin() const
Returns a reverse iterator to the first character of the reversed view. It corresponds to the last ch...
Definition: daw_string_view2.h:388
constexpr CharT pop_front()
Increment the data( ) pointer by 1.
Definition: daw_string_view2.h:549
constexpr size_type find_last_of(CharT const (&s)[N], size_type pos)
Definition: daw_string_view2.h:1322
constexpr size_type find_last_not_of(basic_string_view< CharT, Bounds > v, size_type pos) const
Definition: daw_string_view2.h:1470
constexpr size_type rfind(const_pointer s, size_type pos, size_type count) const
Definition: daw_string_view2.h:1076
constexpr size_t search_last(const_pointer str, size_type pos) const
Definition: daw_string_view2.h:1199
constexpr size_type find_first_not_of_if(UnaryPredicate pred) const
Definition: daw_string_view2.h:1254
constexpr basic_string_view(CharPtr s) noexcept
Construct a string_view with a range starting with s.
Definition: daw_string_view2.h:279
constexpr size_type find_first_not_of(basic_string_view< CharT, Bounds > v) const
Definition: daw_string_view2.h:1393
constexpr basic_string_view pop_front_until(CharT where)
Searches for where, returns substring between front and where, then pops off the substring and the wh...
Definition: daw_string_view2.h:607
constexpr size_type find_first_of(CharT c, size_type pos) const
Definition: daw_string_view2.h:1258
constexpr friend bool operator>=(StringView &&lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1681
constexpr bool operator==(basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1581
constexpr size_type rfind(basic_string_view< CharT, Bounds > v) const
Definition: daw_string_view2.h:1083
constexpr size_type find_first_of(const_pointer str, size_type pos) const
Definition: daw_string_view2.h:1135
constexpr basic_string_view(basic_string_view< CharT, B > sv, size_type count) noexcept
Converting substr constructor from any string_view with matching CharT types.
Definition: daw_string_view2.h:292
constexpr size_type search_last(basic_string_view< CharT, Bounds > v, size_type pos) const
Definition: daw_string_view2.h:1177
constexpr basic_string_view & remove_prefix_until(UnaryPredicate pred)
Removes all elements until pred is true or end reached.
Definition: daw_string_view2.h:848
constexpr size_type find_last_of(const_pointer s, size_type pos) const
Definition: daw_string_view2.h:1340
constexpr size_type find_last_not_of(basic_string_view< CharT, Bounds > v) const
Definition: daw_string_view2.h:1492
constexpr basic_string_view trim_copy() const noexcept
Definition: daw_string_view2.h:1733
constexpr const_iterator cend() const
Returns an iterator to the character following the last character of the view. This character acts as...
Definition: daw_string_view2.h:404
constexpr size_type find_first_not_of(CharT const(&&s)[N]) const
Definition: daw_string_view2.h:1437
constexpr size_type rfind(CharT c) const
Definition: daw_string_view2.h:1092
constexpr bool starts_with(CharT c) const
Definition: daw_string_view2.h:1526
constexpr size_type find_last_not_of(const_pointer s) const
Definition: daw_string_view2.h:1521
constexpr void remove_prefix_while(UnaryPred is_whitespace) noexcept
Definition: daw_string_view2.h:1697
constexpr void trim_prefix() noexcept
Definition: daw_string_view2.h:1702
constexpr size_type find(const_pointer s, size_type pos) const
Definition: daw_string_view2.h:1043
constexpr reverse_iterator rend() const
Returns a reverse iterator to the character following the last character of the reversed view....
Definition: daw_string_view2.h:415
constexpr basic_string_view pop_front_until(UnaryPredicate pred, nodiscard_t)
Increment data until the predicate is true or the string_view is empty. Return a new string_view form...
Definition: daw_string_view2.h:627
constexpr friend bool operator>(const_pointer lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1656
constexpr basic_string_view try_pop_back_until(basic_string_view where)
searches for last where, returns substring between where and end, then pops off the substring and the...
Definition: daw_string_view2.h:784
constexpr basic_string_view(const_pointer s, size_type count) noexcept
Construct a string_view.
Definition: daw_string_view2.h:268
static constexpr int compare(basic_string_view< CharT, BL > lhs, basic_string_view< CharT, BR > rhs, Compare cmp=Compare{ })
Definition: daw_string_view2.h:920
constexpr size_type rfind(CharT c, size_type pos) const
Definition: daw_string_view2.h:1087
constexpr const_reference at(size_type pos) const
Access to the elements of range.
Definition: daw_string_view2.h:485
constexpr bool starts_with(const_pointer s) const
Definition: daw_string_view2.h:1549
constexpr size_type find(basic_string_view< CharT, Bounds > v, size_type pos) const
Definition: daw_string_view2.h:1007
constexpr size_type find_first_of(const_pointer s, size_type pos, size_type count) const
Definition: daw_string_view2.h:1271
constexpr size_type find(CharT c) const
Definition: daw_string_view2.h:1034
constexpr size_type copy(pointer dest, size_type count) const
Definition: daw_string_view2.h:895
constexpr friend bool operator==(const_pointer lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1594
constexpr basic_string_view & remove_prefix_until(CharT where)
searches for where, and disregards everything until the end of that
Definition: daw_string_view2.h:799
constexpr basic_string_view pop_back_until(CharT where)
searches for the last where, returns substring between where and end, then pops off the substring and...
Definition: daw_string_view2.h:725
constexpr bool starts_with(basic_string_view< CharT, Bounds > s) const
Definition: daw_string_view2.h:1535
constexpr basic_string_view pop_front(size_type count)
Increment data( ) by count elements and return a new string_view that would be formed formed from the...
Definition: daw_string_view2.h:560
constexpr basic_string_view try_pop_front_until(basic_string_view where)
searches for where, returns substring between front and where, then pops off the substring and the wh...
Definition: daw_string_view2.h:768
constexpr void reset()
Reset the range to a default constructed state.
Definition: daw_string_view2.h:517
constexpr size_type copy(pointer dest, size_type count, size_type pos) const
Definition: daw_string_view2.h:880
constexpr int compare(size_type pos1, size_type count1, const_pointer s, size_type count2, Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:997
constexpr size_type find_last_of(const_pointer s) const
Definition: daw_string_view2.h:1345
std::add_const_t< CharT > * const_pointer
Definition: daw_string_view2.h:140
constexpr size_type rfind(const_pointer s) const
Definition: daw_string_view2.h:1103
constexpr friend bool operator>=(const_pointer lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1674
constexpr bool operator!=(basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1599
constexpr size_type find_first_of_if(UnaryPredicate pred, size_type pos) const
Definition: daw_string_view2.h:1211
std::add_lvalue_reference_t< CharT > reference
Definition: daw_string_view2.h:141
constexpr basic_string_view & remove_prefix_until(basic_string_view where)
searches for where, and disregards everything until the end of that
Definition: daw_string_view2.h:823
constexpr int compare(size_type pos1, size_type count1, const_pointer s, Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:989
constexpr basic_string_view pop_back_until(basic_string_view where, nodiscard_t)
searches for last where, returns substring between where and end, then pops off the substring
Definition: daw_string_view2.h:677
constexpr size_type find_last_not_of_if(UnaryPredicate pred, size_type pos) const
Definition: daw_string_view2.h:1445
constexpr size_type find(CharT c, size_type pos) const
Definition: daw_string_view2.h:1029
const_iterator iterator
Definition: daw_string_view2.h:145
constexpr size_type find_first_not_of(CharT c) const
Definition: daw_string_view2.h:1404
constexpr basic_string_view(basic_string_view::const_pointer first, basic_string_view::const_pointer last) noexcept
Construct a string_view from a range formed by two character pointers.
Definition: daw_string_view2.h:342
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: daw_string_view2.h:147
constexpr const_reference front() const
Access the first element in range.
Definition: daw_string_view2.h:494
constexpr const_reverse_iterator crend() const
Returns a reverse iterator to the character following the last character of the reversed view....
Definition: daw_string_view2.h:426
constexpr basic_string_view trim_suffix_copy() const noexcept
Definition: daw_string_view2.h:1722
constexpr const_reference operator[](size_type pos) const
Access to the elements of range.
Definition: daw_string_view2.h:477
constexpr size_type find_last_not_of(const_pointer s, size_type pos, size_type count) const
Definition: daw_string_view2.h:1508
constexpr bool ends_with(CharT c) const
Definition: daw_string_view2.h:1553
constexpr size_type find_last_of(const_pointer s, size_type pos, size_type count) const
Definition: daw_string_view2.h:1335
constexpr size_type find_last_not_of_if(UnaryPredicate pred) const
Definition: daw_string_view2.h:1464
constexpr bool operator<(basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1616
constexpr size_type find_first_not_of_if(UnaryPredicate pred, size_type pos) const
Definition: daw_string_view2.h:1236
constexpr basic_string_view pop_front_until(CharT where, nodiscard_t)
Searches for where, returns substring between front and where, then pops off the substring.
Definition: daw_string_view2.h:584
constexpr size_type find_last_of(basic_string_view< CharT, Bounds > s) const
Definition: daw_string_view2.h:1307
constexpr const_iterator end() const
Returns an iterator to the character following the last character of the view. This character acts as...
Definition: daw_string_view2.h:396
constexpr const_pointer data_end() const
Returns a pointer to the character following the last character of the view. This character acts as a...
Definition: daw_string_view2.h:467
constexpr size_type search_last(basic_string_view< CharT, Bounds > v) const
Definition: daw_string_view2.h:1195
constexpr int compare(size_type pos1, size_type count1, basic_string_view v, Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:974
constexpr basic_string_view pop_back_until(basic_string_view where)
searches for last where, returns substring between where and end, then pops off the substring and the...
Definition: daw_string_view2.h:708
constexpr basic_string_view substr() const
Definition: daw_string_view2.h:908
constexpr basic_string_view pop_front_until(UnaryPredicate pred)
Increment data until the predicate is true or the string_view is empty. Return a new string_view form...
Definition: daw_string_view2.h:646
constexpr int compare(CharT const (&rhs)[N], Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:968
constexpr friend bool operator==(StringView &&lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1588
constexpr size_type find_first_of(basic_string_view< CharT, Bounds > v, size_type pos) const
Find the first item in v that is in string from pos.
Definition: daw_string_view2.h:1113
constexpr basic_string_view & remove_prefix_until(CharT where, nodiscard_t)
searches for where, and disregards everything prior to where
Definition: daw_string_view2.h:810
constexpr size_type find_first_not_of(CharT c, size_type pos) const
Definition: daw_string_view2.h:1398
constexpr const_reference back() const
Access the last element in range.
Definition: daw_string_view2.h:501
constexpr size_type find_last_not_of(CharT c) const
Definition: daw_string_view2.h:1503
constexpr size_type find_first_of_if(UnaryPredicate pred) const
Definition: daw_string_view2.h:1229
constexpr size_type rfind(basic_string_view< CharT, Bounds > v, size_type pos) const
Definition: daw_string_view2.h:1054
constexpr size_type find(const_pointer s, size_type pos, size_type count) const
Definition: daw_string_view2.h:1038
constexpr size_type search(basic_string_view< CharT, Bounds > v, size_type pos) const
Definition: daw_string_view2.h:1148
constexpr basic_string_view pop_back(size_type count)
create a substr of the last count characters and remove them from end
Definition: daw_string_view2.h:665
constexpr int compare(StringView &&rhs, Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:961
constexpr CharT pop_back()
Definition: daw_string_view2.h:655
CharT * pointer
Definition: daw_string_view2.h:139
const_pointer const_iterator
Definition: daw_string_view2.h:144
constexpr basic_string_view pop_back_until(CharT where, nodiscard_t)
searches for last where, returns substring between where and end, then pops off the substring
Definition: daw_string_view2.h:691
void i_am_a_daw_string_view2
A tag type for detecting string_view.
Definition: daw_string_view2.h:152
constexpr int compare(size_type pos1, size_type count1, basic_string_view< CharT, Bounds > v, size_type pos2, size_type count2, Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:981
constexpr bool ends_with(basic_string_view< CharT, Bounds > s) const
Definition: daw_string_view2.h:1562
constexpr size_type size() const
Returns the number of CharT elements in the view.
Definition: daw_string_view2.h:436
constexpr size_type find_first_not_of(const_pointer s) const
Definition: daw_string_view2.h:1430
constexpr friend bool operator!=(const_pointer lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1604
constexpr basic_string_view substr(size_type pos, size_type count) const
Definition: daw_string_view2.h:900
constexpr size_type find_first_of(CharT c) const
Definition: daw_string_view2.h:1265
constexpr void remove_suffix_while(UnaryPred is_whitespace) noexcept
Definition: daw_string_view2.h:1713
constexpr basic_string_view(CharT const (&string_literal)[N]) noexcept
Construct a string_view from a character array. Assumes a string literal like array with last element...
Definition: daw_string_view2.h:331
constexpr int compare(basic_string_view< CharT, B > rhs, Compare cmp=Compare{ }) const
Definition: daw_string_view2.h:953
constexpr size_type find_first_not_of(const_pointer s, size_type pos, size_type count) const
Definition: daw_string_view2.h:1410
constexpr size_type find_last_of(CharT c, size_type pos) const
Definition: daw_string_view2.h:1311
constexpr basic_string_view pop_front_until(basic_string_view where, nodiscard_t)
Increment data( ) until the substring where is found and return a new string_view that would be forme...
Definition: daw_string_view2.h:574
constexpr size_type find_last_of(basic_string_view< CharT, Bounds > s, size_type pos) const
Definition: daw_string_view2.h:1290
constexpr basic_string_view() noexcept=default
Construct an empty string_view.
constexpr void clear()
Empty the range.
Definition: daw_string_view2.h:510
constexpr basic_string_view & remove_prefix_until(UnaryPredicate pred, nodiscard_t)
removes all elements prior to predicate returning true
Definition: daw_string_view2.h:861
constexpr size_t search_last(const_pointer str) const
Definition: daw_string_view2.h:1204
constexpr basic_string_view(StringView &&sv) noexcept
Construct a string_view from a type that forms a contiguous range of characters.
Definition: daw_string_view2.h:306
constexpr size_type search(basic_string_view< CharT, Bounds > v) const
Definition: daw_string_view2.h:1162
constexpr basic_string_view trim_prefix_copy() const noexcept
Definition: daw_string_view2.h:1706
constexpr friend bool operator>(StringView &&lhs, basic_string_view rhs) noexcept
Definition: daw_string_view2.h:1663
constexpr reverse_iterator rbegin() const
Returns a reverse iterator to the first character of the reversed view. It corresponds to the last ch...
Definition: daw_string_view2.h:380
constexpr size_t search(const_pointer str) const
Definition: daw_string_view2.h:1171
Tag type for specifying that the searched for term/item is not to be removed from string_view.
Definition: daw_string_view2.h:68
A predicate type used in the find based routine to return true when the element is none of the specif...
Definition: daw_string_view2.h:87