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