From a17148b9f31db778fea1a4e061f9263052b49678 Mon Sep 17 00:00:00 2001 From: cristei <51248378+cristeigabriel@users.noreply.github.com> Date: Sun, 12 Dec 2021 18:44:32 +0200 Subject: [PATCH 1/7] Implement LWG-3591: `lazy_split_view::inner-iterator::base() &&` invalidates outer iterators Fixes #2401 --- stl/inc/ranges | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index c823cd719ca..50cdf2dd8a8 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1947,7 +1947,7 @@ namespace ranges { return _Current; } _NODISCARD constexpr iterator_t<_Base> base() && noexcept( - is_nothrow_move_constructible_v>) /* strengthened */ { + is_nothrow_move_constructible_v>) requires forward_range<_Vw> { return _STD move(_Current); } @@ -4404,7 +4404,7 @@ namespace ranges { } _NODISCARD constexpr iterator_t<_Base> base() && noexcept( - is_nothrow_move_constructible_v>) /* strengthened */ { + is_nothrow_move_constructible_v>) requires forward_range<_Vw> { return _STD move(_Current); } From 1866266b6bf58a879e78c6328b7c4768debe0b07 Mon Sep 17 00:00:00 2001 From: cristei <51248378+cristeigabriel@users.noreply.github.com> Date: Mon, 13 Dec 2021 21:37:48 +0200 Subject: [PATCH 2/7] Fix LWG-3591 implementation, do LWG-3592 suggested changes. --- stl/inc/ranges | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index 50cdf2dd8a8..82e9fd1e855 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1947,7 +1947,7 @@ namespace ranges { return _Current; } _NODISCARD constexpr iterator_t<_Base> base() && noexcept( - is_nothrow_move_constructible_v>) requires forward_range<_Vw> { + is_nothrow_move_constructible_v>) /* strengthened */ { return _STD move(_Current); } @@ -3675,7 +3675,8 @@ namespace ranges { } _NODISCARD constexpr iterator_t<_BaseTy> base() && noexcept( - is_nothrow_move_constructible_v>) /* strengthened */ { + is_nothrow_move_constructible_v>) /* strengthened */ + requires forward_range<_Vw> { return _STD move(_It._Get_current()); } @@ -3756,7 +3757,7 @@ namespace ranges { _NODISCARD constexpr auto begin() { if constexpr (forward_range<_Vw>) { - return _Outer_iter<_Simple_view<_Vw>>{*this, _RANGES begin(_Range)}; + return _Outer_iter < _Simple_view<_Vw> && _Simple_view<_Pat> > {*this, _RANGES begin(_Range)}; } else { this->_Current = _RANGES begin(_Range); return _Outer_iter{*this}; @@ -3772,7 +3773,7 @@ namespace ranges { // clang-format off _NODISCARD constexpr auto end() requires forward_range<_Vw> && common_range<_Vw> { // clang-format on - return _Outer_iter<_Simple_view<_Vw>>{*this, _RANGES end(_Range)}; + return _Outer_iter < _Simple_view<_Vw> && _Simple_view<_Pat> > {*this, _RANGES end(_Range)}; } _NODISCARD constexpr auto end() const { @@ -4404,7 +4405,7 @@ namespace ranges { } _NODISCARD constexpr iterator_t<_Base> base() && noexcept( - is_nothrow_move_constructible_v>) requires forward_range<_Vw> { + is_nothrow_move_constructible_v>) /* strengthened */ { return _STD move(_Current); } From fcfd3c4dd053ae7bde7fa3c33eac8e45a9186e4c Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 15 Dec 2021 21:28:36 -0800 Subject: [PATCH 3/7] Trick clang-format --- stl/inc/ranges | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index 82e9fd1e855..1473de8d6cd 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -3757,7 +3757,8 @@ namespace ranges { _NODISCARD constexpr auto begin() { if constexpr (forward_range<_Vw>) { - return _Outer_iter < _Simple_view<_Vw> && _Simple_view<_Pat> > {*this, _RANGES begin(_Range)}; + constexpr bool _Both_simple = _Simple_view<_Vw> && _Simple_view<_Pat>; + return _Outer_iter<_Both_simple>{*this, _RANGES begin(_Range)}; } else { this->_Current = _RANGES begin(_Range); return _Outer_iter{*this}; @@ -3773,7 +3774,8 @@ namespace ranges { // clang-format off _NODISCARD constexpr auto end() requires forward_range<_Vw> && common_range<_Vw> { // clang-format on - return _Outer_iter < _Simple_view<_Vw> && _Simple_view<_Pat> > {*this, _RANGES end(_Range)}; + constexpr bool _Both_simple = _Simple_view<_Vw> && _Simple_view<_Pat>; + return _Outer_iter<_Both_simple>{*this, _RANGES end(_Range)}; } _NODISCARD constexpr auto end() const { From 3ed3e7c272474ca1ea6b863d0127c6b2738ac86f Mon Sep 17 00:00:00 2001 From: cristei <51248378+cristeigabriel@users.noreply.github.com> Date: Sun, 19 Dec 2021 03:58:46 +0200 Subject: [PATCH 4/7] Implement compile-time restraints for reference types in containers and allocator Fixes #2408. This PR implements a message (or more, depending on structure) when you try to instantiate an object which has inherent contradicting type requirements (ex. "pointer to reference"). I tried not to be pedantic with the implementation, but I might've went wrong with that, thus I'm sorry if I did. Notes: I have noticed different order for implementing static asserts in containers, sometimes it's before required types and right after, if there is, friend classes, and sometimes, it's after required types and in different access modifiers (not like it changes anything, just a nitpick). --- stl/inc/array | 6 ++++++ stl/inc/deque | 2 ++ stl/inc/forward_list | 2 ++ stl/inc/list | 2 ++ stl/inc/map | 4 ++++ stl/inc/queue | 4 ++++ stl/inc/set | 4 ++++ stl/inc/stack | 2 ++ stl/inc/unordered_map | 2 ++ stl/inc/unordered_set | 4 ++++ stl/inc/vector | 2 ++ stl/inc/xmemory | 2 ++ 12 files changed, 36 insertions(+) diff --git a/stl/inc/array b/stl/inc/array index 9c8b39023ed..fe894250afe 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -434,6 +434,9 @@ struct pointer_traits<_Array_iterator<_Ty, _Size>> { template class array { // fixed size array of values public: + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); + using value_type = _Ty; using size_type = size_t; using difference_type = ptrdiff_t; @@ -620,6 +623,9 @@ struct _Empty_array_element {}; template class array<_Ty, 0> { public: + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); + using value_type = _Ty; using size_type = size_t; using difference_type = ptrdiff_t; diff --git a/stl/inc/deque b/stl/inc/deque index b57c45eb523..e42df7bfc0a 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -583,6 +583,8 @@ private: friend _Tidy_guard; static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("deque", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Alty = _Rebind_alloc_t<_Alloc, _Ty>; using _Alty_traits = allocator_traits<_Alty>; diff --git a/stl/inc/forward_list b/stl/inc/forward_list index b2b0087c35d..e03dcff2354 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -518,6 +518,8 @@ private: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("forward_list", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Scary_val = _Flist_val, _Flist_simple_types<_Ty>, _Flist_iter_types<_Ty, typename _Alty_traits::size_type, typename _Alty_traits::difference_type, diff --git a/stl/inc/list b/stl/inc/list index 607f9c41e7a..e8bd1814613 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -774,6 +774,8 @@ private: public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("list", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using value_type = _Ty; using allocator_type = _Alloc; diff --git a/stl/inc/map b/stl/inc/map index 66fdd9fc81d..8826f0c3444 100644 --- a/stl/inc/map +++ b/stl/inc/map @@ -75,6 +75,8 @@ class map : public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("map", "pair")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Mybase = _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false>>; using _Nodeptr = typename _Mybase::_Nodeptr; @@ -423,6 +425,8 @@ class multimap : public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, true>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("multimap", "pair")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Mybase = _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, true>>; using key_type = _Kty; diff --git a/stl/inc/queue b/stl/inc/queue index d798d5ed4f6..0f983f174a4 100644 --- a/stl/inc/queue +++ b/stl/inc/queue @@ -30,6 +30,8 @@ public: using container_type = _Container; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); queue() = default; @@ -201,6 +203,8 @@ public: using value_compare = _Pr; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); priority_queue() = default; diff --git a/stl/inc/set b/stl/inc/set index ffb4c5cf5b9..23fca952d91 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -54,6 +54,8 @@ class set : public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("set", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false>>; using key_type = _Kty; @@ -233,6 +235,8 @@ class multiset : public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("multiset", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>>; using key_type = _Kty; diff --git a/stl/inc/stack b/stl/inc/stack index 63643921611..9de0275dcc3 100644 --- a/stl/inc/stack +++ b/stl/inc/stack @@ -28,6 +28,8 @@ public: using container_type = _Container; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); stack() = default; diff --git a/stl/inc/unordered_map b/stl/inc/unordered_map index d5c868d4805..a0540811331 100644 --- a/stl/inc/unordered_map +++ b/stl/inc/unordered_map @@ -69,6 +69,8 @@ class unordered_map : public _Hash<_Umap_traits<_Kty, _Ty, _Uhash_compare<_Kty, public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_map", "pair")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; diff --git a/stl/inc/unordered_set b/stl/inc/unordered_set index 1d8e6716df5..28b075fdb19 100644 --- a/stl/inc/unordered_set +++ b/stl/inc/unordered_set @@ -65,6 +65,8 @@ class unordered_set : public _Hash<_Uset_traits<_Kty, _Uhash_compare<_Kty, _Hash public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_set", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; @@ -334,6 +336,8 @@ class unordered_multiset : public _Hash<_Uset_traits<_Kty, _Uhash_compare<_Kty, public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_multiset", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; diff --git a/stl/inc/vector b/stl/inc/vector index 4f7ef44b271..96c118e8471 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -489,6 +489,8 @@ private: public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("vector", "T")); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using value_type = _Ty; using allocator_type = _Alloc; diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 35008b7a9f2..a7fe2cecb04 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -782,6 +782,8 @@ class allocator { public: static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " "because allocator is ill-formed."); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _From_primary = allocator; From 27ca55d9812dba6b91ac0f2744691d850bbea8db Mon Sep 17 00:00:00 2001 From: cristei <51248378+cristeigabriel@users.noreply.github.com> Date: Sun, 19 Dec 2021 04:06:28 +0200 Subject: [PATCH 5/7] Quickfix --- stl/inc/set | 6 +++--- stl/inc/unordered_set | 8 ++++---- stl/inc/xmemory | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/stl/inc/set b/stl/inc/set index 23fca952d91..3e8e9dbf0ff 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -54,8 +54,8 @@ class set : public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("set", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false>>; using key_type = _Kty; @@ -235,7 +235,7 @@ class multiset : public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("multiset", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " + static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>>; diff --git a/stl/inc/unordered_set b/stl/inc/unordered_set index 28b075fdb19..90abce2cd71 100644 --- a/stl/inc/unordered_set +++ b/stl/inc/unordered_set @@ -65,8 +65,8 @@ class unordered_set : public _Hash<_Uset_traits<_Kty, _Uhash_compare<_Kty, _Hash public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_set", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; @@ -336,8 +336,8 @@ class unordered_multiset : public _Hash<_Uset_traits<_Kty, _Uhash_compare<_Kty, public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_multiset", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; diff --git a/stl/inc/xmemory b/stl/inc/xmemory index a7fe2cecb04..50692fb4766 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -782,8 +782,8 @@ class allocator { public: static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " "because allocator is ill-formed."); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids allocators for reference elements " + "because of [allocator.requirements]."); using _From_primary = allocator; From 7ff40f1f2d24138f2c838bd6ab44fcb68649cd26 Mon Sep 17 00:00:00 2001 From: cristei <51248378+cristeigabriel@users.noreply.github.com> Date: Sun, 19 Dec 2021 04:46:33 +0200 Subject: [PATCH 6/7] Update set --- stl/inc/set | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/set b/stl/inc/set index 3e8e9dbf0ff..6d17fb1ec9b 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -236,7 +236,7 @@ public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("multiset", "T")); static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>>; using key_type = _Kty; From aadbc63c5345b60c9bf9fcfbf536c2547c0aa2e0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 9 Apr 2023 21:42:17 -0700 Subject: [PATCH 7/7] Changes during code review. * Changed `unordered_multimap` which was originally overlooked * Varied the wording for container adaptors * For `map`, `multimap`, `unordered_map`, and `unordered_multimap`, checked both the keys and values * Added `!is_function_v<_Ty>` to `allocator` * Changed the checks outside `allocator` to `is_object_v<_Ty>` with matching messages --- stl/inc/array | 8 ++++---- stl/inc/deque | 4 ++-- stl/inc/forward_list | 4 ++-- stl/inc/list | 4 ++-- stl/inc/map | 12 ++++++++---- stl/inc/queue | 8 ++++---- stl/inc/set | 8 ++++---- stl/inc/stack | 4 ++-- stl/inc/unordered_map | 10 ++++++++-- stl/inc/unordered_set | 8 ++++---- stl/inc/vector | 4 ++-- stl/inc/xmemory | 2 ++ 12 files changed, 44 insertions(+), 32 deletions(-) diff --git a/stl/inc/array b/stl/inc/array index 83c0f1dd929..f9321688f5e 100644 --- a/stl/inc/array +++ b/stl/inc/array @@ -406,8 +406,8 @@ struct pointer_traits<_Array_iterator<_Ty, _Size>> { _EXPORT_STD template class array { // fixed size array of values public: - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using value_type = _Ty; using size_type = size_t; @@ -595,8 +595,8 @@ struct _Empty_array_element {}; template class array<_Ty, 0> { public: - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using value_type = _Ty; using size_type = size_t; diff --git a/stl/inc/deque b/stl/inc/deque index 52acccac230..1bbf465b2b9 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -575,8 +575,8 @@ private: friend _Tidy_guard; static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("deque", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using _Alty = _Rebind_alloc_t<_Alloc, _Ty>; using _Alty_traits = allocator_traits<_Alty>; diff --git a/stl/inc/forward_list b/stl/inc/forward_list index 60336ff1ea2..66aada2d043 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -519,8 +519,8 @@ private: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("forward_list", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using _Scary_val = _Flist_val, _Flist_simple_types<_Ty>, _Flist_iter_types<_Ty, typename _Alty_traits::size_type, typename _Alty_traits::difference_type, diff --git a/stl/inc/list b/stl/inc/list index 8bac99f33fb..0df30ff122d 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -776,8 +776,8 @@ private: public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("list", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using value_type = _Ty; using allocator_type = _Alloc; diff --git a/stl/inc/map b/stl/inc/map index 5bdeca7cea6..eaca60e2932 100644 --- a/stl/inc/map +++ b/stl/inc/map @@ -75,8 +75,10 @@ class map : public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("map", "pair")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using _Mybase = _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false>>; using _Nodeptr = typename _Mybase::_Nodeptr; @@ -459,8 +461,10 @@ class multimap : public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, true>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("multimap", "pair")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using _Mybase = _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, true>>; using key_type = _Kty; diff --git a/stl/inc/queue b/stl/inc/queue index 7fe23ff2e3e..68d7ec4ab1f 100644 --- a/stl/inc/queue +++ b/stl/inc/queue @@ -34,8 +34,8 @@ public: using container_type = _Container; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids container adaptors of non-object types " + "because of [container.requirements]."); queue() = default; @@ -236,8 +236,8 @@ public: using value_compare = _Pr; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids container adaptors of non-object types " + "because of [container.requirements]."); priority_queue() = default; diff --git a/stl/inc/set b/stl/inc/set index f875db9067a..f0fb28b05f6 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -54,8 +54,8 @@ class set : public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("set", "T")); - static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false>>; using key_type = _Kty; @@ -267,8 +267,8 @@ class multiset : public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>> { public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("multiset", "T")); - static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using _Mybase = _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true>>; using key_type = _Kty; diff --git a/stl/inc/stack b/stl/inc/stack index 2f26bdd5beb..d23c4305a56 100644 --- a/stl/inc/stack +++ b/stl/inc/stack @@ -32,8 +32,8 @@ public: using container_type = _Container; static_assert(is_same_v<_Ty, value_type>, "container adaptors require consistent types"); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids container adaptors of non-object types " + "because of [container.requirements]."); stack() = default; diff --git a/stl/inc/unordered_map b/stl/inc/unordered_map index 5f0fbbcd3b7..40561f6eb79 100644 --- a/stl/inc/unordered_map +++ b/stl/inc/unordered_map @@ -69,8 +69,10 @@ class unordered_map : public _Hash<_Umap_traits<_Kty, _Ty, _Uhash_compare<_Kty, public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_map", "pair")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; @@ -559,6 +561,10 @@ public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE( "unordered_multimap", "pair")); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; diff --git a/stl/inc/unordered_set b/stl/inc/unordered_set index 92b0237ba1c..0401a5a4628 100644 --- a/stl/inc/unordered_set +++ b/stl/inc/unordered_set @@ -66,8 +66,8 @@ class unordered_set : public _Hash<_Uset_traits<_Kty, _Uhash_compare<_Kty, _Hash public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_set", "T")); - static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; @@ -413,8 +413,8 @@ class unordered_multiset : public _Hash<_Uset_traits<_Kty, _Uhash_compare<_Kty, public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Kty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("unordered_multiset", "T")); - static_assert(!is_reference_v<_Kty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Kty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); private: using _Mytraits = _Uhash_compare<_Kty, _Hasher, _Keyeq>; diff --git a/stl/inc/vector b/stl/inc/vector index 95bf8d76d27..1d8ec8a59d6 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -447,8 +447,8 @@ private: public: static_assert(!_ENFORCE_MATCHING_ALLOCATORS || is_same_v<_Ty, typename _Alloc::value_type>, _MISMATCHED_ALLOCATOR_MESSAGE("vector", "T")); - static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids containers of reference elements " - "because of [container.requirements]."); + static_assert(is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); using value_type = _Ty; using allocator_type = _Alloc; diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 62f825ef8de..7a0597f0941 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -907,6 +907,8 @@ class allocator { public: static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " "because allocator is ill-formed."); + static_assert(!is_function_v<_Ty>, "The C++ Standard forbids allocators for function elements " + "because of [allocator.requirements]."); static_assert(!is_reference_v<_Ty>, "The C++ Standard forbids allocators for reference elements " "because of [allocator.requirements].");