@@ -35,39 +35,19 @@ void conversion_test(T);
35
35
template <class T , class ... Args>
36
36
concept ImplicitlyConstructible = requires (Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
37
37
38
- void test () {
39
- {
40
- // The constructors in this subclause shall not participate in overload
41
- // resolution unless uses_allocator_v<container_type, Alloc> is true
42
-
43
- using C = test_less<int >;
44
- using A1 = test_allocator<int >;
45
- using A2 = other_allocator<int >;
46
- using V1 = std::vector<int , A1>;
47
- using V2 = std::vector<int , A2>;
48
- using M1 = std::flat_multiset<int , C, V1>;
49
- using M2 = std::flat_multiset<int , C, V2>;
50
- static_assert (std::is_constructible_v<M1, const V1&, const A1&>);
51
- static_assert (std::is_constructible_v<M2, const V2&, const A2&>);
52
- static_assert (!std::is_constructible_v<M1, const V1&, const A2&>);
53
- static_assert (!std::is_constructible_v<M2, const V2&, const A1&>);
54
-
55
- static_assert (std::is_constructible_v<M1, const V1&, const C&, const A1&>);
56
- static_assert (std::is_constructible_v<M2, const V2&, const C&, const A2&>);
57
- static_assert (!std::is_constructible_v<M1, const V1&, const C&, const A2&>);
58
- static_assert (!std::is_constructible_v<M2, const V2&, const C&, const A1&>);
59
- }
38
+ template <template <class ...> class KeyContainer >
39
+ constexpr void test () {
60
40
{
61
41
// flat_multiset(container_type)
62
- using M = std::flat_multiset<int >;
63
- std::vector <int > ks = {1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 };
64
- auto m = M (ks);
65
- int expected[] = {1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 };
42
+ using M = std::flat_multiset<int , std::less< int >, KeyContainer< int > >;
43
+ KeyContainer <int > ks = {1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 };
44
+ auto m = M (ks);
45
+ int expected[] = {1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 };
66
46
assert (std::ranges::equal (m, expected));
67
47
68
48
// explicit(false)
69
- static_assert (std::is_constructible_v<M, const std::vector <int >&>);
70
- static_assert (!ImplicitlyConstructible<M, const std::vector <int >&>);
49
+ static_assert (std::is_constructible_v<M, const KeyContainer <int >&>);
50
+ static_assert (!ImplicitlyConstructible<M, const KeyContainer <int >&>);
71
51
72
52
m = M (std::move (ks));
73
53
assert (ks.empty ()); // it was moved-from
@@ -77,7 +57,7 @@ void test() {
77
57
// flat_multiset(container_type)
78
58
// move-only
79
59
int expected[] = {3 , 3 , 2 , 1 };
80
- using Ks = std::deque <MoveOnly, min_allocator<MoveOnly>>;
60
+ using Ks = KeyContainer <MoveOnly, min_allocator<MoveOnly>>;
81
61
using M = std::flat_multiset<MoveOnly, std::greater<MoveOnly>, Ks>;
82
62
Ks ks;
83
63
ks.push_back (1 );
@@ -92,8 +72,8 @@ void test() {
92
72
// flat_multiset(container_type)
93
73
// container's allocators are used
94
74
using A = test_allocator<int >;
95
- using M = std::flat_multiset<int , std::less<int >, std::deque <int , A>>;
96
- auto ks = std::deque <int , A>({1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 }, A (5 ));
75
+ using M = std::flat_multiset<int , std::less<int >, KeyContainer <int , A>>;
76
+ auto ks = KeyContainer <int , A>({1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 }, A (5 ));
97
77
auto m = M (std::move (ks));
98
78
assert (ks.empty ()); // it was moved-from
99
79
assert ((m == M{1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 }));
@@ -102,30 +82,30 @@ void test() {
102
82
}
103
83
{
104
84
// flat_multiset(container_type, key_compare)
105
- using C = test_less<int >;
106
- using M = std::flat_multiset<int , C>;
107
- std::vector <int > ks = {1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 };
108
- auto m = M (ks, C (4 ));
85
+ using C = test_less<int >;
86
+ using M = std::flat_multiset<int , C, KeyContainer< int > >;
87
+ KeyContainer <int > ks = {1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 };
88
+ auto m = M (ks, C (4 ));
109
89
assert (std::ranges::equal (m, std::vector<int >{1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 }));
110
90
assert (m.key_comp () == C (4 ));
111
91
112
92
// explicit
113
- static_assert (std::is_constructible_v<M, const std::vector <int >&, const C&>);
114
- static_assert (!ImplicitlyConstructible<M, const std::vector <int >&, const C&>);
93
+ static_assert (std::is_constructible_v<M, const KeyContainer <int >&, const C&>);
94
+ static_assert (!ImplicitlyConstructible<M, const KeyContainer <int >&, const C&>);
115
95
}
116
96
{
117
97
// flat_multiset(container_type , const Allocator&)
118
98
using A = test_allocator<int >;
119
- using M = std::flat_multiset<int , std::less<int >, std::deque <int , A>>;
120
- auto ks = std::deque <int , A>({1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 }, A (5 ));
99
+ using M = std::flat_multiset<int , std::less<int >, KeyContainer <int , A>>;
100
+ auto ks = KeyContainer <int , A>({1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 }, A (5 ));
121
101
auto m = M (ks, A (4 )); // replaces the allocators
122
102
assert (!ks.empty ()); // it was an lvalue above
123
103
assert ((m == M{1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 }));
124
104
auto keys = M (m).extract ();
125
105
assert (keys.get_allocator () == A (4 ));
126
106
127
107
// explicit(false)
128
- static_assert (ImplicitlyConstructible<M, const std::deque <int , A>&, const A&>);
108
+ static_assert (ImplicitlyConstructible<M, const KeyContainer <int , A>&, const A&>);
129
109
M m2 = {ks, A (4 )}; // implicit ctor
130
110
assert (!ks.empty ()); // it was an lvalue above
131
111
assert (m2 == m);
@@ -134,19 +114,19 @@ void test() {
134
114
}
135
115
{
136
116
// flat_multiset(container_type , const Allocator&)
137
- using C = test_less<int >;
138
- using A = test_allocator<int >;
139
- using M = std::flat_multiset<int , C, std::vector <int , A>>;
140
- std::vector <int , A> ks = {1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 };
141
- auto m = M (ks, C (4 ), A (5 ));
142
- assert (std::ranges::equal (m, std::vector <int , A>{1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 }));
117
+ using C = test_less<int >;
118
+ using A = test_allocator<int >;
119
+ using M = std::flat_multiset<int , C, KeyContainer <int , A>>;
120
+ KeyContainer <int , A> ks = {1 , 1 , 1 , 2 , 2 , 3 , 2 , 3 , 3 };
121
+ auto m = M (ks, C (4 ), A (5 ));
122
+ assert (std::ranges::equal (m, KeyContainer <int , A>{1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 }));
143
123
assert (m.key_comp () == C (4 ));
144
124
auto m_copy = m;
145
125
auto keys = std::move (m_copy).extract ();
146
126
assert (keys.get_allocator () == A (5 ));
147
127
148
128
// explicit(false)
149
- static_assert (ImplicitlyConstructible<M, const std::vector <int , A>&, const A&>);
129
+ static_assert (ImplicitlyConstructible<M, const KeyContainer <int , A>&, const A&>);
150
130
M m2 = {ks, C (4 ), A (5 )};
151
131
assert (m2 == m);
152
132
assert (m2.key_comp () == C (4 ));
@@ -155,8 +135,44 @@ void test() {
155
135
}
156
136
}
157
137
138
+ constexpr bool test () {
139
+ {
140
+ // The constructors in this subclause shall not participate in overload
141
+ // resolution unless uses_allocator_v<container_type, Alloc> is true
142
+
143
+ using C = test_less<int >;
144
+ using A1 = test_allocator<int >;
145
+ using A2 = other_allocator<int >;
146
+ using V1 = std::vector<int , A1>;
147
+ using V2 = std::vector<int , A2>;
148
+ using M1 = std::flat_multiset<int , C, V1>;
149
+ using M2 = std::flat_multiset<int , C, V2>;
150
+ static_assert (std::is_constructible_v<M1, const V1&, const A1&>);
151
+ static_assert (std::is_constructible_v<M2, const V2&, const A2&>);
152
+ static_assert (!std::is_constructible_v<M1, const V1&, const A2&>);
153
+ static_assert (!std::is_constructible_v<M2, const V2&, const A1&>);
154
+
155
+ static_assert (std::is_constructible_v<M1, const V1&, const C&, const A1&>);
156
+ static_assert (std::is_constructible_v<M2, const V2&, const C&, const A2&>);
157
+ static_assert (!std::is_constructible_v<M1, const V1&, const C&, const A2&>);
158
+ static_assert (!std::is_constructible_v<M2, const V2&, const C&, const A1&>);
159
+ }
160
+
161
+ test<std::vector>();
162
+
163
+ #ifndef __cpp_lib_constexpr_deque
164
+ if (!TEST_IS_CONSTANT_EVALUATED)
165
+ #endif
166
+ test<std::deque>();
167
+
168
+ return true ;
169
+ }
170
+
158
171
int main (int , char **) {
159
172
test ();
173
+ #if TEST_STD_VER >= 26
174
+ static_assert (test ());
175
+ #endif
160
176
161
177
return 0 ;
162
178
}
0 commit comments