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 29template <typename T> 30class 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(...); 37public: 38 enum { value = sizeof(check<T>(0)) == sizeof(yes) }; 39}; 40 41template <typename T> 42class 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(...); 49public: 50 enum { value = sizeof(check<T>(0)) == sizeof(yes) }; 51}; 52 53 54template <typename T> 55class 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(...); 62public: 63 enum { value = sizeof(check<T>(0)) == sizeof(yes) }; 64}; 65 66template <class F, class return_type> 67void 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 75template <class F, class return_type, class arg_type> 76void 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 84template <class F, class return_type, class arg_type1, class arg_type2> 85void 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 93template <class F, class return_type> 94void 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 102int 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