Skip to content

Commit b7763e0

Browse files
committed
[libc++][NFC] Merge identical char_traits functions into a base class
1 parent 655651a commit b7763e0

File tree

1 file changed

+64
-202
lines changed

1 file changed

+64
-202
lines changed

libcxx/include/__string/char_traits.h

+64-202
Original file line numberDiff line numberDiff line change
@@ -170,31 +170,72 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char> {
170170
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); }
171171
};
172172

173-
// char_traits<wchar_t>
174-
175-
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
176-
template <>
177-
struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> {
178-
using char_type = wchar_t;
179-
using int_type = wint_t;
173+
template <class _CharT, class _IntT, _IntT _EOFVal>
174+
struct __char_traits_base {
175+
using char_type = _CharT;
176+
using int_type = _IntT;
180177
using off_type = streamoff;
181-
using pos_type = streampos;
182178
using state_type = mbstate_t;
183-
# if _LIBCPP_STD_VER >= 20
179+
#if _LIBCPP_STD_VER >= 20
184180
using comparison_category = strong_ordering;
185-
# endif
181+
#endif
186182

187-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
188-
assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
189-
__c1 = __c2;
183+
// There are different aliases for the different char types, but they are all aliases to this type
184+
using pos_type = fpos<mbstate_t>;
185+
186+
_LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 void
187+
assign(char_type& __lhs, const char_type& __rhs) _NOEXCEPT {
188+
__lhs = __rhs;
190189
}
191-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
192-
return __c1 == __c2;
190+
191+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq(char_type __lhs, char_type __rhs) _NOEXCEPT {
192+
return __lhs == __rhs;
193193
}
194-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
195-
return __c1 < __c2;
194+
195+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool lt(char_type __lhs, char_type __rhs) _NOEXCEPT {
196+
return __lhs < __rhs;
196197
}
197198

199+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
200+
move(char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
201+
return std::__constexpr_memmove(__dest, __src, __element_count(__n));
202+
}
203+
204+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
205+
copy(char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
206+
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__dest, __dest + __n, __src),
207+
"char_traits::copy: source and destination ranges overlap");
208+
return std::__constexpr_memmove(__dest, __src, __element_count(__n));
209+
}
210+
211+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
212+
assign(char_type* __str, size_t __n, char_type __fill_char) _NOEXCEPT {
213+
std::fill_n(__str, __n, __fill_char);
214+
return __str;
215+
}
216+
217+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
218+
return char_type(__c);
219+
}
220+
221+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT { return int_type(__c); }
222+
223+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __lhs, int_type __rhs) _NOEXCEPT {
224+
return __lhs == __rhs;
225+
}
226+
227+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return _EOFVal; }
228+
229+
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
230+
return eq_int_type(__c, eof()) ? static_cast<int_type>(~eof()) : __c;
231+
}
232+
};
233+
234+
// char_traits<wchar_t>
235+
236+
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
237+
template <>
238+
struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> : __char_traits_base<wchar_t, wint_t, static_cast<wint_t>(WEOF)> {
198239
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
199240
compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
200241
if (__n == 0)
@@ -212,63 +253,14 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> {
212253
return nullptr;
213254
return std::__constexpr_wmemchr(__s, __a, __n);
214255
}
215-
216-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
217-
move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
218-
return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
219-
}
220-
221-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
222-
copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
223-
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
224-
"char_traits::copy: source and destination ranges overlap");
225-
std::__constexpr_memmove(__s1, __s2, __element_count(__n));
226-
return __s1;
227-
}
228-
229-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
230-
assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
231-
std::fill_n(__s, __n, __a);
232-
return __s;
233-
}
234-
235-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
236-
return eq_int_type(__c, eof()) ? ~eof() : __c;
237-
}
238-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
239-
return char_type(__c);
240-
}
241-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
242-
return int_type(__c);
243-
}
244-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
245-
return __c1 == __c2;
246-
}
247-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(WEOF); }
248256
};
249257
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
250258

251259
#ifndef _LIBCPP_HAS_NO_CHAR8_T
252260

253261
template <>
254-
struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> {
255-
using char_type = char8_t;
256-
using int_type = unsigned int;
257-
using off_type = streamoff;
258-
using pos_type = u8streampos;
259-
using state_type = mbstate_t;
260-
# if _LIBCPP_STD_VER >= 20
261-
using comparison_category = strong_ordering;
262-
# endif
263-
264-
static inline _LIBCPP_HIDE_FROM_ABI constexpr void assign(char_type& __c1, const char_type& __c2) noexcept {
265-
__c1 = __c2;
266-
}
267-
static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq(char_type __c1, char_type __c2) noexcept {
268-
return __c1 == __c2;
269-
}
270-
static inline _LIBCPP_HIDE_FROM_ABI constexpr bool lt(char_type __c1, char_type __c2) noexcept { return __c1 < __c2; }
271-
262+
struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
263+
: __char_traits_base<char8_t, unsigned int, static_cast<unsigned int>(EOF)> {
272264
static _LIBCPP_HIDE_FROM_ABI constexpr int
273265
compare(const char_type* __s1, const char_type* __s2, size_t __n) noexcept {
274266
return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
@@ -282,61 +274,13 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> {
282274
find(const char_type* __s, size_t __n, const char_type& __a) noexcept {
283275
return std::__constexpr_memchr(__s, __a, __n);
284276
}
285-
286-
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
287-
move(char_type* __s1, const char_type* __s2, size_t __n) noexcept {
288-
return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
289-
}
290-
291-
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
292-
copy(char_type* __s1, const char_type* __s2, size_t __n) noexcept {
293-
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
294-
"char_traits::copy: source and destination ranges overlap");
295-
std::__constexpr_memmove(__s1, __s2, __element_count(__n));
296-
return __s1;
297-
}
298-
299-
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
300-
assign(char_type* __s, size_t __n, char_type __a) noexcept {
301-
std::fill_n(__s, __n, __a);
302-
return __s;
303-
}
304-
305-
static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type not_eof(int_type __c) noexcept {
306-
return eq_int_type(__c, eof()) ? ~eof() : __c;
307-
}
308-
static inline _LIBCPP_HIDE_FROM_ABI constexpr char_type to_char_type(int_type __c) noexcept { return char_type(__c); }
309-
static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type to_int_type(char_type __c) noexcept { return int_type(__c); }
310-
static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept {
311-
return __c1 == __c2;
312-
}
313-
static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type eof() noexcept { return int_type(EOF); }
314277
};
315278

316279
#endif // _LIBCPP_HAS_NO_CHAR8_T
317280

318281
template <>
319-
struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> {
320-
using char_type = char16_t;
321-
using int_type = uint_least16_t;
322-
using off_type = streamoff;
323-
using pos_type = u16streampos;
324-
using state_type = mbstate_t;
325-
#if _LIBCPP_STD_VER >= 20
326-
using comparison_category = strong_ordering;
327-
#endif
328-
329-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
330-
assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
331-
__c1 = __c2;
332-
}
333-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
334-
return __c1 == __c2;
335-
}
336-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
337-
return __c1 < __c2;
338-
}
339-
282+
struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
283+
: __char_traits_base<char16_t, uint_least16_t, static_cast<uint_least16_t>(0xFFFF)> {
340284
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
341285
compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
342286
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
@@ -349,38 +293,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> {
349293
return nullptr;
350294
return __match;
351295
}
352-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
353-
move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
354-
return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
355-
}
356-
357-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
358-
copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
359-
_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
360-
"char_traits::copy: source and destination ranges overlap");
361-
std::__constexpr_memmove(__s1, __s2, __element_count(__n));
362-
return __s1;
363-
}
364-
365-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
366-
assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
367-
std::fill_n(__s, __n, __a);
368-
return __s;
369-
}
370-
371-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
372-
return eq_int_type(__c, eof()) ? ~eof() : __c;
373-
}
374-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
375-
return char_type(__c);
376-
}
377-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
378-
return int_type(__c);
379-
}
380-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
381-
return __c1 == __c2;
382-
}
383-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(0xFFFF); }
384296
};
385297

386298
inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
@@ -402,27 +314,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char16_t>::length(const
402314
}
403315

404316
template <>
405-
struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> {
406-
using char_type = char32_t;
407-
using int_type = uint_least32_t;
408-
using off_type = streamoff;
409-
using pos_type = u32streampos;
410-
using state_type = mbstate_t;
411-
#if _LIBCPP_STD_VER >= 20
412-
using comparison_category = strong_ordering;
413-
#endif
414-
415-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
416-
assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
417-
__c1 = __c2;
418-
}
419-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
420-
return __c1 == __c2;
421-
}
422-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
423-
return __c1 < __c2;
424-
}
425-
317+
struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
318+
: __char_traits_base<char32_t, uint_least32_t, static_cast<uint_least32_t>(0xFFFFFFFF)> {
426319
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
427320
compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
428321
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
@@ -435,37 +328,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> {
435328
return nullptr;
436329
return __match;
437330
}
438-
439-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
440-
move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
441-
return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
442-
}
443-
444-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
445-
copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
446-
std::__constexpr_memmove(__s1, __s2, __element_count(__n));
447-
return __s1;
448-
}
449-
450-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
451-
assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
452-
std::fill_n(__s, __n, __a);
453-
return __s;
454-
}
455-
456-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
457-
return eq_int_type(__c, eof()) ? ~eof() : __c;
458-
}
459-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
460-
return char_type(__c);
461-
}
462-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
463-
return int_type(__c);
464-
}
465-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
466-
return __c1 == __c2;
467-
}
468-
static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(0xFFFFFFFF); }
469331
};
470332

471333
inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int

0 commit comments

Comments
 (0)