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 // UNSUPPORTED: c++98, c++03 11 12 // <functional> 13 14 // template<CopyConstructible Fn, CopyConstructible... Types> 15 // unspecified bind(Fn, Types...); 16 // template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> 17 // unspecified bind(Fn, Types...); 18 19 // Check that the call operators have the proper return type and that they 20 // only SFINAE away when too few arguments are provided. Otherwise they should 21 // be well formed and should ignore any additional arguments. 22 23 #include <functional> 24 #include <type_traits> 25 #include <cassert> 26 27 #include "test_macros.h" 28 29 int dummy = 42; 30 31 int return_value(int) { return dummy; } 32 int& return_lvalue(int) { return dummy; } 33 const int& return_const_lvalue(int) { return dummy; } 34 int&& return_rvalue(int) { return std::move(dummy); } 35 const int&& return_const_rvalue(int) { return std::move(dummy); } 36 37 template <class Bind, class ...Args> 38 auto CheckCallImp(int) 39 -> decltype((std::declval<Bind>()(std::declval<Args>()...)), std::true_type{}); 40 41 template <class Bind, class ...> 42 auto CheckCallImp(long) -> std::false_type; 43 44 template <class ...Args> 45 constexpr bool CheckCall() { 46 return decltype(CheckCallImp<Args...>(0))::value; 47 } 48 49 template <class Expect, class Fn> 50 void do_test(Fn* func) { 51 using namespace std::placeholders; 52 auto ret = std::bind(func, _1); 53 auto ret_r = std::bind<Expect>(func, _1); 54 using Bind = decltype(ret); 55 using BindR = decltype(ret_r); 56 57 using Ret = decltype(ret(42)); 58 using Ret2 = decltype(ret(42, 43)); // Test that the extra argument is discarded. 59 using RetR = decltype(ret_r(42)); 60 using RetR2 = decltype(ret_r(42, 43)); 61 62 static_assert(std::is_same<Ret, Expect>::value, ""); 63 static_assert(std::is_same<Ret2, Expect>::value, ""); 64 static_assert(std::is_same<RetR, Expect>::value, ""); 65 static_assert(std::is_same<RetR2, Expect>::value, ""); 66 67 Expect exp = ret(100); // the input value is ignored. dummy is returned. 68 Expect exp2 = ret(101, 102); 69 Expect exp_r = ret_r(100); 70 Expect exp_r2 = ret_r(101, 102); 71 72 assert(exp == 42); 73 assert(exp2 == 42); 74 assert(exp_r == 42); 75 assert(exp_r2 == 42); 76 77 if ((std::is_reference<Expect>::value)) { 78 assert(&exp == &dummy); 79 assert(&exp2 == &dummy); 80 assert(&exp_r == &dummy); 81 assert(&exp_r2 == &dummy); 82 } 83 // Check that the call operator SFINAE's away when too few arguments 84 // are provided but is well-formed otherwise. 85 { 86 LIBCPP_STATIC_ASSERT(!CheckCall<Bind>(), ""); 87 static_assert(CheckCall<Bind, int>(), ""); 88 static_assert(CheckCall<Bind, int, int>(), ""); 89 LIBCPP_STATIC_ASSERT(!CheckCall<BindR>(), ""); 90 static_assert(CheckCall<BindR, int>(), ""); 91 static_assert(CheckCall<BindR, int, int>(), ""); 92 } 93 } 94 95 96 // Test but with an explicit return type which differs from the real one. 97 template <class Expect, class Fn> 98 void do_test_r(Fn* func) { 99 using namespace std::placeholders; 100 auto ret = std::bind<Expect>(func, _1); 101 using Bind = decltype(ret); 102 using Ret = decltype(ret(42)); 103 using Ret2 = decltype(ret(42, 43)); // Test that the extra argument is discarded. 104 static_assert(std::is_same<Ret, Expect>::value, ""); 105 static_assert(std::is_same<Ret2, Expect>::value, ""); 106 Expect exp = ret(100); // the input value is ignored 107 Expect exp2 = ret(101, 102); 108 assert(exp == 42); 109 assert(exp2 == 42); 110 // Check that the call operator SFINAE's away when too few arguments 111 // are provided but is well-formed otherwise. 112 { 113 LIBCPP_STATIC_ASSERT(!CheckCall<Bind>(), ""); 114 static_assert(CheckCall<Bind, int>(), ""); 115 static_assert(CheckCall<Bind, int, int>(), ""); 116 } 117 } 118 119 int main() 120 { 121 do_test<int>(return_value); 122 do_test<int&>(return_lvalue); 123 do_test<const int&>(return_const_lvalue); 124 do_test<int&&>(return_rvalue); 125 do_test<const int&&>(return_const_rvalue); 126 127 do_test_r<long>(return_value); 128 do_test_r<long>(return_lvalue); 129 do_test_r<long>(return_const_lvalue); 130 do_test_r<long>(return_rvalue); 131 do_test_r<long>(return_const_rvalue); 132 133 } 134