1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
13 // template<CopyConstructible Fn, CopyConstructible... Types>
14 // unspecified bind(Fn, Types...); // constexpr since C++20
15 // template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>
16 // unspecified bind(Fn, Types...); // constexpr since C++20
23 #include "test_macros.h"
36 void operator()(int i
)
41 void mem1() {++count
;}
42 void mem2() const {count
+= 2;}
48 using namespace std::placeholders
;
49 int save_count
= count
;
52 std::bind(f_void_1
, _1
)(2);
53 assert(count
== save_count
+ 2);
57 std::bind(f_void_1
, 2)();
58 assert(count
== save_count
+ 2);
63 void (*fp
)(int) = f_void_1
;
65 assert(count
== save_count
+3);
69 void (*fp
)(int) = f_void_1
;
71 assert(count
== save_count
+3);
78 assert(count
== save_count
+4);
84 assert(count
== save_count
+4);
87 // member function pointer
89 void (A_void_1::*fp
)() = &A_void_1::mem1
;
90 std::bind(fp
, _1
)(A_void_1());
91 assert(count
== save_count
+1);
94 std::bind(fp
, _1
)(&a
);
95 assert(count
== save_count
+1);
99 void (A_void_1::*fp
)() = &A_void_1::mem1
;
100 std::bind(fp
, A_void_1())();
101 assert(count
== save_count
+1);
105 assert(count
== save_count
+1);
108 // const member function pointer
110 void (A_void_1::*fp
)() const = &A_void_1::mem2
;
111 std::bind(fp
, _1
)(A_void_1());
112 assert(count
== save_count
+2);
115 std::bind(fp
, _1
)(&a
);
116 assert(count
== save_count
+2);
120 void (A_void_1::*fp
)() const = &A_void_1::mem2
;
121 std::bind(fp
, A_void_1())();
122 assert(count
== save_count
+2);
126 assert(count
== save_count
+2);
133 TEST_CONSTEXPR_CXX20
int f_int_1(int i
) {
138 TEST_CONSTEXPR_CXX20
A_int_1() : data_(5) {}
139 TEST_CONSTEXPR_CXX20
int operator()(int i
) {
143 TEST_CONSTEXPR_CXX20
int mem1() { return 3; }
144 TEST_CONSTEXPR_CXX20
int mem2() const { return 4; }
148 TEST_CONSTEXPR_CXX20
bool test_int_1() {
149 using namespace std::placeholders
;
152 assert(std::bind(f_int_1
, _1
)(2) == 3);
153 assert(std::bind(f_int_1
, 2)() == 3);
157 int (*fp
)(int) = f_int_1
;
158 assert(std::bind(fp
, _1
)(3) == 4);
159 assert(std::bind(fp
, 3)() == 4);
163 assert(std::bind(A_int_1(), _1
)(4) == 3);
164 assert(std::bind(A_int_1(), 4)() == 3);
166 // member function pointer
168 assert(std::bind(&A_int_1::mem1
, _1
)(A_int_1()) == 3);
169 assert(std::bind(&A_int_1::mem1
, A_int_1())() == 3);
171 assert(std::bind(&A_int_1::mem1
, _1
)(&a
) == 3);
172 assert(std::bind(&A_int_1::mem1
, &a
)() == 3);
174 // const member function pointer
176 assert(std::bind(&A_int_1::mem2
, _1
)(A_int_1()) == 4);
177 assert(std::bind(&A_int_1::mem2
, A_int_1())() == 4);
179 assert(std::bind(&A_int_1::mem2
, _1
)(&a
) == 4);
180 assert(std::bind(&A_int_1::mem2
, &a
)() == 4);
182 // member data pointer
184 assert(std::bind(&A_int_1::data_
, _1
)(A_int_1()) == 5);
185 assert(std::bind(&A_int_1::data_
, A_int_1())() == 5);
187 assert(std::bind(&A_int_1::data_
, _1
)(a
) == 5);
188 std::bind(&A_int_1::data_
, _1
)(a
) = 6;
189 assert(std::bind(&A_int_1::data_
, _1
)(a
) == 6);
190 assert(std::bind(&A_int_1::data_
, _1
)(&a
) == 6);
191 std::bind(&A_int_1::data_
, _1
)(&a
) = 7;
192 assert(std::bind(&A_int_1::data_
, _1
)(&a
) == 7);
197 // 2 arg, return void
199 void f_void_2(int i
, int j
)
206 void operator()(int i
, int j
)
211 void mem1(int i
) {count
+= i
;}
212 void mem2(int i
) const {count
+= i
;}
218 using namespace std::placeholders
;
219 int save_count
= count
;
222 std::bind(f_void_2
, _1
, _2
)(2, 3);
223 assert(count
== save_count
+5);
225 std::bind(f_void_2
, 2, _1
)(3);
226 assert(count
== save_count
+5);
228 std::bind(f_void_2
, 2, 3)();
229 assert(count
== save_count
+5);
232 // member function pointer
234 std::bind(&A_void_2::mem1
, _1
, _2
)(A_void_2(), 3);
235 assert(count
== save_count
+3);
237 std::bind(&A_void_2::mem1
, _2
, _1
)(3, A_void_2());
238 assert(count
== save_count
+3);
243 TEST_CONSTEXPR_CXX20
int f_nested(int i
) {
247 TEST_CONSTEXPR_CXX20
int g_nested(int i
) {
251 TEST_CONSTEXPR_CXX20
bool test_nested() {
252 using namespace std::placeholders
;
253 assert(std::bind(f_nested
, std::bind(g_nested
, _1
))(3) == 31);
257 TEST_CONSTEXPR_CXX20
bool test_many_args() {
258 using namespace std::placeholders
;
259 auto f
= [](int a
, char, float, long) { return a
; };
260 auto bound
= std::bind(f
, _4
, _3
, _2
, _1
);
261 assert(bound(0l, 1.0f
, '2', 3) == 3);
265 int main(int, char**) {
271 // The other tests are not constexpr-friendly since they need to use a global variable
272 #if TEST_STD_VER >= 20
273 static_assert(test_int_1());
274 static_assert(test_nested());