diff options
Diffstat (limited to 'libcxx/include/__string/constexpr_c_functions.h')
| -rw-r--r-- | libcxx/include/__string/constexpr_c_functions.h | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/libcxx/include/__string/constexpr_c_functions.h b/libcxx/include/__string/constexpr_c_functions.h index 0bc128b68b57..fbe7e10d440c 100644 --- a/libcxx/include/__string/constexpr_c_functions.h +++ b/libcxx/include/__string/constexpr_c_functions.h @@ -204,23 +204,26 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copy return __dest; } -template <class _Tp, class _Up, __enable_if_t<__is_always_bitcastable<_Up, _Tp>::value, int> = 0> +template <class _Tp, class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n) { + static_assert(__is_always_bitcastable<_Up, _Tp>::value); size_t __count = static_cast<size_t>(__n); if (__libcpp_is_constant_evaluated()) { #ifdef _LIBCPP_COMPILER_CLANG_BASED - if (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value) { + if _LIBCPP_CONSTEXPR (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value) { ::__builtin_memmove(__dest, __src, __count * sizeof(_Tp)); return __dest; - } + } else #endif - if (std::__is_pointer_in_range(__src, __src + __count, __dest)) { - for (; __count > 0; --__count) - std::__assign_trivially_copyable(__dest[__count - 1], __src[__count - 1]); - } else { - for (size_t __i = 0; __i != __count; ++__i) - std::__assign_trivially_copyable(__dest[__i], __src[__i]); + { + if (std::__is_pointer_in_range(__src, __src + __count, __dest)) { + for (; __count > 0; --__count) + std::__assign_trivially_copyable(__dest[__count - 1], __src[__count - 1]); + } else { + for (size_t __i = 0; __i != __count; ++__i) + std::__assign_trivially_copyable(__dest[__i], __src[__i]); + } } } else if (__count > 0) { ::__builtin_memmove(__dest, __src, (__count - 1) * sizeof(_Tp) + __datasizeof_v<_Tp>); |
