1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // <functional>
11
12 // template<Returnable R, CopyConstructible... ArgTypes>
13 // class function<R(ArgTypes...)> {
14 // public:
15 // typedef R result_type;
16 // typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and
17 // // the type in ArgTypes is T1
18 // typedef T1 first_argument_type; // iff sizeof...(ArgTypes) == 2 and
19 // // ArgTypes contains T1 and T2
20 // typedef T2 second_argument_type; // iff sizeof...(ArgTypes) == 2 and
21 // // ArgTypes contains T1 and T2
22 // ...
23 // };
24
25 #include <functional>
26 #include <type_traits>
27
28
29 template <typename T>
30 class has_argument_type
31 {
32 typedef char yes;
33 typedef long no;
34
35 template <typename C> static yes check( typename C::argument_type * );
36 template <typename C> static no check(...);
37 public:
38 enum { value = sizeof(check<T>(0)) == sizeof(yes) };
39 };
40
41 template <typename T>
42 class has_first_argument_type
43 {
44 typedef char yes;
45 typedef long no;
46
47 template <typename C> static yes check( typename C::first_argument_type * );
48 template <typename C> static no check(...);
49 public:
50 enum { value = sizeof(check<T>(0)) == sizeof(yes) };
51 };
52
53
54 template <typename T>
55 class has_second_argument_type
56 {
57 typedef char yes;
58 typedef long no;
59
60 template <typename C> static yes check( typename C::second_argument_type *);
61 template <typename C> static no check(...);
62 public:
63 enum { value = sizeof(check<T>(0)) == sizeof(yes) };
64 };
65
66 template <class F, class return_type>
test_nullary_function()67 void test_nullary_function ()
68 {
69 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
70 static_assert((!has_argument_type<F>::value), "" );
71 static_assert((!has_first_argument_type<F>::value), "" );
72 static_assert((!has_second_argument_type<F>::value), "" );
73 }
74
75 template <class F, class return_type, class arg_type>
test_unary_function()76 void test_unary_function ()
77 {
78 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
79 static_assert((std::is_same<typename F::argument_type, arg_type>::value), "" );
80 static_assert((!has_first_argument_type<F>::value), "" );
81 static_assert((!has_second_argument_type<F>::value), "" );
82 }
83
84 template <class F, class return_type, class arg_type1, class arg_type2>
test_binary_function()85 void test_binary_function ()
86 {
87 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
88 static_assert((std::is_same<typename F::first_argument_type, arg_type1>::value), "" );
89 static_assert((std::is_same<typename F::second_argument_type, arg_type2>::value), "" );
90 static_assert((!has_argument_type<F>::value), "" );
91 }
92
93 template <class F, class return_type>
test_other_function()94 void test_other_function ()
95 {
96 static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
97 static_assert((!has_argument_type<F>::value), "" );
98 static_assert((!has_first_argument_type<F>::value), "" );
99 static_assert((!has_second_argument_type<F>::value), "" );
100 }
101
main()102 int main()
103 {
104 test_nullary_function<std::function<int()>, int>();
105 test_unary_function <std::function<double(int)>, double, int>();
106 test_binary_function <std::function<double(int, char)>, double, int, char>();
107 test_other_function <std::function<double(int, char, double)>, double>();
108 }
109