1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // <functional>
10
11 // template<Returnable R, CopyConstructible... ArgTypes>
12 // class function<R(ArgTypes...)> {
13 // public:
14 // typedef R result_type;
15 // typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and
16 // // the type in ArgTypes is T1
17 // typedef T1 first_argument_type; // iff sizeof...(ArgTypes) == 2 and
18 // // ArgTypes contains T1 and T2
19 // typedef T2 second_argument_type; // iff sizeof...(ArgTypes) == 2 and
20 // // ArgTypes contains T1 and T2
21 // ...
22 // };
23
24 // This test runs in C++03, but we have deprecated using std::function in C++03.
25 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
26
27 #include <functional>
28 #include <type_traits>
29
30 #include "test_macros.h"
31
32
33 template <typename T>
34 class has_argument_type
35 {
36 typedef char yes;
37 typedef long no;
38
39 template <typename C> static yes check( typename C::argument_type * );
40 template <typename C> static no check(...);
41 public:
42 enum { value = sizeof(check<T>(0)) == sizeof(yes) };
43 };
44
45 template <typename T>
46 class has_first_argument_type
47 {
48 typedef char yes;
49 typedef long no;
50
51 template <typename C> static yes check( typename C::first_argument_type * );
52 template <typename C> static no check(...);
53 public:
54 enum { value = sizeof(check<T>(0)) == sizeof(yes) };
55 };
56
57
58 template <typename T>
59 class has_second_argument_type
60 {
61 typedef char yes;
62 typedef long no;
63
64 template <typename C> static yes check( typename C::second_argument_type *);
65 template <typename C> static no check(...);
66 public:
67 enum { value = sizeof(check<T>(0)) == sizeof(yes) };
68 };
69
70 template <class F, class return_type>
test_nullary_function()71 void test_nullary_function ()
72 {
73 #if TEST_STD_VER <= 17
74 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
75 #endif
76 static_assert((!has_argument_type<F>::value), "" );
77 static_assert((!has_first_argument_type<F>::value), "" );
78 static_assert((!has_second_argument_type<F>::value), "" );
79 }
80
81 template <class F, class return_type, class arg_type>
test_unary_function()82 void test_unary_function ()
83 {
84 #if TEST_STD_VER <= 17
85 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
86 static_assert((std::is_same<typename F::argument_type, arg_type>::value), "" );
87 #endif
88 static_assert((!has_first_argument_type<F>::value), "" );
89 static_assert((!has_second_argument_type<F>::value), "" );
90 }
91
92 template <class F, class return_type, class arg_type1, class arg_type2>
test_binary_function()93 void test_binary_function ()
94 {
95 #if TEST_STD_VER <= 17
96 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
97 static_assert((std::is_same<typename F::first_argument_type, arg_type1>::value), "" );
98 static_assert((std::is_same<typename F::second_argument_type, arg_type2>::value), "" );
99 #endif
100 static_assert((!has_argument_type<F>::value), "" );
101 }
102
103 template <class F, class return_type>
test_other_function()104 void test_other_function ()
105 {
106 #if TEST_STD_VER <= 17
107 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
108 #endif
109 static_assert((!has_argument_type<F>::value), "" );
110 static_assert((!has_first_argument_type<F>::value), "" );
111 static_assert((!has_second_argument_type<F>::value), "" );
112 }
113
main(int,char **)114 int main(int, char**)
115 {
116 test_nullary_function<std::function<int()>, int>();
117 test_unary_function <std::function<double(int)>, double, int>();
118 test_binary_function <std::function<double(int, char)>, double, int, char>();
119 test_other_function <std::function<double(int, char, double)>, double>();
120
121 return 0;
122 }
123