From 2096f37d7a580a4b4ddce2a44abb80ff90f273ee Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Thu, 21 Mar 2024 11:57:07 +0100 Subject: [PATCH] [libc++][NFC] Use __constexpr_memmove instead of copy_n in <__string/char_traits.h> (#85920) `copy_n` has been used to allow constant evaluation of `char_traits`. We now have `__constexpr_memmove`, which `copy_n` just forwards to. We can call `__constexpr_memmove` directly, avoiding a bunch of instantiations. This reduces the time it takes to include `` from 321ms to 285ms. --- libcxx/include/__string/char_traits.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h index 5880d3a22db2e7..47ed1057caaab1 100644 --- a/libcxx/include/__string/char_traits.h +++ b/libcxx/include/__string/char_traits.h @@ -9,7 +9,6 @@ #ifndef _LIBCPP___STRING_CHAR_TRAITS_H #define _LIBCPP___STRING_CHAR_TRAITS_H -#include <__algorithm/copy_n.h> #include <__algorithm/fill_n.h> #include <__algorithm/find_end.h> #include <__algorithm/find_first_of.h> @@ -144,7 +143,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2), "char_traits::copy: source and destination ranges overlap"); - std::copy_n(__s2, __n, __s1); + std::__constexpr_memmove(__s1, __s2, __element_count(__n)); return __s1; } @@ -221,7 +220,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2), "char_traits::copy: source and destination ranges overlap"); - std::copy_n(__s2, __n, __s1); + std::__constexpr_memmove(__s1, __s2, __element_count(__n)); return __s1; } @@ -287,7 +286,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2), "char_traits::copy: source and destination ranges overlap"); - std::copy_n(__s2, __n, __s1); + std::__constexpr_memmove(__s1, __s2, __element_count(__n)); return __s1; } @@ -366,7 +365,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2), "char_traits::copy: source and destination ranges overlap"); - std::copy_n(__s2, __n, __s1); + std::__constexpr_memmove(__s1, __s2, __element_count(__n)); return __s1; } @@ -454,7 +453,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - std::copy_n(__s2, __n, __s1); + std::__constexpr_memmove(__s1, __s2, __element_count(__n)); return __s1; }