111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The LLVM Compiler Infrastructure 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is dual licensed under the MIT and the University of Illinois Open 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Source Licenses. See LICENSE.TXT for details. 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===// 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <functional> 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// template<Returnable R, CopyConstructible... ArgTypes> 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// class function<R(ArgTypes...)> { 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// public: 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// typedef R result_type; 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// // the type in ArgTypes is T1 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// typedef T1 first_argument_type; // iff sizeof...(ArgTypes) == 2 and 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// // ArgTypes contains T1 and T2 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// typedef T2 second_argument_type; // iff sizeof...(ArgTypes) == 2 and 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// // ArgTypes contains T1 and T2 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// ... 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// }; 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <functional> 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <type_traits> 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <typename T> 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass has_argument_type 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef char yes; 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef long no; 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <typename C> static yes check( typename C::argument_type * ); 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <typename C> static no check(...); 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum { value = sizeof(check<T>(0)) == sizeof(yes) }; 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <typename T> 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass has_first_argument_type 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef char yes; 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef long no; 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <typename C> static yes check( typename C::first_argument_type * ); 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <typename C> static no check(...); 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum { value = sizeof(check<T>(0)) == sizeof(yes) }; 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <typename T> 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass has_second_argument_type 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef char yes; 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef long no; 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <typename C> static yes check( typename C::second_argument_type *); 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template <typename C> static no check(...); 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic: 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum { value = sizeof(check<T>(0)) == sizeof(yes) }; 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class F, class return_type> 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid test_nullary_function () 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_argument_type<F>::value), "" ); 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_first_argument_type<F>::value), "" ); 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_second_argument_type<F>::value), "" ); 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class F, class return_type, class arg_type> 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid test_unary_function () 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::argument_type, arg_type>::value), "" ); 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_first_argument_type<F>::value), "" ); 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_second_argument_type<F>::value), "" ); 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class F, class return_type, class arg_type1, class arg_type2> 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid test_binary_function () 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::first_argument_type, arg_type1>::value), "" ); 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::second_argument_type, arg_type2>::value), "" ); 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_argument_type<F>::value), "" ); 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class F, class return_type> 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid test_other_function () 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_argument_type<F>::value), "" ); 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_first_argument_type<F>::value), "" ); 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert((!has_second_argument_type<F>::value), "" ); 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertint main() 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test_nullary_function<std::function<int()>, int>(); 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test_unary_function <std::function<double(int)>, double, int>(); 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test_binary_function <std::function<double(int, char)>, double, int, char>(); 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert test_other_function <std::function<double(int, char, double)>, double>(); 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 109