@@ -39,132 +39,37 @@ _LIBCPP_PUSH_MACROS
39
39
_LIBCPP_BEGIN_NAMESPACE_STD
40
40
41
41
template <class _CharT >
42
- struct _LIBCPP_TEMPLATE_VIS char_traits
42
+ struct char_traits ;
43
+ /*
44
+ The Standard does not define the base template for char_traits because it is impossible to provide
45
+ a correct definition for arbitrary character types. Instead, it requires implementations to provide
46
+ specializations for predefined character types like `char`, `wchar_t` and others. We provide this as
47
+ exposition-only to document what members a char_traits specialization should provide:
43
48
{
44
49
using char_type = _CharT;
45
- using int_type = int ;
46
- using off_type = streamoff;
47
- using pos_type = streampos;
48
- using state_type = mbstate_t ;
49
-
50
- static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17
51
- assign (char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
52
- static inline _LIBCPP_CONSTEXPR bool eq (char_type __c1, char_type __c2) _NOEXCEPT
53
- {return __c1 == __c2;}
54
- static inline _LIBCPP_CONSTEXPR bool lt (char_type __c1, char_type __c2) _NOEXCEPT
55
- {return __c1 < __c2;}
56
-
57
- static _LIBCPP_CONSTEXPR_SINCE_CXX17
58
- int compare (const char_type* __s1, const char_type* __s2, size_t __n);
59
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
60
- size_t length (const char_type* __s);
61
- _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
62
- const char_type* find (const char_type* __s, size_t __n, const char_type& __a);
63
- static _LIBCPP_CONSTEXPR_SINCE_CXX20
64
- char_type* move (char_type* __s1, const char_type* __s2, size_t __n);
65
- _LIBCPP_INLINE_VISIBILITY
66
- static _LIBCPP_CONSTEXPR_SINCE_CXX20
67
- char_type* copy (char_type* __s1, const char_type* __s2, size_t __n);
68
- _LIBCPP_INLINE_VISIBILITY
69
- static _LIBCPP_CONSTEXPR_SINCE_CXX20
70
- char_type* assign (char_type* __s, size_t __n, char_type __a);
71
-
72
- static inline _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT
73
- {return eq_int_type (__c, eof ()) ? ~eof () : __c;}
74
- static inline _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT
75
- {return char_type (__c);}
76
- static inline _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT
77
- {return int_type (__c);}
78
- static inline _LIBCPP_CONSTEXPR bool eq_int_type (int_type __c1, int_type __c2) _NOEXCEPT
79
- {return __c1 == __c2;}
80
- static inline _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT
81
- {return int_type (EOF);}
50
+ using int_type = ...;
51
+ using off_type = ...;
52
+ using pos_type = ...;
53
+ using state_type = ...;
54
+
55
+ static void assign(char_type&, const char_type&);
56
+ static bool eq(char_type, char_type);
57
+ static bool lt(char_type, char_type);
58
+
59
+ static int compare(const char_type*, const char_type*, size_t);
60
+ static size_t length(const char_type*);
61
+ static const char_type* find(const char_type*, size_t, const char_type&);
62
+ static char_type* move(char_type*, const char_type*, size_t);
63
+ static char_type* copy(char_type*, const char_type* __s2, size_t);
64
+ static char_type* assign(char_type*, size_t, char_type);
65
+
66
+ static int_type not_eof(int_type);
67
+ static char_type to_char_type(int_type);
68
+ static int_type to_int_type(char_type);
69
+ static bool eq_int_type(int_type, int_type);
70
+ static int_type eof();
82
71
};
83
-
84
- template <class _CharT >
85
- _LIBCPP_CONSTEXPR_SINCE_CXX17 int
86
- char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
87
- {
88
- for (; __n; --__n, ++__s1, ++__s2)
89
- {
90
- if (lt (*__s1, *__s2))
91
- return -1 ;
92
- if (lt (*__s2, *__s1))
93
- return 1 ;
94
- }
95
- return 0 ;
96
- }
97
-
98
- template <class _CharT >
99
- inline
100
- _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t
101
- char_traits<_CharT>::length(const char_type* __s)
102
- {
103
- size_t __len = 0 ;
104
- for (; !eq (*__s, char_type (0 )); ++__s)
105
- ++__len;
106
- return __len;
107
- }
108
-
109
- template <class _CharT >
110
- inline
111
- _LIBCPP_CONSTEXPR_SINCE_CXX17 const _CharT*
112
- char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
113
- {
114
- for (; __n; --__n)
115
- {
116
- if (eq (*__s, __a))
117
- return __s;
118
- ++__s;
119
- }
120
- return nullptr ;
121
- }
122
-
123
- template <class _CharT >
124
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _CharT*
125
- char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
126
- {
127
- if (__n == 0 ) return __s1;
128
- char_type* __r = __s1;
129
- if (__s1 < __s2)
130
- {
131
- for (; __n; --__n, ++__s1, ++__s2)
132
- assign (*__s1, *__s2);
133
- }
134
- else if (__s2 < __s1)
135
- {
136
- __s1 += __n;
137
- __s2 += __n;
138
- for (; __n; --__n)
139
- assign (*--__s1, *--__s2);
140
- }
141
- return __r;
142
- }
143
-
144
- template <class _CharT >
145
- inline _LIBCPP_CONSTEXPR_SINCE_CXX20
146
- _CharT*
147
- char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
148
- {
149
- if (!__libcpp_is_constant_evaluated ()) {
150
- _LIBCPP_ASSERT (__s2 < __s1 || __s2 >= __s1+__n, " char_traits::copy overlapped range" );
151
- }
152
- char_type* __r = __s1;
153
- for (; __n; --__n, ++__s1, ++__s2)
154
- assign (*__s1, *__s2);
155
- return __r;
156
- }
157
-
158
- template <class _CharT >
159
- inline _LIBCPP_CONSTEXPR_SINCE_CXX20
160
- _CharT*
161
- char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
162
- {
163
- char_type* __r = __s;
164
- for (; __n; --__n, ++__s)
165
- assign (*__s, __a);
166
- return __r;
167
- }
72
+ */
168
73
169
74
template <class _CharT >
170
75
_LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -300,7 +205,6 @@ char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a)
300
205
#endif
301
206
}
302
207
303
-
304
208
// char_traits<wchar_t>
305
209
306
210
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -713,6 +617,202 @@ char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& _
713
617
return nullptr ;
714
618
}
715
619
620
+ //
621
+ // Temporary extensions for std::char_traits<unsigned char> and std::char_traits<signed char>.
622
+ // TODO: Remove those in LLVM 18.
623
+ //
624
+ template <>
625
+ struct _LIBCPP_TEMPLATE_VIS
626
+ _LIBCPP_DEPRECATED_ (" char_traits<unsigned char> is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it." )
627
+ char_traits<unsigned char>
628
+ {
629
+ using char_type = unsigned char ;
630
+ using int_type = int ;
631
+ using off_type = streamoff;
632
+ using pos_type = streampos;
633
+ using state_type = mbstate_t ;
634
+
635
+ static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17
636
+ assign (char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
637
+ static inline _LIBCPP_CONSTEXPR bool eq (char_type __c1, char_type __c2) _NOEXCEPT
638
+ {return __c1 == __c2;}
639
+ static inline _LIBCPP_CONSTEXPR bool lt (char_type __c1, char_type __c2) _NOEXCEPT
640
+ {return __c1 < __c2;}
641
+
642
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17
643
+ int compare (const char_type* __s1, const char_type* __s2, size_t __n) {
644
+ for (; __n; --__n, ++__s1, ++__s2)
645
+ {
646
+ if (lt (*__s1, *__s2))
647
+ return -1 ;
648
+ if (lt (*__s2, *__s1))
649
+ return 1 ;
650
+ }
651
+ return 0 ;
652
+ }
653
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
654
+ size_t length (const char_type* __s) {
655
+ size_t __len = 0 ;
656
+ for (; !eq (*__s, char_type (0 )); ++__s)
657
+ ++__len;
658
+ return __len;
659
+ }
660
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
661
+ const char_type* find (const char_type* __s, size_t __n, const char_type& __a) {
662
+ for (; __n; --__n)
663
+ {
664
+ if (eq (*__s, __a))
665
+ return __s;
666
+ ++__s;
667
+ }
668
+ return nullptr ;
669
+ }
670
+ static _LIBCPP_CONSTEXPR_SINCE_CXX20
671
+ char_type* move (char_type* __s1, const char_type* __s2, size_t __n) {
672
+ if (__n == 0 ) return __s1;
673
+ char_type* __r = __s1;
674
+ if (__s1 < __s2)
675
+ {
676
+ for (; __n; --__n, ++__s1, ++__s2)
677
+ assign (*__s1, *__s2);
678
+ }
679
+ else if (__s2 < __s1)
680
+ {
681
+ __s1 += __n;
682
+ __s2 += __n;
683
+ for (; __n; --__n)
684
+ assign (*--__s1, *--__s2);
685
+ }
686
+ return __r;
687
+ }
688
+ _LIBCPP_INLINE_VISIBILITY
689
+ static _LIBCPP_CONSTEXPR_SINCE_CXX20
690
+ char_type* copy (char_type* __s1, const char_type* __s2, size_t __n) {
691
+ if (!__libcpp_is_constant_evaluated ()) {
692
+ _LIBCPP_ASSERT (__s2 < __s1 || __s2 >= __s1+__n, " char_traits::copy overlapped range" );
693
+ }
694
+ char_type* __r = __s1;
695
+ for (; __n; --__n, ++__s1, ++__s2)
696
+ assign (*__s1, *__s2);
697
+ return __r;
698
+ }
699
+ _LIBCPP_INLINE_VISIBILITY
700
+ static _LIBCPP_CONSTEXPR_SINCE_CXX20
701
+ char_type* assign (char_type* __s, size_t __n, char_type __a) {
702
+ char_type* __r = __s;
703
+ for (; __n; --__n, ++__s)
704
+ assign (*__s, __a);
705
+ return __r;
706
+ }
707
+
708
+ static inline _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT
709
+ {return eq_int_type (__c, eof ()) ? ~eof () : __c;}
710
+ static inline _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT
711
+ {return char_type (__c);}
712
+ static inline _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT
713
+ {return int_type (__c);}
714
+ static inline _LIBCPP_CONSTEXPR bool eq_int_type (int_type __c1, int_type __c2) _NOEXCEPT
715
+ {return __c1 == __c2;}
716
+ static inline _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT
717
+ {return int_type (EOF);}
718
+ };
719
+
720
+ template <>
721
+ struct _LIBCPP_TEMPLATE_VIS
722
+ _LIBCPP_DEPRECATED_ (" char_traits<signed char> is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it." )
723
+ char_traits<signed char>
724
+ {
725
+ using char_type = signed char ;
726
+ using int_type = int ;
727
+ using off_type = streamoff;
728
+ using pos_type = streampos;
729
+ using state_type = mbstate_t ;
730
+
731
+ static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17
732
+ assign (char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
733
+ static inline _LIBCPP_CONSTEXPR bool eq (char_type __c1, char_type __c2) _NOEXCEPT
734
+ {return __c1 == __c2;}
735
+ static inline _LIBCPP_CONSTEXPR bool lt (char_type __c1, char_type __c2) _NOEXCEPT
736
+ {return __c1 < __c2;}
737
+
738
+ static _LIBCPP_CONSTEXPR_SINCE_CXX17
739
+ int compare (const char_type* __s1, const char_type* __s2, size_t __n) {
740
+ for (; __n; --__n, ++__s1, ++__s2)
741
+ {
742
+ if (lt (*__s1, *__s2))
743
+ return -1 ;
744
+ if (lt (*__s2, *__s1))
745
+ return 1 ;
746
+ }
747
+ return 0 ;
748
+ }
749
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
750
+ size_t length (const char_type* __s) {
751
+ size_t __len = 0 ;
752
+ for (; !eq (*__s, char_type (0 )); ++__s)
753
+ ++__len;
754
+ return __len;
755
+ }
756
+ _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
757
+ const char_type* find (const char_type* __s, size_t __n, const char_type& __a) {
758
+ for (; __n; --__n)
759
+ {
760
+ if (eq (*__s, __a))
761
+ return __s;
762
+ ++__s;
763
+ }
764
+ return nullptr ;
765
+ }
766
+ static _LIBCPP_CONSTEXPR_SINCE_CXX20
767
+ char_type* move (char_type* __s1, const char_type* __s2, size_t __n) {
768
+ if (__n == 0 ) return __s1;
769
+ char_type* __r = __s1;
770
+ if (__s1 < __s2)
771
+ {
772
+ for (; __n; --__n, ++__s1, ++__s2)
773
+ assign (*__s1, *__s2);
774
+ }
775
+ else if (__s2 < __s1)
776
+ {
777
+ __s1 += __n;
778
+ __s2 += __n;
779
+ for (; __n; --__n)
780
+ assign (*--__s1, *--__s2);
781
+ }
782
+ return __r;
783
+ }
784
+ _LIBCPP_INLINE_VISIBILITY
785
+ static _LIBCPP_CONSTEXPR_SINCE_CXX20
786
+ char_type* copy (char_type* __s1, const char_type* __s2, size_t __n) {
787
+ if (!__libcpp_is_constant_evaluated ()) {
788
+ _LIBCPP_ASSERT (__s2 < __s1 || __s2 >= __s1+__n, " char_traits::copy overlapped range" );
789
+ }
790
+ char_type* __r = __s1;
791
+ for (; __n; --__n, ++__s1, ++__s2)
792
+ assign (*__s1, *__s2);
793
+ return __r;
794
+ }
795
+ _LIBCPP_INLINE_VISIBILITY
796
+ static _LIBCPP_CONSTEXPR_SINCE_CXX20
797
+ char_type* assign (char_type* __s, size_t __n, char_type __a) {
798
+ char_type* __r = __s;
799
+ for (; __n; --__n, ++__s)
800
+ assign (*__s, __a);
801
+ return __r;
802
+ }
803
+
804
+ static inline _LIBCPP_CONSTEXPR int_type not_eof (int_type __c) _NOEXCEPT
805
+ {return eq_int_type (__c, eof ()) ? ~eof () : __c;}
806
+ static inline _LIBCPP_CONSTEXPR char_type to_char_type (int_type __c) _NOEXCEPT
807
+ {return char_type (__c);}
808
+ static inline _LIBCPP_CONSTEXPR int_type to_int_type (char_type __c) _NOEXCEPT
809
+ {return int_type (__c);}
810
+ static inline _LIBCPP_CONSTEXPR bool eq_int_type (int_type __c1, int_type __c2) _NOEXCEPT
811
+ {return __c1 == __c2;}
812
+ static inline _LIBCPP_CONSTEXPR int_type eof () _NOEXCEPT
813
+ {return int_type (EOF);}
814
+ };
815
+
716
816
// helper fns for basic_string and string_view
717
817
718
818
// __str_find
0 commit comments