diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -707,7 +707,6 @@ __type_traits/conjunction.h __type_traits/copy_cv.h __type_traits/copy_cvref.h - __type_traits/datasizeof.h __type_traits/decay.h __type_traits/dependent_type.h __type_traits/disjunction.h diff --git a/libcxx/include/__algorithm/copy_move_common.h b/libcxx/include/__algorithm/copy_move_common.h --- a/libcxx/include/__algorithm/copy_move_common.h +++ b/libcxx/include/__algorithm/copy_move_common.h @@ -15,7 +15,6 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> -#include <__string/constexpr_c_functions.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_always_bitcastable.h> #include <__type_traits/is_constant_evaluated.h> @@ -62,8 +61,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) { const size_t __n = static_cast(__last - __first); - - std::__constexpr_memmove(__result, __first, __element_count(__n)); + ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); return std::make_pair(__last, __result + __n); } @@ -74,7 +72,7 @@ const size_t __n = static_cast(__last - __first); __result -= __n; - std::__constexpr_memmove(__result, __first, __element_count(__n)); + ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); return std::make_pair(__last, __result); } @@ -121,6 +119,16 @@ return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first)); } +template +struct __can_copy_without_conversion : false_type {}; + +template +struct __can_copy_without_conversion< + _IterOps, + _InValue, + _OutIter, + __enable_if_t >::value> > : true_type {}; + template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> __dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) { +#ifdef _LIBCPP_COMPILER_GCC + // GCC doesn't support `__builtin_memmove` during constant evaluation. + if (__libcpp_is_constant_evaluated()) { + return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); + } +#else + // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is + // insufficient). Also, conversions are not supported. + if (__libcpp_is_constant_evaluated()) { + using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>; + if (!is_trivially_copyable<_InValue>::value || + !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) { + return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); + } + } +#endif // _LIBCPP_COMPILER_GCC + using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>; return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first)); } diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h --- a/libcxx/include/__string/char_traits.h +++ b/libcxx/include/__string/char_traits.h @@ -170,6 +170,25 @@ {return int_type(EOF);} }; +template +_LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 +_CharT* __char_traits_move(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT +{ +#ifdef _LIBCPP_COMPILER_GCC + if (__libcpp_is_constant_evaluated()) { + if (__n == 0) + return __dest; + _CharT* __allocation = new _CharT[__n]; + std::copy_n(__source, __n, __allocation); + std::copy_n(static_cast(__allocation), __n, __dest); + delete[] __allocation; + return __dest; + } +#endif + ::__builtin_memmove(__dest, __source, __n * sizeof(_CharT)); + return __dest; +} + // char_traits template <> @@ -230,7 +249,7 @@ static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); + return std::__char_traits_move(__s1, __s2, __n); } static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 @@ -301,7 +320,7 @@ static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); + return std::__char_traits_move(__s1, __s2, __n); } static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 @@ -365,7 +384,7 @@ static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); + return std::__char_traits_move(__s1, __s2, __n); } static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 @@ -449,7 +468,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); + return std::__char_traits_move(__s1, __s2, __n); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 @@ -543,7 +562,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { - return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); + return std::__char_traits_move(__s1, __s2, __n); } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 diff --git a/libcxx/include/__string/constexpr_c_functions.h b/libcxx/include/__string/constexpr_c_functions.h --- a/libcxx/include/__string/constexpr_c_functions.h +++ b/libcxx/include/__string/constexpr_c_functions.h @@ -10,15 +10,11 @@ #define _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H #include <__config> -#include <__type_traits/datasizeof.h> -#include <__type_traits/is_always_bitcastable.h> #include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_equality_comparable.h> #include <__type_traits/is_same.h> -#include <__type_traits/is_trivially_copyable.h> #include <__type_traits/is_trivially_lexicographically_comparable.h> #include <__type_traits/remove_cv.h> -#include <__utility/is_pointer_in_range.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -133,30 +129,6 @@ } } -template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* -__constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n) { - size_t __count = static_cast(__n); - if (__libcpp_is_constant_evaluated()) { -#ifdef _LIBCPP_COMPILER_CLANG_BASED - if (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value) { - ::__builtin_memmove(__dest, __src, __count * sizeof(_Tp)); - return __dest; - } -#endif - if (std::__is_pointer_in_range(__src, __src + __count, __dest)) { - for (; __count > 0; --__count) - __dest[__count - 1] = __src[__count - 1]; - } else { - for (size_t __i = 0; __i != __count; ++__i) - __dest[__i] = __src[__i]; - } - } else if (__count > 0) { - ::__builtin_memmove(__dest, __src, (__count - 1) * sizeof(_Tp) + __libcpp_datasizeof<_Tp>::value); - } - return __dest; -} - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H diff --git a/libcxx/include/__type_traits/datasizeof.h b/libcxx/include/__type_traits/datasizeof.h deleted file mode 100644 --- a/libcxx/include/__type_traits/datasizeof.h +++ /dev/null @@ -1,55 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___TYPE_TRAITS_DATASIZEOF_H -#define _LIBCPP___TYPE_TRAITS_DATASIZEOF_H - -#include <__config> -#include <__type_traits/is_class.h> -#include <__type_traits/is_final.h> -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -// This trait provides the size of a type excluding any tail padding. -// -// It is useful in contexts where performing an operation using the full size of the class (including padding) may -// have unintended side effects, such as overwriting a derived class' member when writing the tail padding of a class -// through a pointer-to-base. - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -struct __libcpp_datasizeof { -#if __has_cpp_attribute(__no_unique_address__) - template - struct _FirstPaddingByte { - [[__no_unique_address__]] _Tp __v_; - char __first_padding_byte_; - }; -#else - template ::value || !is_class<_Tp>::value> - struct _FirstPaddingByte : _Tp { - char __first_padding_byte_; - }; - - template <> - struct _FirstPaddingByte { - _Tp __v_; - char __first_padding_byte_; - }; -#endif - - static const size_t value = offsetof(_FirstPaddingByte<>, __first_padding_byte_); -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___TYPE_TRAITS_DATASIZEOF_H diff --git a/libcxx/include/__utility/is_pointer_in_range.h b/libcxx/include/__utility/is_pointer_in_range.h --- a/libcxx/include/__utility/is_pointer_in_range.h +++ b/libcxx/include/__utility/is_pointer_in_range.h @@ -15,6 +15,8 @@ #include <__type_traits/enable_if.h> #include <__type_traits/integral_constant.h> #include <__type_traits/is_constant_evaluated.h> +#include <__type_traits/is_function.h> +#include <__type_traits/is_member_pointer.h> #include <__type_traits/void_t.h> #include <__utility/declval.h> @@ -24,16 +26,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct __is_less_than_comparable : false_type {}; - template -struct __is_less_than_comparable<_Tp, _Up, __void_t() < std::declval<_Up>())> > : true_type { -}; - -template ::value, int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range( const _Tp* __begin, const _Tp* __end, const _Up* __ptr) { + static_assert(!is_function<_Tp>::value && !is_function<_Up>::value, + "__is_pointer_in_range should not be called with function pointers"); + static_assert(!is_member_pointer<_Tp>::value && !is_member_pointer<_Up>::value, + "__is_pointer_in_range should not be called with member pointers"); + if (__libcpp_is_constant_evaluated()) { _LIBCPP_ASSERT_UNCATEGORIZED(__builtin_constant_p(__begin <= __end), "__begin and __end do not form a range"); @@ -47,16 +47,6 @@ return !__less<>()(__ptr, __begin) && __less<>()(__ptr, __end); } -template ::value, int> = 0> -_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range( - const _Tp* __begin, const _Tp* __end, const _Up* __ptr) { - if (__libcpp_is_constant_evaluated()) - return false; - - return reinterpret_cast(__begin) <= reinterpret_cast(__ptr) && - reinterpret_cast(__ptr) < reinterpret_cast(__end); -} - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -700,6 +700,13 @@ struct __uninitialized_size_tag {}; struct __init_with_sentinel_tag {}; +template +struct __is_less_than_comparable : false_type {}; + +template +struct __is_less_than_comparable<_Tp, _Up, __void_t() < std::declval<_Up>())> > : true_type { +}; + template class basic_string { @@ -2029,11 +2036,25 @@ return *this; } - template + template < + class _Tp, + __enable_if_t<__is_less_than_comparable*, const value_type*>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const { return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v)); } + template < + class _Tp, + __enable_if_t*, const value_type*>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const { + if (__libcpp_is_constant_evaluated()) + return false; + + auto __t_ptr = reinterpret_cast(std::addressof(__v)); + return reinterpret_cast(data()) <= __t_ptr && + __t_ptr < reinterpret_cast(data() + size() + 1); + } + _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void __throw_length_error() const { std::__throw_length_error("basic_string"); diff --git a/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp b/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp --- a/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp +++ b/libcxx/test/libcxx/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp @@ -156,6 +156,26 @@ } })); } + + // Empty input sequence. + { + const std::size_t N = 0; + + From input[1] = {make(1)}; + To output[1] = {make(2)}; + + auto in = InIter(input); + auto in_end = InIter(input + N); + auto sent = SentWrapper(in_end); + auto out = OutIter(output); + + assert(!memmove_called); + func(in, sent, out, N); + + assert(memmove_called); + memmove_called = false; + assert(output[0] == make(2)); + } } template class SentWrapper, class OutIter> diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -42,7 +42,6 @@ array compare array concepts array cstddef -array cstdint array cstdlib array initializer_list array iterator @@ -507,7 +506,6 @@ map compare map concepts map cstddef -map cstdint map cstdlib map functional map initializer_list @@ -733,7 +731,6 @@ set compare set concepts set cstddef -set cstdint set cstdlib set functional set initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -42,7 +42,6 @@ array compare array concepts array cstddef -array cstdint array cstdlib array initializer_list array iterator @@ -507,7 +506,6 @@ map compare map concepts map cstddef -map cstdint map cstdlib map functional map initializer_list @@ -734,7 +732,6 @@ set compare set concepts set cstddef -set cstdint set cstdlib set functional set initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -42,7 +42,6 @@ array compare array concepts array cstddef -array cstdint array cstdlib array initializer_list array iterator @@ -509,7 +508,6 @@ map compare map concepts map cstddef -map cstdint map cstdlib map functional map initializer_list @@ -736,7 +734,6 @@ set compare set concepts set cstddef -set cstdint set cstdlib set functional set initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -42,7 +42,6 @@ array compare array concepts array cstddef -array cstdint array cstdlib array initializer_list array iterator @@ -509,7 +508,6 @@ map compare map concepts map cstddef -map cstdint map cstdlib map functional map initializer_list @@ -736,7 +734,6 @@ set compare set concepts set cstddef -set cstdint set cstdlib set functional set initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -41,7 +41,6 @@ array compare array concepts array cstddef -array cstdint array cstdlib array initializer_list array iterator @@ -515,7 +514,6 @@ map compare map concepts map cstddef -map cstdint map cstdlib map functional map initializer_list @@ -742,7 +740,6 @@ set compare set concepts set cstddef -set cstdint set cstdlib set functional set initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -21,7 +21,6 @@ any version array compare array cstddef -array cstdint array initializer_list array limits array stdexcept @@ -366,7 +365,6 @@ locale version map compare map cstddef -map cstdint map initializer_list map limits map new @@ -523,7 +521,6 @@ semaphore version set compare set cstddef -set cstdint set initializer_list set limits set new diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -21,7 +21,6 @@ any version array compare array cstddef -array cstdint array initializer_list array limits array stdexcept @@ -366,7 +365,6 @@ locale version map compare map cstddef -map cstdint map initializer_list map limits map new @@ -523,7 +521,6 @@ semaphore version set compare set cstddef -set cstdint set initializer_list set limits set new diff --git a/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp b/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp deleted file mode 100644 --- a/libcxx/test/libcxx/type_traits/datasizeof.compile.pass.cpp +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// ADDITIONAL_COMPILE_FLAGS: -Wno-private-header - -#include <__type_traits/datasizeof.h> -#include - -static_assert(std::__libcpp_datasizeof::value == 1, ""); -static_assert(std::__libcpp_datasizeof::value == 2, ""); -static_assert(std::__libcpp_datasizeof::value == 4, ""); -static_assert(std::__libcpp_datasizeof::value == 8, ""); - -struct OneBytePadding { - OneBytePadding() {} - - std::int16_t a; - std::int8_t b; -}; - -#if defined(_WIN32) && !defined(__MINGW32__) -static_assert(std::__libcpp_datasizeof::value == 4, ""); -#else -static_assert(std::__libcpp_datasizeof::value == 3, ""); -#endif - -struct InBetweenPadding { - InBetweenPadding() {} - - std::int32_t a; - std::int8_t b; - std::int16_t c; -}; - -static_assert(std::__libcpp_datasizeof::value == 8, ""); diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy.pass.cpp @@ -18,65 +18,64 @@ #include "test_macros.h" #include "test_iterators.h" -class PaddedBase { -public: - TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {} - - std::int16_t a_; - std::int8_t b_; -}; - -class Derived : public PaddedBase { -public: - TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {} - - std::int8_t c_; -}; - -template -struct Test { - template - TEST_CONSTEXPR_CXX20 void operator()() { - const unsigned N = 1000; - int ia[N] = {}; - for (unsigned i = 0; i < N; ++i) - ia[i] = i; - int ib[N] = {0}; - - OutIter r = std::copy(InIter(ia), InIter(ia + N), OutIter(ib)); - assert(base(r) == ib + N); - for (unsigned i = 0; i < N; ++i) - assert(ia[i] == ib[i]); - } -}; - -struct TestInIters { - template - TEST_CONSTEXPR_CXX20 void operator()() { - types::for_each( - types::concatenate_t, types::type_list > >(), - Test()); - } -}; +template +TEST_CONSTEXPR_CXX20 void test_copy() { + const unsigned N = 1000; + int ia[N] = {}; + for (unsigned i = 0; i < N; ++i) + ia[i] = i; + int ib[N] = {0}; + + OutIter r = std::copy(InIter(ia), InIter(ia + N), OutIter(ib)); + assert(base(r) == ib + N); + for (unsigned i = 0; i < N; ++i) + assert(ia[i] == ib[i]); +} TEST_CONSTEXPR_CXX20 bool test() { - types::for_each(types::cpp17_input_iterator_list(), TestInIters()); - - { // Make sure that padding bits aren't copied - Derived src(1, 2, 3); - Derived dst(4, 5, 6); - std::copy(static_cast(&src), static_cast(&src) + 1, static_cast(&dst)); - assert(dst.a_ == 1); - assert(dst.b_ == 2); - assert(dst.c_ == 6); - } - - { // Make sure that overlapping ranges can be copied - int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::copy(a + 3, a + 10, a); - int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10}; - assert(std::equal(a, a + 10, expected)); - } + test_copy, cpp17_output_iterator >(); + test_copy, forward_iterator >(); + test_copy, bidirectional_iterator >(); + test_copy, random_access_iterator >(); + test_copy, int*>(); + + test_copy, cpp17_output_iterator >(); + test_copy, forward_iterator >(); + test_copy, bidirectional_iterator >(); + test_copy, random_access_iterator >(); + test_copy, int*>(); + + test_copy, cpp17_output_iterator >(); + test_copy, forward_iterator >(); + test_copy, bidirectional_iterator >(); + test_copy, random_access_iterator >(); + test_copy, int*>(); + + test_copy, cpp17_output_iterator >(); + test_copy, forward_iterator >(); + test_copy, bidirectional_iterator >(); + test_copy, random_access_iterator >(); + test_copy, int*>(); + + test_copy >(); + test_copy >(); + test_copy >(); + test_copy >(); + test_copy(); + +#if TEST_STD_VER > 17 + test_copy, contiguous_iterator>(); + test_copy, contiguous_iterator>(); + test_copy, contiguous_iterator>(); + test_copy, contiguous_iterator>(); + test_copy>(); + + test_copy, cpp17_output_iterator>(); + test_copy, forward_iterator>(); + test_copy, bidirectional_iterator>(); + test_copy, random_access_iterator>(); + test_copy, int*>(); +#endif return true; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp @@ -20,26 +20,10 @@ #include "test_iterators.h" #include "user_defined_integral.h" -class PaddedBase { -public: - TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {} - - std::int16_t a_; - std::int8_t b_; -}; - -class Derived : public PaddedBase { -public: - TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {} - - std::int8_t c_; -}; - template TEST_CONSTEXPR_CXX20 void test_copy_backward() { - { const unsigned N = 1000; int ia[N] = {}; for (unsigned i = 0; i < N; ++i) @@ -50,7 +34,6 @@ assert(base(r) == ib); for (unsigned i = 0; i < N; ++i) assert(ia[i] == ib[i]); - } } TEST_CONSTEXPR_CXX20 bool @@ -79,23 +62,6 @@ test_copy_backward>(); #endif - { // Make sure that padding bits aren't copied - Derived src(1, 2, 3); - Derived dst(4, 5, 6); - std::copy_backward( - static_cast(&src), static_cast(&src) + 1, static_cast(&dst) + 1); - assert(dst.a_ == 1); - assert(dst.b_ == 2); - assert(dst.c_ == 6); - } - - { // Make sure that overlapping ranges can be copied - int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::copy_backward(a, a + 7, a + 10); - int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7}; - assert(std::equal(a, a + 10, expected)); - } - return true; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/copy_n.pass.cpp @@ -21,26 +21,10 @@ typedef UserDefinedIntegral UDI; -class PaddedBase { -public: - TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {} - - std::int16_t a_; - std::int8_t b_; -}; - -class Derived : public PaddedBase { -public: - TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {} - - std::int8_t c_; -}; - template TEST_CONSTEXPR_CXX20 void test_copy_n() { - { const unsigned N = 1000; int ia[N] = {}; for (unsigned i = 0; i < N; ++i) @@ -51,23 +35,6 @@ assert(base(r) == ib+N/2); for (unsigned i = 0; i < N/2; ++i) assert(ia[i] == ib[i]); - } - - { // Make sure that padding bits aren't copied - Derived src(1, 2, 3); - Derived dst(4, 5, 6); - std::copy_n(static_cast(&src), 1, static_cast(&dst)); - assert(dst.a_ == 1); - assert(dst.b_ == 2); - assert(dst.c_ == 6); - } - - { // Make sure that overlapping ranges can be copied - int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::copy_n(a + 3, 7, a); - int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10}; - assert(std::equal(a, a + 10, expected)); - } } TEST_CONSTEXPR_CXX20 bool diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp @@ -6,9 +6,6 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 && !stdlib=libc++ -// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000 - // // template @@ -23,25 +20,10 @@ #include "test_macros.h" #include "test_iterators.h" -class PaddedBase { -public: - TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {} - - std::int16_t a_; - std::int8_t b_; -}; - -class Derived : public PaddedBase { -public: - TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {} - - std::int8_t c_; -}; - -template -struct Test { - template - TEST_CONSTEXPR_CXX20 void operator()() { +template +TEST_CONSTEXPR_CXX17 bool +test() +{ const unsigned N = 1000; int ia[N] = {}; for (unsigned i = 0; i < N; ++i) @@ -52,22 +34,15 @@ assert(base(r) == ib+N); for (unsigned i = 0; i < N; ++i) assert(ia[i] == ib[i]); - } -}; - -struct TestOutIters { - template - TEST_CONSTEXPR_CXX20 void operator()() { - types::for_each( - types::concatenate_t, types::type_list > >(), - Test()); - } -}; - -template -struct Test1 { - template - TEST_CONSTEXPR_CXX23 void operator()() { + + return true; +} + +#if TEST_STD_VER >= 11 +template +void +test1() +{ const unsigned N = 100; std::unique_ptr ia[N]; for (unsigned i = 0; i < N; ++i) @@ -78,48 +53,140 @@ assert(base(r) == ib+N); for (unsigned i = 0; i < N; ++i) assert(*ib[i] == static_cast(i)); - } -}; - -struct Test1OutIters { - template - TEST_CONSTEXPR_CXX23 void operator()() { - types::for_each(types::concatenate_t*>, - types::type_list*> > >(), - Test1()); - } -}; - -TEST_CONSTEXPR_CXX20 bool test() { - types::for_each(types::cpp17_input_iterator_list(), TestOutIters()); - if (TEST_STD_VER >= 23 || !TEST_IS_CONSTANT_EVALUATED) - types::for_each(types::cpp17_input_iterator_list*>(), Test1OutIters()); - - { // Make sure that padding bits aren't copied - Derived src(1, 2, 3); - Derived dst(4, 5, 6); - std::move(static_cast(&src), static_cast(&src) + 1, static_cast(&dst)); - assert(dst.a_ == 1); - assert(dst.b_ == 2); - assert(dst.c_ == 6); - } - - { // Make sure that overlapping ranges can be copied - int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::move(a + 3, a + 10, a); - int expected[] = {4, 5, 6, 7, 8, 9, 10, 8, 9, 10}; - assert(std::equal(a, a + 10, expected)); - } - - return true; } +#endif int main(int, char**) { - test(); -#if TEST_STD_VER >= 20 - static_assert(test()); -#endif + test, cpp17_output_iterator >(); + test, forward_iterator >(); + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test, cpp17_output_iterator >(); + test, forward_iterator >(); + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test, cpp17_output_iterator >(); + test, forward_iterator >(); + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test, cpp17_output_iterator >(); + test, forward_iterator >(); + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test >(); + test >(); + test >(); + test >(); + test(); + +#if TEST_STD_VER >= 11 + test1*>, cpp17_output_iterator*> >(); + test1*>, forward_iterator*> >(); + test1*>, bidirectional_iterator*> >(); + test1*>, random_access_iterator*> >(); + test1*>, std::unique_ptr*>(); + + test1*>, cpp17_output_iterator*> >(); + test1*>, forward_iterator*> >(); + test1*>, bidirectional_iterator*> >(); + test1*>, random_access_iterator*> >(); + test1*>, std::unique_ptr*>(); + + test1*>, cpp17_output_iterator*> >(); + test1*>, forward_iterator*> >(); + test1*>, bidirectional_iterator*> >(); + test1*>, random_access_iterator*> >(); + test1*>, std::unique_ptr*>(); + + test1*>, cpp17_output_iterator*> >(); + test1*>, forward_iterator*> >(); + test1*>, bidirectional_iterator*> >(); + test1*>, random_access_iterator*> >(); + test1*>, std::unique_ptr*>(); + + test1*, cpp17_output_iterator*> >(); + test1*, forward_iterator*> >(); + test1*, bidirectional_iterator*> >(); + test1*, random_access_iterator*> >(); + test1*, std::unique_ptr*>(); +#endif // TEST_STD_VER >= 11 + +#if TEST_STD_VER > 17 + test, contiguous_iterator>(); + test, contiguous_iterator>(); + test, contiguous_iterator>(); + test, contiguous_iterator>(); + test>(); + test, cpp17_output_iterator>(); + test, forward_iterator>(); + test, bidirectional_iterator>(); + test, random_access_iterator>(); + test, int*>(); + test, contiguous_iterator>(); + + test1*>, contiguous_iterator*>>(); + test1*>, contiguous_iterator*>>(); + test1*>, contiguous_iterator*>>(); + test1*>, contiguous_iterator*>>(); + test1*, contiguous_iterator*>>(); + test1*>, cpp17_output_iterator*>>(); + test1*>, forward_iterator*>>(); + test1*>, bidirectional_iterator*>>(); + test1*>, random_access_iterator*>>(); + test1*>, std::unique_ptr*>(); + test1*>, contiguous_iterator*>>(); + + static_assert(test, cpp17_input_iterator >()); + static_assert(test, forward_iterator >()); + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test, cpp17_input_iterator >()); + static_assert(test, forward_iterator >()); + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test, cpp17_input_iterator >()); + static_assert(test, forward_iterator >()); + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test, cpp17_input_iterator >()); + static_assert(test, forward_iterator >()); + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test, cpp17_input_iterator >()); + static_assert(test, forward_iterator >()); + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test >()); + static_assert(test >()); + static_assert(test >()); + static_assert(test >()); + static_assert(test >()); + static_assert(test()); +#endif // TEST_STD_VER > 17 return 0; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 && !stdlib=libc++ - // // template @@ -22,103 +20,103 @@ #include "test_macros.h" #include "test_iterators.h" -class PaddedBase { -public: - TEST_CONSTEXPR PaddedBase(std::int16_t a, std::int8_t b) : a_(a), b_(b) {} - - std::int16_t a_; - std::int8_t b_; -}; - -class Derived : public PaddedBase { -public: - TEST_CONSTEXPR Derived(std::int16_t a, std::int8_t b, std::int8_t c) : PaddedBase(a, b), c_(c) {} - - std::int8_t c_; -}; - -template -struct Test { - template - TEST_CONSTEXPR_CXX20 void operator()() { - const unsigned N = 1000; - int ia[N] = {}; - for (unsigned i = 0; i < N; ++i) - ia[i] = i; - int ib[N] = {0}; - - OutIter r = std::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N)); - assert(base(r) == ib); - for (unsigned i = 0; i < N; ++i) - assert(ia[i] == ib[i]); - } -}; - -struct TestOutIters { - template - TEST_CONSTEXPR_CXX20 void operator()() { - types::for_each( - types::concatenate_t >(), - Test()); - } -}; - -template -struct Test1 { - template - TEST_CONSTEXPR_CXX23 void operator()() { - const unsigned N = 100; - std::unique_ptr ia[N]; - for (unsigned i = 0; i < N; ++i) - ia[i].reset(new int(i)); - std::unique_ptr ib[N]; - - OutIter r = std::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N)); - assert(base(r) == ib); - for (unsigned i = 0; i < N; ++i) - assert(*ib[i] == static_cast(i)); - } -}; - -struct Test1OutIters { - template - TEST_CONSTEXPR_CXX23 void operator()() { - types::for_each(types::concatenate_t*> >(), - Test1()); - } -}; - -TEST_CONSTEXPR_CXX20 bool test() { - types::for_each(types::bidirectional_iterator_list(), TestOutIters()); - if (TEST_STD_VER >= 23 || !TEST_IS_CONSTANT_EVALUATED) - types::for_each(types::bidirectional_iterator_list*>(), Test1OutIters()); - - { // Make sure that padding bits aren't copied - Derived src(1, 2, 3); - Derived dst(4, 5, 6); - std::move_backward( - static_cast(&src), static_cast(&src) + 1, static_cast(&dst) + 1); - assert(dst.a_ == 1); - assert(dst.b_ == 2); - assert(dst.c_ == 6); - } - - { // Make sure that overlapping ranges can be copied - int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::move_backward(a, a + 7, a + 10); - int expected[] = {1, 2, 3, 1, 2, 3, 4, 5, 6, 7}; - assert(std::equal(a, a + 10, expected)); - } +template +TEST_CONSTEXPR_CXX17 bool test() { + const unsigned N = 1000; + int ia[N] = {}; + for (unsigned i = 0; i < N; ++i) + ia[i] = i; + int ib[N] = {0}; + + OutIter r = std::move_backward(InIter(ia), InIter(ia + N), OutIter(ib + N)); + assert(base(r) == ib); + for (unsigned i = 0; i < N; ++i) + assert(ia[i] == ib[i]); return true; } +#if TEST_STD_VER >= 11 +template +void test1() { + const unsigned N = 100; + std::unique_ptr ia[N]; + for (unsigned i = 0; i < N; ++i) + ia[i].reset(new int(i)); + std::unique_ptr ib[N]; + + OutIter r = std::move_backward(InIter(ia), InIter(ia + N), OutIter(ib + N)); + assert(base(r) == ib); + for (unsigned i = 0; i < N; ++i) + assert(*ib[i] == static_cast(i)); +} +#endif + int main(int, char**) { - test(); -#if TEST_STD_VER >= 20 - static_assert(test()); -#endif + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test, bidirectional_iterator >(); + test, random_access_iterator >(); + test, int*>(); + + test >(); + test >(); + test(); + +#if TEST_STD_VER >= 11 + test1*>, bidirectional_iterator*> >(); + test1*>, random_access_iterator*> >(); + test1*>, std::unique_ptr*>(); + + test1*>, bidirectional_iterator*> >(); + test1*>, random_access_iterator*> >(); + test1*>, std::unique_ptr*>(); + + test1*, bidirectional_iterator*> >(); + test1*, random_access_iterator*> >(); + test1*, std::unique_ptr*>(); +#endif // TEST_STD_VER >= 11 + +#if TEST_STD_VER > 17 + test, contiguous_iterator>(); + test, contiguous_iterator>(); + test>(); + test, bidirectional_iterator>(); + test, random_access_iterator>(); + test, int*>(); + test, contiguous_iterator>(); + + test1*>, contiguous_iterator*>>(); + test1*>, contiguous_iterator*>>(); + test1*, contiguous_iterator*>>(); + test1*>, bidirectional_iterator*>>(); + test1*>, random_access_iterator*>>(); + test1*>, std::unique_ptr*>(); + test1*>, contiguous_iterator*>>(); + + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test, bidirectional_iterator >()); + static_assert(test, random_access_iterator >()); + static_assert(test, contiguous_iterator >()); + static_assert(test, int*>()); + + static_assert(test >()); + static_assert(test >()); + static_assert(test >()); + static_assert(test()); +#endif // TEST_STD_VER > 17 return 0; }