1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <functional>
6
7 #include <lib/fit/function.h>
8 #include <lib/fit/function_traits.h>
9 #include <unittest/unittest.h>
10
11 namespace {
12
13 template <typename Callable, typename... Args>
invoke_with_defaults(Callable c,fit::parameter_pack<Args...>)14 void invoke_with_defaults(Callable c, fit::parameter_pack<Args...>) {
15 c(Args()...);
16 }
17
18 template <typename Callable>
invoke_with_defaults(Callable c)19 void invoke_with_defaults(Callable c) {
20 invoke_with_defaults(std::move(c), typename fit::function_traits<Callable>::args{});
21 }
22
arg_capture()23 bool arg_capture() {
24 BEGIN_TEST;
25
26 int i = 0;
27 invoke_with_defaults([&] { i = 42; });
28 EXPECT_EQ(42, i);
29 invoke_with_defaults([&](int, float) { i = 54; });
30 EXPECT_EQ(54, i);
31
32 END_TEST;
33 }
34
35 // Performs static assertions against a function-like type of signature int(float, bool).
36 template <typename Callable>
37 struct TraitsTest {
38 using Traits = fit::function_traits<Callable>;
39
40 static_assert(std::is_same_v<int(float, bool), typename Traits::signature>);
41 static_assert(std::is_same_v<int, typename Traits::return_type>);
42 static_assert(2 == Traits::args::size);
43 static_assert(std::is_same_v<float, typename Traits::args::template at<0>>);
44 static_assert(std::is_same_v<bool, typename Traits::args::template at<1>>);
45 };
46
47 // compile-time test
48 namespace signature_traits {
49 using Traits = TraitsTest<int(float, bool)>::Traits;
50 } // namespace signature_traits
51
52 // compile-time test
53 namespace function_pointer_traits {
54 using Traits = TraitsTest<int (*)(float, bool)>::Traits;
55 static_assert(std::is_same_v<int (*)(float, bool), Traits::type>);
56 } // namespace function_pointer_traits
57
58 // compile-time test
59 namespace lambda_traits {
__anon751b94140402(float, bool) 60 auto lambda = [](float, bool) { return 0; };
61 using Traits = TraitsTest<decltype(lambda)>::Traits;
62 } // namespace lambda_traits
63
64 template <typename Functor>
65 struct FunctorTraitsTest {
66 using Traits = typename TraitsTest<Functor>::Traits;
67 static_assert(std::is_same_v<Functor, typename Traits::type>);
68 };
69
70 // compile-time test
71 namespace mutable_functor_traits {
72 struct MutableFunctor {
operator ()__anon751b94140111::mutable_functor_traits::MutableFunctor73 int operator()(float, bool) { return 0; }
74 };
75 using Traits = FunctorTraitsTest<MutableFunctor>::Traits;
76 } //namespace mutable_functor_traits
77
78 // compile-time test
79 namespace fit_function_traits {
80 using Traits = FunctorTraitsTest<fit::function<int(float, bool)>>;
81 } // namespace fit_function_traits
82
83 // compile-time test
84 namespace std_function_traits {
85 using Traits = FunctorTraitsTest<std::function<int(float, bool)>>;
86 } // namespace std_function_traits
87
88 } // namespace
89
90 BEGIN_TEST_CASE(function_traits_tests)
91 RUN_TEST(arg_capture)
92 // suppress -Wunneeded-internal-declaration
93 (void)lambda_traits::lambda;
94 END_TEST_CASE(function_traits_tests)
95