Home | History | Annotate | Download | only in func.wrap.func
      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