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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
11 // template <class F> unspecified not_fn(F&& f);
14 #include <type_traits>
18 #include "test_macros.h"
20 #include "callable_types.h"
22 ///////////////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////////////
27 static int bang_called
;
29 EvilBool(EvilBool
const&) = default;
30 EvilBool(EvilBool
&&) = default;
32 friend EvilBool
operator!(EvilBool
const& other
) {
34 return EvilBool
{!other
.value
};
38 friend struct MoveOnlyCallable
<EvilBool
>;
39 friend struct CopyCallable
<EvilBool
>;
40 friend struct NoExceptCallable
<EvilBool
>;
42 constexpr explicit EvilBool(bool x
) : value(x
) {}
43 EvilBool
& operator=(EvilBool
const& other
) = default;
49 int EvilBool::bang_called
= 0;
52 ExplicitBool(ExplicitBool
const&) = default;
53 ExplicitBool(ExplicitBool
&&) = default;
55 constexpr explicit operator bool() const { return value
; }
58 friend struct MoveOnlyCallable
<ExplicitBool
>;
59 friend struct CopyCallable
<ExplicitBool
>;
61 constexpr explicit ExplicitBool(bool x
) : value(x
) {}
62 constexpr ExplicitBool
& operator=(bool x
) {
71 struct NoExceptEvilBool
{
72 NoExceptEvilBool(NoExceptEvilBool
const&) = default;
73 NoExceptEvilBool(NoExceptEvilBool
&&) = default;
74 NoExceptEvilBool
& operator=(NoExceptEvilBool
const& other
) = default;
76 constexpr explicit NoExceptEvilBool(bool x
) : value(x
) {}
78 friend NoExceptEvilBool
operator!(NoExceptEvilBool
const& other
) noexcept
{
79 return NoExceptEvilBool
{!other
.value
};
88 bool constructor_tests()
91 using T
= MoveOnlyCallable
<bool>;
93 using RetT
= decltype(std::not_fn(std::move(value
)));
94 static_assert(std::is_move_constructible
<RetT
>::value
, "");
95 static_assert(!std::is_copy_constructible
<RetT
>::value
, "");
96 static_assert(!std::is_move_assignable
<RetT
>::value
, "");
97 static_assert(!std::is_copy_assignable
<RetT
>::value
, "");
98 auto ret
= std::not_fn(std::move(value
));
99 // test it was moved from
100 assert(value
.value
== false);
101 // test that ret() negates the original value 'true'
102 assert(ret() == false);
103 assert(ret(0, 0.0, "blah") == false);
104 // Move ret and test that it was moved from and that ret2 got the
106 auto ret2
= std::move(ret
);
107 assert(ret() == true);
108 assert(ret2() == false);
109 assert(ret2(42) == false);
112 using T
= CopyCallable
<bool>;
114 using RetT
= decltype(std::not_fn(value
));
115 static_assert(std::is_move_constructible
<RetT
>::value
, "");
116 static_assert(std::is_copy_constructible
<RetT
>::value
, "");
117 static_assert(!std::is_move_assignable
<RetT
>::value
, "");
118 static_assert(!std::is_copy_assignable
<RetT
>::value
, "");
119 auto ret
= std::not_fn(value
);
120 // test that value is unchanged (copied not moved)
121 assert(value
.value
== false);
122 // test 'ret' has the original value
123 assert(ret() == true);
124 assert(ret(42, 100) == true);
125 // move from 'ret' and check that 'ret2' has the original value.
126 auto ret2
= std::move(ret
);
127 assert(ret() == false);
128 assert(ret2() == true);
129 assert(ret2("abc") == true);
130 // initialize not_fn with rvalue
131 auto ret3
= std::not_fn(std::move(value
));
132 assert(ret(0) == false);
133 assert(ret3(0) == true);
136 using T
= CopyAssignableWrapper
;
139 using RetT
= decltype(std::not_fn(value
));
140 static_assert(std::is_move_constructible
<RetT
>::value
, "");
141 static_assert(std::is_copy_constructible
<RetT
>::value
, "");
142 auto ret
= std::not_fn(value
);
143 assert(ret() == false);
144 auto ret2
= std::not_fn(value2
);
145 assert(ret2() == true);
148 using T
= MoveAssignableWrapper
;
151 using RetT
= decltype(std::not_fn(std::move(value
)));
152 static_assert(std::is_move_constructible
<RetT
>::value
, "");
153 static_assert(!std::is_copy_constructible
<RetT
>::value
, "");
154 static_assert(!std::is_copy_assignable
<RetT
>::value
, "");
155 auto ret
= std::not_fn(std::move(value
));
156 assert(ret() == false);
157 auto ret2
= std::not_fn(std::move(value2
));
158 assert(ret2() == true);
163 void return_type_tests()
167 using T
= CopyCallable
<bool>;
168 auto ret
= std::not_fn(T
{false});
169 static_assert(is_same
<decltype(ret()), bool>::value
, "");
170 static_assert(is_same
<decltype(ret("abc")), bool>::value
, "");
171 assert(ret() == true);
174 using T
= CopyCallable
<ExplicitBool
>;
175 auto ret
= std::not_fn(T
{true});
176 static_assert(is_same
<decltype(ret()), bool>::value
, "");
177 static_assert(is_same
<decltype(ret(std::string("abc"))), bool>::value
, "");
178 assert(ret() == false);
181 using T
= CopyCallable
<EvilBool
>;
182 auto ret
= std::not_fn(T
{false});
183 static_assert(is_same
<decltype(ret()), EvilBool
>::value
, "");
184 EvilBool::bang_called
= 0;
185 auto value_ret
= ret();
186 assert(EvilBool::bang_called
== 1);
187 assert(value_ret
.value
== true);
189 assert(EvilBool::bang_called
== 2);
193 // Other tests only test using objects with call operators. Test various
194 // other callable types here.
196 bool other_callable_types_test()
198 { // test with function pointer
199 auto ret
= std::not_fn(returns_true
);
200 assert(ret() == false);
202 { // test with lambda
203 auto returns_value
= [](bool value
) { return value
; };
204 auto ret
= std::not_fn(returns_value
);
205 assert(ret(true) == false);
206 assert(ret(false) == true);
208 { // test with pointer to member function
209 MemFunCallable
mt(true);
210 const MemFunCallable
mf(false);
211 auto ret
= std::not_fn(&MemFunCallable::return_value
);
212 assert(ret(mt
) == false);
213 assert(ret(mf
) == true);
214 assert(ret(&mt
) == false);
215 assert(ret(&mf
) == true);
217 { // test with pointer to member function
218 MemFunCallable
mt(true);
219 MemFunCallable
mf(false);
220 auto ret
= std::not_fn(&MemFunCallable::return_value_nc
);
221 assert(ret(mt
) == false);
222 assert(ret(mf
) == true);
223 assert(ret(&mt
) == false);
224 assert(ret(&mf
) == true);
226 { // test with pointer to member data
227 MemFunCallable
mt(true);
228 const MemFunCallable
mf(false);
229 auto ret
= std::not_fn(&MemFunCallable::value
);
230 assert(ret(mt
) == false);
231 assert(ret(mf
) == true);
232 assert(ret(&mt
) == false);
233 assert(ret(&mf
) == true);
238 void throws_in_constructor_test()
240 #ifndef TEST_HAS_NO_EXCEPTIONS
241 struct ThrowsOnCopy
{
242 ThrowsOnCopy(ThrowsOnCopy
const&) {
245 ThrowsOnCopy() = default;
246 bool operator()() const {
248 #ifdef TEST_COMPILER_MSVC
251 __builtin_unreachable();
258 (void)std::not_fn(cp
);
260 } catch (int const& value
) {
268 bool call_operator_sfinae_test() {
269 { // wrong number of arguments
270 using T
= decltype(std::not_fn(returns_true
));
271 static_assert(std::is_invocable
<T
>::value
, ""); // callable only with no args
272 static_assert(!std::is_invocable
<T
, bool>::value
, "");
274 { // violates const correctness (member function pointer)
275 using T
= decltype(std::not_fn(&MemFunCallable::return_value_nc
));
276 static_assert(std::is_invocable
<T
, MemFunCallable
&>::value
, "");
277 static_assert(!std::is_invocable
<T
, const MemFunCallable
&>::value
, "");
279 { // violates const correctness (call object)
280 using Obj
= CopyCallable
<bool>;
281 using NCT
= decltype(std::not_fn(Obj
{true}));
282 using CT
= const NCT
;
283 static_assert(std::is_invocable
<NCT
>::value
, "");
284 static_assert(!std::is_invocable
<CT
>::value
, "");
286 { // returns bad type with no operator!
287 auto fn
= [](auto x
) { return x
; };
288 using T
= decltype(std::not_fn(fn
));
289 static_assert(std::is_invocable
<T
, bool>::value
, "");
290 static_assert(!std::is_invocable
<T
, std::string
>::value
, "");
296 bool call_operator_forwarding_test()
298 using Fn
= ForwardingCallObject
;
300 auto obj
= std::not_fn(Fn
{st
});
301 const auto& c_obj
= obj
;
304 assert(st
.check_call
<>(CT_NonConst
| CT_LValue
));
306 assert(st
.check_call
<>(CT_NonConst
| CT_RValue
));
308 assert(st
.check_call
<>(CT_Const
| CT_LValue
));
310 assert(st
.check_call
<>(CT_Const
| CT_RValue
));
312 { // test value categories
316 assert(st
.check_call
<int&>(CT_NonConst
| CT_LValue
));
318 assert(st
.check_call
<const int&>(CT_NonConst
| CT_LValue
));
320 assert(st
.check_call
<int&&>(CT_NonConst
| CT_LValue
));
322 assert(st
.check_call
<const int&&>(CT_NonConst
| CT_LValue
));
324 assert(st
.check_call
<int&&>(CT_NonConst
| CT_LValue
));
326 { // test value categories - rvalue
330 assert(st
.check_call
<int&>(CT_NonConst
| CT_RValue
));
332 assert(st
.check_call
<const int&>(CT_NonConst
| CT_RValue
));
333 std::move(obj
)(std::move(x
));
334 assert(st
.check_call
<int&&>(CT_NonConst
| CT_RValue
));
335 std::move(obj
)(std::move(cx
));
336 assert(st
.check_call
<const int&&>(CT_NonConst
| CT_RValue
));
338 assert(st
.check_call
<int&&>(CT_NonConst
| CT_RValue
));
340 { // test value categories - const call
344 assert(st
.check_call
<int&>(CT_Const
| CT_LValue
));
346 assert(st
.check_call
<const int&>(CT_Const
| CT_LValue
));
348 assert(st
.check_call
<int&&>(CT_Const
| CT_LValue
));
349 c_obj(std::move(cx
));
350 assert(st
.check_call
<const int&&>(CT_Const
| CT_LValue
));
352 assert(st
.check_call
<int&&>(CT_Const
| CT_LValue
));
354 { // test value categories - const call rvalue
358 assert(st
.check_call
<int&>(CT_Const
| CT_RValue
));
359 std::move(c_obj
)(cx
);
360 assert(st
.check_call
<const int&>(CT_Const
| CT_RValue
));
361 std::move(c_obj
)(std::move(x
));
362 assert(st
.check_call
<int&&>(CT_Const
| CT_RValue
));
363 std::move(c_obj
)(std::move(cx
));
364 assert(st
.check_call
<const int&&>(CT_Const
| CT_RValue
));
365 std::move(c_obj
)(42);
366 assert(st
.check_call
<int&&>(CT_Const
| CT_RValue
));
369 using String
= const char *;
370 const double y
= 3.14;
372 obj(42, std::move(y
), s
, String
{"foo"});
373 assert((st
.check_call
<int&&, const double&&, String
&, String
&&>(CT_NonConst
| CT_LValue
)));
374 std::move(obj
)(42, std::move(y
), s
, String
{"foo"});
375 assert((st
.check_call
<int&&, const double&&, String
&, String
&&>(CT_NonConst
| CT_RValue
)));
376 c_obj(42, std::move(y
), s
, String
{"foo"});
377 assert((st
.check_call
<int&&, const double&&, String
&, String
&&>(CT_Const
| CT_LValue
)));
378 std::move(c_obj
)(42, std::move(y
), s
, String
{"foo"});
379 assert((st
.check_call
<int&&, const double&&, String
&, String
&&>(CT_Const
| CT_RValue
)));
385 bool call_operator_noexcept_test()
388 using T
= ConstCallable
<bool>;
390 auto ret
= std::not_fn(value
);
391 static_assert(!noexcept(ret()), "call should not be noexcept");
392 auto const& cret
= ret
;
393 static_assert(!noexcept(cret()), "call should not be noexcept");
396 using T
= NoExceptCallable
<bool>;
398 auto ret
= std::not_fn(value
);
399 LIBCPP_STATIC_ASSERT(noexcept(!std::__invoke(value
)), "");
400 #if TEST_STD_VER > 14
401 static_assert(noexcept(!std::invoke(value
)), "");
403 static_assert(noexcept(ret()), "call should be noexcept");
404 auto const& cret
= ret
;
405 static_assert(noexcept(cret()), "call should be noexcept");
408 using T
= NoExceptCallable
<NoExceptEvilBool
>;
410 auto ret
= std::not_fn(value
);
411 static_assert(noexcept(ret()), "call should not be noexcept");
412 auto const& cret
= ret
;
413 static_assert(noexcept(cret()), "call should not be noexcept");
416 using T
= NoExceptCallable
<EvilBool
>;
418 auto ret
= std::not_fn(value
);
419 static_assert(!noexcept(ret()), "call should not be noexcept");
420 auto const& cret
= ret
;
421 static_assert(!noexcept(cret()), "call should not be noexcept");
427 bool test_lwg2767() {
428 // See https://cplusplus.github.io/LWG/lwg-defects.html#2767
429 struct Abstract
{ virtual void f() const = 0; };
430 struct Derived
: public Abstract
{ void f() const {} };
431 struct F
{ constexpr bool operator()(Abstract
&&) { return false; } };
435 bool b
= std::not_fn(F
{})(std::move(a
));
441 int main(int, char**)
445 other_callable_types_test();
446 throws_in_constructor_test();
447 call_operator_sfinae_test(); // somewhat of an extension
448 call_operator_forwarding_test();
449 call_operator_noexcept_test();
452 #if TEST_STD_VER >= 20
453 static_assert(constructor_tests());
454 static_assert(other_callable_types_test());
455 static_assert(call_operator_sfinae_test()); // somewhat of an extension
456 static_assert(call_operator_forwarding_test());
457 static_assert(call_operator_noexcept_test());
458 static_assert(test_lwg2767());