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> 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> 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> 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> 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 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