diff --git a/stl/inc/__msvc_string_view.hpp b/stl/inc/__msvc_string_view.hpp index 57fc646177e..14198cbdf6b 100644 --- a/stl/inc/__msvc_string_view.hpp +++ b/stl/inc/__msvc_string_view.hpp @@ -1344,9 +1344,10 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer "Bad char_traits for basic_string_view; N4950 [string.view.template.general]/1 " "\"The program is ill-formed if traits::char_type is not the same type as charT.\""); - static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> && is_standard_layout_v<_Elem>, - "The character type of basic_string_view must be a non-array trivial standard-layout type. See N4950 " - "[strings.general]/1."); + static_assert(!is_array_v<_Elem> && is_trivially_copyable_v<_Elem> && is_trivially_default_constructible_v<_Elem> + && is_standard_layout_v<_Elem>, + "The character type of basic_string_view must be a non-array trivially copyable standard-layout type T where " + "is_trivially_default_constructible_v is true. See N5001 [strings.general]/1."); using traits_type = _Traits; using value_type = _Elem; diff --git a/stl/inc/execution b/stl/inc/execution index 8f9ed7b5501..99801e6d75c 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -500,7 +500,8 @@ struct _Parallel_choose_max_chunk { template struct alignas(_Ty) alignas(size_t) alignas(_Atomic_counter_t) _Circular_buffer { // work stealing deque extent type - static_assert(is_trivial_v<_Ty>, "Work stealing deques work only with trivial operations"); + static_assert(is_trivially_copyable_v<_Ty> && is_trivially_default_constructible_v<_Ty>, + "Work stealing deques work only with trivial operations"); size_t _Log_size; _Atomic_counter_t _Ref_count; diff --git a/stl/inc/filesystem b/stl/inc/filesystem index 8a20d566326..34562e576cb 100644 --- a/stl/inc/filesystem +++ b/stl/inc/filesystem @@ -352,19 +352,12 @@ namespace filesystem { inline constexpr _Is_slash_oper _Is_slash{}; - template - _NODISCARD _Ty _Unaligned_load(const void* _Ptr) { // load a _Ty from _Ptr - static_assert(is_trivial_v<_Ty>, "Unaligned loads require trivial types"); - _Ty _Tmp; - _CSTD memcpy(&_Tmp, _Ptr, sizeof(_Tmp)); - return _Tmp; - } - _NODISCARD inline bool _Is_drive_prefix(const wchar_t* const _First) { // test if _First points to a prefix of the form X: // pre: _First points to at least 2 wchar_t instances // pre: Little endian - auto _Value = _Unaligned_load(_First); + unsigned int _Value; + _CSTD memcpy(&_Value, _First, sizeof(_Value)); // load from possibly unaligned address _Value &= 0xFFFF'FFDFu; // transform lowercase drive letters into uppercase ones _Value -= (static_cast(L':') << (sizeof(wchar_t) * CHAR_BIT)) | L'A'; return _Value < 26; diff --git a/stl/inc/memory b/stl/inc/memory index 864f44f90af..f485dbca947 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -2246,7 +2246,8 @@ struct _NODISCARD _Reverse_destroy_multidimensional_n_guard { template void _Uninitialized_copy_multidimensional(const _Ty (&_In)[_Size], _Ty (&_Out)[_Size]) { - if constexpr (is_trivial_v<_Ty>) { + using _Item = remove_all_extents_t<_Ty>; + if constexpr (conjunction_v, is_trivially_destructible<_Item>>) { _STD _Copy_memmove_n(_In, _Size, _Out); } else if constexpr (is_array_v<_Ty>) { _Reverse_destroy_multidimensional_n_guard<_Ty> _Guard{_Out, 0}; @@ -2610,7 +2611,8 @@ struct _NODISCARD _Reverse_destroy_multidimensional_n_al_guard { template void _Uninitialized_copy_multidimensional_al(const _Ty (&_In)[_Size], _Ty (&_Out)[_Size], _Alloc& _Al) { using _Item = remove_all_extents_t<_Ty>; - if constexpr (conjunction_v, _Uses_default_construct<_Alloc, _Item*, const _Item&>>) { + if constexpr (conjunction_v, is_trivially_destructible<_Item>, + _Uses_default_construct<_Alloc, _Item*, const _Item&>>) { _STD _Copy_memmove_n(_In, _Size, _Out); } else if constexpr (is_array_v<_Ty>) { _Reverse_destroy_multidimensional_n_al_guard<_Ty, _Alloc> _Guard{_Out, 0, _Al}; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 8edd5d4c62b..93d6422336d 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -2299,7 +2299,7 @@ _NODISCARD inline size_t _Fnv1a_append_bytes(size_t _Val, const unsigned char* c template _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First, const _Ty* const _Last) noexcept { // accumulate range [_First, _Last) into partial FNV-1a hash _Val - static_assert(is_trivial_v<_Ty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Ty>, "Only trivially copyable types can be directly hashed."); const auto _Firstb = reinterpret_cast(_First); const auto _Lastb = reinterpret_cast(_Last); return _Fnv1a_append_bytes(_Val, _Firstb, static_cast(_Lastb - _Firstb)); @@ -2308,7 +2308,7 @@ _NODISCARD size_t _Fnv1a_append_range(const size_t _Val, const _Ty* const _First template _NODISCARD size_t _Fnv1a_append_value( const size_t _Val, const _Kty& _Keyval) noexcept { // accumulate _Keyval into partial FNV-1a hash _Val - static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Kty>, "Only trivially copyable types can be directly hashed."); return _Fnv1a_append_bytes(_Val, &reinterpret_cast(_Keyval), sizeof(_Kty)); } @@ -2320,7 +2320,7 @@ _NODISCARD size_t _Hash_representation(const _Kty& _Keyval) noexcept { // bitwis template _NODISCARD size_t _Hash_array_representation( const _Kty* const _First, const size_t _Count) noexcept { // bitwise hashes the representation of an array - static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed."); + static_assert(is_trivially_copyable_v<_Kty>, "Only trivially copyable types can be directly hashed."); return _Fnv1a_append_bytes( _FNV_offset_basis, reinterpret_cast(_First), _Count * sizeof(_Kty)); } diff --git a/stl/inc/xstring b/stl/inc/xstring index e39cb1871a3..55b5a67de10 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -538,9 +538,10 @@ private: "N4950 [string.require]/3 requires that the supplied " "char_traits character type match the string's character type."); - static_assert(!is_array_v<_Elem> && is_trivial_v<_Elem> && is_standard_layout_v<_Elem>, - "The character type of basic_string must be a non-array trivial standard-layout type. See N4950 " - "[strings.general]/1."); + static_assert(!is_array_v<_Elem> && is_trivially_copyable_v<_Elem> && is_trivially_default_constructible_v<_Elem> + && is_standard_layout_v<_Elem>, + "The character type of basic_string must be a non-array trivially copyable standard-layout type T where " + "is_trivially_default_constructible_v is true. See N5001 [strings.general]/1."); public: using traits_type = _Traits; @@ -573,12 +574,13 @@ private: // _String_val::_Bx::_Ptr (type is pointer) // _String_val::_Mysize (type is size_type) // _String_val::_Myres (type is size_type) - // N4950 [strings.general]/1 says _Elem must be trivial standard-layout, so memcpy is safe. + // N5001 [strings.general]/1 says _Elem must be trivially copyable standard-layout, so memcpy is safe. // We need to ask if pointer is safe to memcpy. // size_type must be an unsigned integral type so memcpy is safe. // We also need to disable memcpy if the user has supplied _Traits, since // they can observe traits::assign and similar. - static constexpr bool _Can_memcpy_val = _Is_specialization_v<_Traits, char_traits> && is_trivial_v; + static constexpr bool _Can_memcpy_val = + _Is_specialization_v<_Traits, char_traits> && is_trivially_copyable_v; // This offset skips over the _Container_base members, if any static constexpr size_t _Memcpy_val_offset = _Size_after_ebco_v<_Container_base>; static constexpr size_t _Memcpy_val_size = sizeof(_Scary_val) - _Memcpy_val_offset; diff --git a/tests/std/tests/GH_000431_copy_move_family/test.cpp b/tests/std/tests/GH_000431_copy_move_family/test.cpp index 125792ea6e4..3527ebf0bb7 100644 --- a/tests/std/tests/GH_000431_copy_move_family/test.cpp +++ b/tests/std/tests/GH_000431_copy_move_family/test.cpp @@ -37,7 +37,8 @@ struct TrivialStruct { return i == right.i; } }; -STATIC_ASSERT(is_trivial_v); +STATIC_ASSERT(is_trivially_copyable_v); +STATIC_ASSERT(is_trivially_default_constructible_v); struct TriviallyCopyableStruct { int i; @@ -49,7 +50,7 @@ struct TriviallyCopyableStruct { } }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMovableStruct { int i; @@ -65,7 +66,7 @@ struct TriviallyMovableStruct { } }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); enum int_enum : int {}; enum char_enum : char {}; diff --git a/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp b/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp index cac035a3e90..8041ee4127e 100644 --- a/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp +++ b/tests/std/tests/GH_000431_iter_copy_move_cat/test.compile.pass.cpp @@ -170,14 +170,15 @@ void test_iter_cat_for_containers() { struct TrivialStruct { int i; }; -STATIC_ASSERT(is_trivial_v); +STATIC_ASSERT(is_trivially_copyable_v); +STATIC_ASSERT(is_trivially_default_constructible_v); struct TriviallyCopyableStruct { int i; TriviallyCopyableStruct(); }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMovableStruct { int i; @@ -188,7 +189,7 @@ struct TriviallyMovableStruct { TriviallyMovableStruct& operator=(TriviallyMovableStruct&&) = default; }; STATIC_ASSERT(is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyConstructibleStruct { int i; @@ -204,7 +205,7 @@ STATIC_ASSERT(is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_copy_assignable_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyAssignableStruct { int i; @@ -220,7 +221,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v); STATIC_ASSERT(is_trivially_copy_assignable_v); STATIC_ASSERT(is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyCopyConstructibleStruct { int i; @@ -236,7 +237,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyCopyAssignableStruct { int i; @@ -253,7 +254,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v) STATIC_ASSERT(is_trivially_copy_assignable_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMoveConstructibleStruct { int i; @@ -269,7 +270,7 @@ STATIC_ASSERT(is_trivially_move_constructible_v); STATIC_ASSERT(!is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct TriviallyMoveAssignableStruct { int i; @@ -285,7 +286,7 @@ STATIC_ASSERT(!is_trivially_move_constructible_v) STATIC_ASSERT(!is_trivially_copy_assignable_v); STATIC_ASSERT(is_trivially_move_assignable_v); STATIC_ASSERT(!is_trivially_copyable_v); -STATIC_ASSERT(!is_trivial_v); +STATIC_ASSERT(!is_trivially_default_constructible_v); struct EmptyBase {}; diff --git a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp index c48709d1875..d1bdbdfa72b 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_left/test.cpp @@ -19,9 +19,10 @@ constexpr void check_members(const extents& ext, index_se using Ext = extents; using Mapping = layout_left::mapping; - // layout_left meets the layout mapping policy requirements and is a trivial type + // layout_left meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_left::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); diff --git a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp index ef08dd7e9a9..75c685c3e92 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_right/test.cpp @@ -19,9 +19,10 @@ constexpr void check_members(const extents& ext, index_se using Ext = extents; using Mapping = layout_right::mapping; - // layout_right meets the layout mapping policy requirements and is a trivial type + // layout_right meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_right::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp index 5f34b8c1541..033b68fc761 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp @@ -105,9 +105,10 @@ constexpr void do_check_members(const extents& ext, using Strides = array; using Mapping = layout_stride::mapping; - // layout_stride meets the layout mapping policy requirements and is a trivial type + // layout_stride meets the requirements of N5001 [mdspan.layout.policy.overview]/1 static_assert(check_layout_mapping_policy_requirements()); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); // layout_stride::mapping is a trivially copyable type that models regular for each Ext static_assert(is_trivially_copyable_v); diff --git a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp index c68533ccd0e..8a682080e90 100644 --- a/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_mdspan/test.cpp @@ -337,7 +337,8 @@ struct TrivialAccessor { }; static_assert(check_accessor_policy_requirements>()); -static_assert(is_trivial_v>); +static_assert(is_trivially_copyable_v>); +static_assert(is_trivially_default_constructible_v>); template class AccessorTemplate> constexpr void check_modeled_concepts_and_member_types() { diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index b964b554c8f..ba0e7f4d685 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -173,7 +173,8 @@ namespace test_unexpected { namespace test_unexpect { auto copy = unexpect; static_assert(is_same_v); - static_assert(is_trivial_v); + static_assert(is_trivially_copyable_v); + static_assert(is_trivially_default_constructible_v); static_assert(is_empty_v); } // namespace test_unexpect diff --git a/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp b/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp index acd3a8d11af..0625be2e3e4 100644 --- a/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp +++ b/tests/std/tests/P0513R0_poisoning_the_hash/test.cpp @@ -52,7 +52,7 @@ constexpr bool standard_hash_enabled() { && is_trivially_move_constructible_v> // && is_trivially_copy_assignable_v> // && is_trivially_move_assignable_v> // - && is_trivial_v> // as a consequence of the above + && is_trivially_copyable_v> // && is_same_v::argument_type, T> // && is_same_v::result_type, size_t> // && (noexcept(hash{}(declval())) == NoExcept) // diff --git a/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp b/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp index f44a8d332a8..9582b548a25 100644 --- a/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp +++ b/tests/std/tests/P0896R4_P1614R2_comparisons/test.cpp @@ -52,7 +52,8 @@ constexpr bool is_trivially_constexpr() { // Not required, but likely portable nonetheless: STATIC_ASSERT(std::is_empty_v); - STATIC_ASSERT(std::is_trivial_v); + STATIC_ASSERT(std::is_trivially_copyable_v); + STATIC_ASSERT(std::is_trivially_default_constructible_v); STATIC_ASSERT(std::is_trivially_copy_constructible_v); STATIC_ASSERT(std::is_trivially_move_constructible_v); STATIC_ASSERT(std::is_trivially_copy_assignable_v); diff --git a/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp b/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp index aa272fea61b..c2fe39556fb 100644 --- a/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp +++ b/tests/std/tests/P0896R4_ranges_algorithm_machinery/test.compile.pass.cpp @@ -547,7 +547,8 @@ namespace dangling_test { namespace result_test { using ranges::in_found_result, ranges::in_fun_result, ranges::in_in_result, ranges::in_out_result, ranges::in_in_out_result, ranges::in_out_out_result, ranges::min_max_result; - using std::is_aggregate_v, std::is_convertible_v, std::is_trivial_v; + using std::is_aggregate_v, std::is_convertible_v, std::is_trivially_copyable_v, + std::is_trivially_default_constructible_v; // Validate the result types are: // * aggregates @@ -559,14 +560,23 @@ namespace result_test { static_assert(is_aggregate_v>); static_assert(is_aggregate_v>); - // * trivial when parameter types are trivial - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); - static_assert(is_trivial_v>); + // * trivially copyable when parameter types are trivially copyable + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_copyable_v>); + + // * trivially default constructible when parameter types are trivially default constructible + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); + static_assert(is_trivially_default_constructible_v>); // * usable with structured bindings constexpr bool test_bindings_in_found_result() { diff --git a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp index 40d4d320f4f..fb4b4d6f98e 100644 --- a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp @@ -54,9 +54,10 @@ constexpr bool test_cpo(T const& obj) { // Not required, but likely portable nonetheless: static_assert(std::is_empty_v); - static_assert(std::is_trivial_v); + static_assert(std::is_trivially_copyable_v); static_assert(std::is_nothrow_destructible_v); static_assert(std::is_nothrow_default_constructible_v); + static_assert(std::is_trivially_default_constructible_v); static_assert(std::is_nothrow_copy_constructible_v); static_assert(std::is_trivially_copy_constructible_v); static_assert(std::is_nothrow_move_constructible_v); diff --git a/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp b/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp index ca5ce231773..72244709389 100644 --- a/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp +++ b/tests/std/tests/P2322R6_ranges_alg_fold/test.cpp @@ -252,7 +252,8 @@ struct instantiator { constexpr bool test_in_value_result() { using ranges::in_value_result; static_assert(is_aggregate_v>); - static_assert(is_trivial_v>); + static_assert(is_trivially_copyable_v>); + static_assert(is_trivially_default_constructible_v>); in_value_result res = {nullptr, 6}; { // Validate binding