• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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