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 11namespace { 12 13template <typename Callable, typename... Args> 14void invoke_with_defaults(Callable c, fit::parameter_pack<Args...>) { 15 c(Args()...); 16} 17 18template <typename Callable> 19void invoke_with_defaults(Callable c) { 20 invoke_with_defaults(std::move(c), typename fit::function_traits<Callable>::args{}); 21} 22 23bool 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). 36template <typename Callable> 37struct 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 48namespace signature_traits { 49 using Traits = TraitsTest<int(float, bool)>::Traits; 50} // namespace signature_traits 51 52// compile-time test 53namespace 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 59namespace lambda_traits { 60 auto lambda = [](float, bool) { return 0; }; 61 using Traits = TraitsTest<decltype(lambda)>::Traits; 62} // namespace lambda_traits 63 64template <typename Functor> 65struct 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 71namespace mutable_functor_traits { 72 struct MutableFunctor { 73 int operator()(float, bool) { return 0; } 74 }; 75 using Traits = FunctorTraitsTest<MutableFunctor>::Traits; 76} //namespace mutable_functor_traits 77 78// compile-time test 79namespace fit_function_traits { 80 using Traits = FunctorTraitsTest<fit::function<int(float, bool)>>; 81} // namespace fit_function_traits 82 83// compile-time test 84namespace std_function_traits { 85 using Traits = FunctorTraitsTest<std::function<int(float, bool)>>; 86} // namespace std_function_traits 87 88} // namespace 89 90BEGIN_TEST_CASE(function_traits_tests) 91RUN_TEST(arg_capture) 92// suppress -Wunneeded-internal-declaration 93(void)lambda_traits::lambda; 94END_TEST_CASE(function_traits_tests) 95