12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
+ #include " subspace/fn/fn.h"
16
+
15
17
#include < concepts>
16
18
17
19
#include " googletest/include/gtest/gtest.h"
18
20
#include " subspace/construct/into.h"
19
- #include " subspace/fn/fn.h"
20
21
#include " subspace/mem/forward.h"
21
22
#include " subspace/mem/move.h"
22
23
#include " subspace/mem/replace.h"
@@ -116,9 +117,9 @@ static_assert(sus::mem::relocate_by_memcpy<Fn<void()>>);
116
117
static_assert (std::is_constructible_v<FnOnce<void ()>, decltype ([]() {})>);
117
118
static_assert (std::is_constructible_v<FnMut<void ()>, decltype ([]() {})>);
118
119
static_assert (std::is_constructible_v<Fn<void ()>, decltype ([]() {})>);
119
- static_assert (std::is_constructible_v<FnOnce<void ()>, decltype (& v_v_function)>);
120
- static_assert (std::is_constructible_v<FnMut<void ()>, decltype (& v_v_function)>);
121
- static_assert (std::is_constructible_v<Fn<void ()>, decltype (& v_v_function)>);
120
+ static_assert (std::is_constructible_v<FnOnce<void ()>, decltype (v_v_function)>);
121
+ static_assert (std::is_constructible_v<FnMut<void ()>, decltype (v_v_function)>);
122
+ static_assert (std::is_constructible_v<Fn<void ()>, decltype (v_v_function)>);
122
123
// Non-void types for the same.
123
124
static_assert (std::is_constructible_v<FnOnce<int (float )>,
124
125
decltype ([](float ) { return 1 ; })>);
@@ -127,10 +128,10 @@ static_assert(std::is_constructible_v<FnMut<int(float)>,
127
128
static_assert (
128
129
std::is_constructible_v<Fn<int (float )>, decltype ([](float ) { return 1 ; })>);
129
130
static_assert (
130
- std::is_constructible_v<FnOnce<int (float )>, decltype (& i_f_function)>);
131
+ std::is_constructible_v<FnOnce<int (float )>, decltype (i_f_function)>);
131
132
static_assert (
132
- std::is_constructible_v<FnMut<int (float )>, decltype (& i_f_function)>);
133
- static_assert (std::is_constructible_v<Fn<int (float )>, decltype (& i_f_function)>);
133
+ std::is_constructible_v<FnMut<int (float )>, decltype (i_f_function)>);
134
+ static_assert (std::is_constructible_v<Fn<int (float )>, decltype (i_f_function)>);
134
135
// Lambdas with bound args can be bound to FnOnce, FnMut and Fn.
135
136
static_assert (std::is_constructible_v<FnOnce<void ()>,
136
137
decltype ([i = int (1 )]() { (void )i; })>);
@@ -148,11 +149,11 @@ static_assert(std::is_constructible_v<
148
149
// The return type of the FnOnce must match that of the lambda. It will not
149
150
// allow converting to void.
150
151
static_assert (std::is_constructible_v<FnOnce<SubClass*(BaseClass*)>,
151
- decltype (& s_b_function)>);
152
- static_assert (!std::is_constructible_v<FnOnce< void (BaseClass*)>,
153
- decltype (& b_b_function)>);
152
+ decltype (s_b_function)>);
153
+ static_assert (
154
+ !std::is_constructible_v<FnOnce< void (BaseClass*)>, decltype (b_b_function)>);
154
155
static_assert (!std::is_constructible_v<FnOnce<SubClass*(BaseClass*)>,
155
- decltype (& b_b_function)>);
156
+ decltype (b_b_function)>);
156
157
static_assert (std::is_constructible_v<FnOnce<SubClass*(BaseClass*)>,
157
158
decltype (s_b_lambda)>);
158
159
static_assert (
@@ -161,9 +162,9 @@ static_assert(!std::is_constructible_v<FnOnce<SubClass*(BaseClass*)>,
161
162
decltype (b_b_lambda)>);
162
163
// Similarly, argument types can't be converted to a different type.
163
164
static_assert (std::is_constructible_v<FnOnce<SubClass*(SubClass*)>,
164
- decltype (& s_s_function)>);
165
+ decltype (s_s_function)>);
165
166
static_assert (!std::is_constructible_v<FnOnce<SubClass*(BaseClass*)>,
166
- decltype (& s_s_function)>);
167
+ decltype (s_s_function)>);
167
168
static_assert (std::is_constructible_v<FnOnce<SubClass*(SubClass*)>,
168
169
decltype (s_s_lambda)>);
169
170
static_assert (!std::is_constructible_v<FnOnce<SubClass*(BaseClass*)>,
@@ -234,6 +235,34 @@ static_assert(!can_run<void, int&, int&&>);
234
235
static_assert (!can_run<void , int &, const int &&>);
235
236
236
237
TEST (Fn, Pointer) {
238
+ {
239
+ auto receive_fn = [](FnOnce<i32 (i32 , i32 )> f, i32 a, i32 b) {
240
+ return sus::move (f)(a, b);
241
+ };
242
+ auto * ptr = +[](i32 a, i32 b) { return a * 2 + b; };
243
+ EXPECT_EQ (receive_fn (ptr, 1 , 2 ), 4 );
244
+ }
245
+ {
246
+ auto receive_fn = [](FnMut<i32 (i32 , i32 )> f, i32 a, i32 b) {
247
+ f (a, b);
248
+ return sus::move (f)(a, b);
249
+ };
250
+ auto * ptr = +[](i32 a, i32 b) { return a * 2 + b; };
251
+ EXPECT_EQ (receive_fn (ptr, 1 , 2 ), 4 );
252
+ }
253
+ {
254
+ {
255
+ auto receive_fn = [](Fn<i32 (i32 , i32 )> f, i32 a, i32 b) {
256
+ f (a, b);
257
+ return sus::move (f)(a, b);
258
+ };
259
+ auto * ptr = +[](i32 a, i32 b) { return a * 2 + b; };
260
+ EXPECT_EQ (receive_fn (ptr, 1 , 2 ), 4 );
261
+ }
262
+ }
263
+ }
264
+
265
+ TEST (Fn, CapturelessLambda) {
237
266
{
238
267
auto receive_fn = [](FnOnce<i32 (i32 , i32 )> f, i32 a, i32 b) {
239
268
return sus::move (f)(a, b);
@@ -291,7 +320,32 @@ TEST(Fn, Lambda) {
291
320
}
292
321
}
293
322
294
- void g () {}
323
+ TEST (Fn, TemplateLambda) {
324
+ {
325
+ auto receive_fn = [](FnOnce<i32 (i32 )> f, i32 b) { return sus::move (f)(b); };
326
+ auto lambda = [a = 1_i32](auto b) { return a * 2 + b; };
327
+ EXPECT_EQ (receive_fn (lambda, 2 ), 4 );
328
+ }
329
+ {
330
+ auto receive_fn = [](FnMut<i32 (i32 )> f, i32 b) {
331
+ f (b);
332
+ return sus::move (f)(b);
333
+ };
334
+ auto lambda = [a = 1_i32](auto b) mutable {
335
+ a += 1 ;
336
+ return a * 2 + b;
337
+ };
338
+ EXPECT_EQ (receive_fn (lambda, 2 ), 8 );
339
+ }
340
+ {
341
+ auto receive_fn = [](Fn<i32 (i32 )> f, i32 b) {
342
+ f (b);
343
+ return sus::move (f)(b);
344
+ };
345
+ auto lambda = [a = 1_i32](auto b) { return a * 2 + b; };
346
+ EXPECT_EQ (receive_fn (lambda, 2 ), 4 );
347
+ }
348
+ }
295
349
296
350
TEST (FnDeathTest, NullPointer) {
297
351
void (*f)() = nullptr ;
0 commit comments