1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // <functional> 10 11 // reference_wrapper 12 13 // has weak result type 14 15 #include <functional> 16 #include <type_traits> 17 18 template <class Arg, class Result> 19 struct my_unary_function 20 { // std::unary_function was removed in C++17 21 typedef Arg argument_type; 22 typedef Result result_type; 23 }; 24 25 template <class Arg1, class Arg2, class Result> 26 struct my_binary_function 27 { // std::binary_function was removed in C++17 28 typedef Arg1 first_argument_type; 29 typedef Arg2 second_argument_type; 30 typedef Result result_type; 31 }; 32 33 class functor1 34 : public my_unary_function<int, char> 35 { 36 }; 37 38 class functor2 39 : public my_binary_function<char, int, double> 40 { 41 }; 42 43 class functor3 44 : public my_unary_function<char, int>, 45 public my_binary_function<char, int, double> 46 { 47 public: 48 typedef float result_type; 49 }; 50 51 class functor4 52 : public my_unary_function<char, int>, 53 public my_binary_function<char, int, double> 54 { 55 public: 56 }; 57 58 class C {}; 59 60 template <class T> 61 struct has_result_type 62 { 63 private: 64 struct two {char _; char __;}; 65 template <class U> static two test(...); 66 template <class U> static char test(typename U::result_type* = 0); 67 public: 68 static const bool value = sizeof(test<T>(0)) == 1; 69 }; 70 71 int main(int, char**) 72 { 73 static_assert((std::is_same<std::reference_wrapper<functor1>::result_type, 74 char>::value), ""); 75 static_assert((std::is_same<std::reference_wrapper<functor2>::result_type, 76 double>::value), ""); 77 static_assert((std::is_same<std::reference_wrapper<functor3>::result_type, 78 float>::value), ""); 79 static_assert((std::is_same<std::reference_wrapper<void()>::result_type, 80 void>::value), ""); 81 static_assert((std::is_same<std::reference_wrapper<int*(double*)>::result_type, 82 int*>::value), ""); 83 static_assert((std::is_same<std::reference_wrapper<void(*)()>::result_type, 84 void>::value), ""); 85 static_assert((std::is_same<std::reference_wrapper<int*(*)(double*)>::result_type, 86 int*>::value), ""); 87 static_assert((std::is_same<std::reference_wrapper<int*(C::*)(double*)>::result_type, 88 int*>::value), ""); 89 static_assert((std::is_same<std::reference_wrapper<int (C::*)(double*) const volatile>::result_type, 90 int>::value), ""); 91 static_assert((std::is_same<std::reference_wrapper<C()>::result_type, 92 C>::value), ""); 93 static_assert(has_result_type<std::reference_wrapper<functor3> >::value, ""); 94 static_assert(!has_result_type<std::reference_wrapper<functor4> >::value, ""); 95 static_assert(!has_result_type<std::reference_wrapper<C> >::value, ""); 96 97 return 0; 98 } 99