@@ -30,7 +30,7 @@ constexpr int f3(int x, int y, int z) {
30
30
struct Cat {
31
31
string name;
32
32
33
- string noise (const string& s) const {
33
+ constexpr string noise (const string& s) const {
34
34
return name + " says " + s;
35
35
}
36
36
};
@@ -53,6 +53,26 @@ struct DetectQualifiers {
53
53
}
54
54
};
55
55
56
+ _CONSTEXPR23 void test_movable_only_types () {
57
+ auto unique_lambda = [up1 = make_unique<int >(1200 )](unique_ptr<int >&& up2) {
58
+ if (up1 && up2) {
59
+ return make_unique<int >(*up1 + *up2);
60
+ } else if (up1) {
61
+ return make_unique<int >(*up1 * -1 );
62
+ } else if (up2) {
63
+ return make_unique<int >(*up2 * -10 );
64
+ } else {
65
+ return make_unique<int >(-9000 );
66
+ }
67
+ };
68
+ auto bound6 = bind_front (move (unique_lambda), make_unique<int >(34 ));
69
+ assert (*unique_lambda (make_unique<int >(56 )) == -560 );
70
+ assert (*move (bound6)() == 1234 );
71
+ auto bound7 = move (bound6);
72
+ assert (*move (bound6)() == -9000 );
73
+ assert (*move (bound7)() == 1234 );
74
+ }
75
+
56
76
constexpr bool test_constexpr () {
57
77
// Test varying numbers of arguments.
58
78
assert (bind_front (f0)() == 1729 );
@@ -92,13 +112,39 @@ constexpr bool test_constexpr() {
92
112
bound1 (4 );
93
113
assert (value == 234 );
94
114
115
+ // Test PMFs.
116
+ Cat cat{" Peppermint" };
117
+ auto bound2 = bind_front (&Cat::noise, cat); // stores a copy
118
+ assert (bound2 (" meow" ) == " Peppermint says meow" );
119
+ cat.name = " Fluffy" ;
120
+ assert (cat.noise (" hiss" ) == " Fluffy says hiss" );
121
+ assert (bound2 (" purr" ) == " Peppermint says purr" );
122
+
123
+ auto bound3 = bind_front (&Cat::noise, &cat); // stores a pointer
124
+ assert (bound3 (" MEOW" ) == " Fluffy says MEOW" );
125
+ cat.name = " Peppermint" ;
126
+ assert (bound3 (" PURR" ) == " Peppermint says PURR" );
127
+
128
+ auto bound4 = bind_front (&Cat::noise, ref (cat)); // stores a reference_wrapper
129
+ assert (bound4 (" Why do you keep renaming me?" ) == " Peppermint says Why do you keep renaming me?" );
130
+ cat.name = " Cat" ;
131
+ assert (bound4 (" You can't rename me anymore, Human" ) == " Cat says You can't rename me anymore, Human" );
132
+
95
133
// Test "perfect forwarding call wrapper" behavior.
96
134
auto bound5 = bind_front (DetectQualifiers{});
97
135
assert (bound5 () == " modifiable lvalue" );
98
136
assert (as_const (bound5)() == " const lvalue" );
99
137
assert (move (bound5)() == " modifiable rvalue" );
100
138
assert (move (as_const (bound5))() == " const rvalue" );
101
139
140
+ #if _HAS_CXX23
141
+ test_movable_only_types ();
142
+ #else // _HAS_CXX23
143
+ if (!is_constant_evaluated ()) {
144
+ test_movable_only_types ();
145
+ }
146
+ #endif // _HAS_CXX23
147
+
102
148
// Test decay when binding.
103
149
const int arr[] = {11 , 22 , 33 };
104
150
const int three = 3 ;
@@ -128,43 +174,6 @@ int main() {
128
174
assert (test_constexpr ());
129
175
static_assert (test_constexpr ());
130
176
131
- // Test PMFs.
132
- Cat cat{" Peppermint" };
133
- auto bound2 = bind_front (&Cat::noise, cat); // stores a copy
134
- assert (bound2 (" meow" ) == " Peppermint says meow" );
135
- cat.name = " Fluffy" ;
136
- assert (cat.noise (" hiss" ) == " Fluffy says hiss" );
137
- assert (bound2 (" purr" ) == " Peppermint says purr" );
138
-
139
- auto bound3 = bind_front (&Cat::noise, &cat); // stores a pointer
140
- assert (bound3 (" MEOW" ) == " Fluffy says MEOW" );
141
- cat.name = " Peppermint" ;
142
- assert (bound3 (" PURR" ) == " Peppermint says PURR" );
143
-
144
- auto bound4 = bind_front (&Cat::noise, ref (cat)); // stores a reference_wrapper, uses LWG-2219
145
- assert (bound4 (" Why do you keep renaming me?" ) == " Peppermint says Why do you keep renaming me?" );
146
- cat.name = " Cat" ;
147
- assert (bound4 (" You can't rename me anymore, Human" ) == " Cat says You can't rename me anymore, Human" );
148
-
149
- // Test movable-only types.
150
- auto unique_lambda = [up1 = make_unique<int >(1200 )](unique_ptr<int >&& up2) {
151
- if (up1 && up2) {
152
- return make_unique<int >(*up1 + *up2);
153
- } else if (up1) {
154
- return make_unique<int >(*up1 * -1 );
155
- } else if (up2) {
156
- return make_unique<int >(*up2 * -10 );
157
- } else {
158
- return make_unique<int >(-9000 );
159
- }
160
- };
161
- auto bound6 = bind_front (move (unique_lambda), make_unique<int >(34 ));
162
- assert (*unique_lambda (make_unique<int >(56 )) == -560 );
163
- assert (*move (bound6)() == 1234 );
164
- auto bound7 = move (bound6);
165
- assert (*move (bound6)() == -9000 );
166
- assert (*move (bound7)() == 1234 );
167
-
168
177
// Also test GH-1292 "bind_front violates [func.require]p8" in which the return type of bind_front inadvertently
169
178
// depends on the value category and/or cv-qualification of its arguments.
170
179
{
0 commit comments