1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
12 // template <class F> unspecified not_fn(F&& f);
15 #include <type_traits>
19 #include "test_macros.h"
23 ///////////////////////////////////////////////////////////////////////////////
24 // CALLABLE TEST TYPES
25 ///////////////////////////////////////////////////////////////////////////////
27 bool returns_true() { return true; }
29 template <class Ret = bool>
30 struct MoveOnlyCallable {
31 MoveOnlyCallable(MoveOnlyCallable const&) = delete;
32 MoveOnlyCallable(MoveOnlyCallable&& other)
34 { other.value = !other.value; }
36 template <class ...Args>
37 Ret operator()(Args&&...) { return Ret{value}; }
39 explicit MoveOnlyCallable(bool x) : value(x) {}
43 template <class Ret = bool>
45 CopyCallable(CopyCallable const& other)
46 : value(other.value) {}
48 CopyCallable(CopyCallable&& other)
49 : value(other.value) { other.value = !other.value; }
51 template <class ...Args>
52 Ret operator()(Args&&...) { return Ret{value}; }
54 explicit CopyCallable(bool x) : value(x) {}
59 template <class Ret = bool>
60 struct ConstCallable {
61 ConstCallable(ConstCallable const& other)
62 : value(other.value) {}
64 ConstCallable(ConstCallable&& other)
65 : value(other.value) { other.value = !other.value; }
67 template <class ...Args>
68 Ret operator()(Args&&...) const { return Ret{value}; }
70 explicit ConstCallable(bool x) : value(x) {}
76 template <class Ret = bool>
77 struct NoExceptCallable {
78 NoExceptCallable(NoExceptCallable const& other)
79 : value(other.value) {}
81 template <class ...Args>
82 Ret operator()(Args&&...) noexcept { return Ret{value}; }
84 template <class ...Args>
85 Ret operator()(Args&&...) const noexcept { return Ret{value}; }
87 explicit NoExceptCallable(bool x) : value(x) {}
91 struct CopyAssignableWrapper {
92 CopyAssignableWrapper(CopyAssignableWrapper const&) = default;
93 CopyAssignableWrapper(CopyAssignableWrapper&&) = default;
94 CopyAssignableWrapper& operator=(CopyAssignableWrapper const&) = default;
95 CopyAssignableWrapper& operator=(CopyAssignableWrapper &&) = default;
97 template <class ...Args>
98 bool operator()(Args&&...) { return value; }
100 explicit CopyAssignableWrapper(bool x) : value(x) {}
105 struct MoveAssignableWrapper {
106 MoveAssignableWrapper(MoveAssignableWrapper const&) = delete;
107 MoveAssignableWrapper(MoveAssignableWrapper&&) = default;
108 MoveAssignableWrapper& operator=(MoveAssignableWrapper const&) = delete;
109 MoveAssignableWrapper& operator=(MoveAssignableWrapper &&) = default;
111 template <class ...Args>
112 bool operator()(Args&&...) { return value; }
114 explicit MoveAssignableWrapper(bool x) : value(x) {}
118 struct MemFunCallable {
119 explicit MemFunCallable(bool x) : value(x) {}
121 bool return_value() const { return value; }
122 bool return_value_nc() { return value; }
126 enum CallType : unsigned {
134 inline constexpr CallType operator|(CallType LHS, CallType RHS) {
135 return static_cast<CallType>(static_cast<unsigned>(LHS) | static_cast<unsigned>(RHS));
138 struct ForwardingCallObject {
140 template <class ...Args>
141 bool operator()(Args&&...) & {
142 set_call<Args&&...>(CT_NonConst | CT_LValue);
146 template <class ...Args>
147 bool operator()(Args&&...) const & {
148 set_call<Args&&...>(CT_Const | CT_LValue);
152 // Don't allow the call operator to be invoked as an rvalue.
153 template <class ...Args>
154 bool operator()(Args&&...) && {
155 set_call<Args&&...>(CT_NonConst | CT_RValue);
159 template <class ...Args>
160 bool operator()(Args&&...) const && {
161 set_call<Args&&...>(CT_Const | CT_RValue);
165 template <class ...Args>
166 static void set_call(CallType type) {
167 assert(last_call_type == CT_None);
168 assert(last_call_args == nullptr);
169 last_call_type = type;
170 last_call_args = &makeArgumentID<Args...>();
173 template <class ...Args>
174 static bool check_call(CallType type) {
176 last_call_type == type
178 && *last_call_args == makeArgumentID<Args...>();
179 last_call_type = CT_None;
180 last_call_args = nullptr;
184 static CallType last_call_type;
185 static TypeID const* last_call_args;
188 CallType ForwardingCallObject::last_call_type = CT_None;
189 TypeID const* ForwardingCallObject::last_call_args = nullptr;
193 ///////////////////////////////////////////////////////////////////////////////
195 ///////////////////////////////////////////////////////////////////////////////
198 static int bang_called;
200 EvilBool(EvilBool const&) = default;
201 EvilBool(EvilBool&&) = default;
203 friend EvilBool operator!(EvilBool const& other) {
205 return EvilBool{!other.value};
209 friend struct MoveOnlyCallable<EvilBool>;
210 friend struct CopyCallable<EvilBool>;
211 friend struct NoExceptCallable<EvilBool>;
213 explicit EvilBool(bool x) : value(x) {}
214 EvilBool& operator=(EvilBool const& other) = default;
220 int EvilBool::bang_called = 0;
222 struct ExplicitBool {
223 ExplicitBool(ExplicitBool const&) = default;
224 ExplicitBool(ExplicitBool&&) = default;
226 explicit operator bool() const { return value; }
229 friend struct MoveOnlyCallable<ExplicitBool>;
230 friend struct CopyCallable<ExplicitBool>;
232 explicit ExplicitBool(bool x) : value(x) {}
233 ExplicitBool& operator=(bool x) {
242 struct NoExceptEvilBool {
243 NoExceptEvilBool(NoExceptEvilBool const&) = default;
244 NoExceptEvilBool(NoExceptEvilBool&&) = default;
245 NoExceptEvilBool& operator=(NoExceptEvilBool const& other) = default;
247 explicit NoExceptEvilBool(bool x) : value(x) {}
249 friend NoExceptEvilBool operator!(NoExceptEvilBool const& other) noexcept {
250 return NoExceptEvilBool{!other.value};
258 void constructor_tests()
261 using T = MoveOnlyCallable<bool>;
263 using RetT = decltype(std::not_fn(std::move(value)));
264 static_assert(std::is_move_constructible<RetT>::value, "");
265 static_assert(!std::is_copy_constructible<RetT>::value, "");
266 static_assert(!std::is_move_assignable<RetT>::value, "");
267 static_assert(!std::is_copy_assignable<RetT>::value, "");
268 auto ret = std::not_fn(std::move(value));
269 // test it was moved from
270 assert(value.value == false);
271 // test that ret() negates the original value 'true'
272 assert(ret() == false);
273 assert(ret(0, 0.0, "blah") == false);
274 // Move ret and test that it was moved from and that ret2 got the
276 auto ret2 = std::move(ret);
277 assert(ret() == true);
278 assert(ret2() == false);
279 assert(ret2(42) == false);
282 using T = CopyCallable<bool>;
284 using RetT = decltype(std::not_fn(value));
285 static_assert(std::is_move_constructible<RetT>::value, "");
286 static_assert(std::is_copy_constructible<RetT>::value, "");
287 static_assert(!std::is_move_assignable<RetT>::value, "");
288 static_assert(!std::is_copy_assignable<RetT>::value, "");
289 auto ret = std::not_fn(value);
290 // test that value is unchanged (copied not moved)
291 assert(value.value == false);
292 // test 'ret' has the original value
293 assert(ret() == true);
294 assert(ret(42, 100) == true);
295 // move from 'ret' and check that 'ret2' has the original value.
296 auto ret2 = std::move(ret);
297 assert(ret() == false);
298 assert(ret2() == true);
299 assert(ret2("abc") == true);
302 using T = CopyAssignableWrapper;
305 using RetT = decltype(std::not_fn(value));
306 static_assert(std::is_move_constructible<RetT>::value, "");
307 static_assert(std::is_copy_constructible<RetT>::value, "");
308 static_assert(std::is_move_assignable<RetT>::value, "");
309 static_assert(std::is_copy_assignable<RetT>::value, "");
310 auto ret = std::not_fn(value);
311 assert(ret() == false);
312 auto ret2 = std::not_fn(value2);
313 assert(ret2() == true);
315 assert(ret() == true);
316 assert(ret2() == true);
319 using T = MoveAssignableWrapper;
322 using RetT = decltype(std::not_fn(std::move(value)));
323 static_assert(std::is_move_constructible<RetT>::value, "");
324 static_assert(!std::is_copy_constructible<RetT>::value, "");
325 static_assert(std::is_move_assignable<RetT>::value, "");
326 static_assert(!std::is_copy_assignable<RetT>::value, "");
327 auto ret = std::not_fn(std::move(value));
328 assert(ret() == false);
329 auto ret2 = std::not_fn(std::move(value2));
330 assert(ret2() == true);
331 ret = std::move(ret2);
332 assert(ret() == true);
336 void return_type_tests()
340 using T = CopyCallable<bool>;
341 auto ret = std::not_fn(T{false});
342 static_assert(is_same<decltype(ret()), bool>::value, "");
343 static_assert(is_same<decltype(ret("abc")), bool>::value, "");
344 assert(ret() == true);
347 using T = CopyCallable<ExplicitBool>;
348 auto ret = std::not_fn(T{true});
349 static_assert(is_same<decltype(ret()), bool>::value, "");
350 static_assert(is_same<decltype(ret(std::string("abc"))), bool>::value, "");
351 assert(ret() == false);
354 using T = CopyCallable<EvilBool>;
355 auto ret = std::not_fn(T{false});
356 static_assert(is_same<decltype(ret()), EvilBool>::value, "");
357 EvilBool::bang_called = 0;
358 auto value_ret = ret();
359 assert(EvilBool::bang_called == 1);
360 assert(value_ret.value == true);
362 assert(EvilBool::bang_called == 2);
366 // Other tests only test using objects with call operators. Test various
367 // other callable types here.
368 void other_callable_types_test()
370 { // test with function pointer
371 auto ret = std::not_fn(returns_true);
372 assert(ret() == false);
374 { // test with lambda
375 auto returns_value = [](bool value) { return value; };
376 auto ret = std::not_fn(returns_value);
377 assert(ret(true) == false);
378 assert(ret(false) == true);
380 { // test with pointer to member function
381 MemFunCallable mt(true);
382 const MemFunCallable mf(false);
383 auto ret = std::not_fn(&MemFunCallable::return_value);
384 assert(ret(mt) == false);
385 assert(ret(mf) == true);
386 assert(ret(&mt) == false);
387 assert(ret(&mf) == true);
389 { // test with pointer to member function
390 MemFunCallable mt(true);
391 MemFunCallable mf(false);
392 auto ret = std::not_fn(&MemFunCallable::return_value_nc);
393 assert(ret(mt) == false);
394 assert(ret(mf) == true);
395 assert(ret(&mt) == false);
396 assert(ret(&mf) == true);
398 { // test with pointer to member data
399 MemFunCallable mt(true);
400 const MemFunCallable mf(false);
401 auto ret = std::not_fn(&MemFunCallable::value);
402 assert(ret(mt) == false);
403 assert(ret(mf) == true);
404 assert(ret(&mt) == false);
405 assert(ret(&mf) == true);
409 void throws_in_constructor_test()
411 #ifndef TEST_HAS_NO_EXCEPTIONS
412 struct ThrowsOnCopy {
413 ThrowsOnCopy(ThrowsOnCopy const&) {
416 ThrowsOnCopy() = default;
417 bool operator()() const { assert(false); }
424 } catch (int const& value) {
431 void call_operator_sfinae_test() {
432 { // wrong number of arguments
433 using T = decltype(std::not_fn(returns_true));
434 static_assert(std::is_callable<T()>::value, ""); // callable only with no args
435 static_assert(!std::is_callable<T(bool)>::value, "");
437 { // violates const correctness (member function pointer)
438 using T = decltype(std::not_fn(&MemFunCallable::return_value_nc));
439 static_assert(std::is_callable<T(MemFunCallable&)>::value, "");
440 static_assert(!std::is_callable<T(const MemFunCallable&)>::value, "");
442 { // violates const correctness (call object)
443 using Obj = CopyCallable<bool>;
444 using NCT = decltype(std::not_fn(Obj{true}));
445 using CT = const NCT;
446 static_assert(std::is_callable<NCT()>::value, "");
447 static_assert(!std::is_callable<CT()>::value, "");
449 { // returns bad type with no operator!
450 auto fn = [](auto x) { return x; };
451 using T = decltype(std::not_fn(fn));
452 static_assert(std::is_callable<T(bool)>::value, "");
453 static_assert(!std::is_callable<T(std::string)>::value, "");
457 void call_operator_forwarding_test()
459 using Fn = ForwardingCallObject;
460 auto obj = std::not_fn(Fn{});
461 const auto& c_obj = obj;
464 assert(Fn::check_call<>(CT_NonConst | CT_LValue));
466 assert(Fn::check_call<>(CT_NonConst | CT_RValue));
468 assert(Fn::check_call<>(CT_Const | CT_LValue));
470 assert(Fn::check_call<>(CT_Const | CT_RValue));
472 { // test value categories
476 assert(Fn::check_call<int&>(CT_NonConst | CT_LValue));
478 assert(Fn::check_call<const int&>(CT_NonConst | CT_LValue));
480 assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue));
482 assert(Fn::check_call<const int&&>(CT_NonConst | CT_LValue));
484 assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue));
486 { // test value categories - rvalue
490 assert(Fn::check_call<int&>(CT_NonConst | CT_RValue));
492 assert(Fn::check_call<const int&>(CT_NonConst | CT_RValue));
493 std::move(obj)(std::move(x));
494 assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue));
495 std::move(obj)(std::move(cx));
496 assert(Fn::check_call<const int&&>(CT_NonConst | CT_RValue));
498 assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue));
500 { // test value categories - const call
504 assert(Fn::check_call<int&>(CT_Const | CT_LValue));
506 assert(Fn::check_call<const int&>(CT_Const | CT_LValue));
508 assert(Fn::check_call<int&&>(CT_Const | CT_LValue));
509 c_obj(std::move(cx));
510 assert(Fn::check_call<const int&&>(CT_Const | CT_LValue));
512 assert(Fn::check_call<int&&>(CT_Const | CT_LValue));
514 { // test value categories - const call rvalue
518 assert(Fn::check_call<int&>(CT_Const | CT_RValue));
519 std::move(c_obj)(cx);
520 assert(Fn::check_call<const int&>(CT_Const | CT_RValue));
521 std::move(c_obj)(std::move(x));
522 assert(Fn::check_call<int&&>(CT_Const | CT_RValue));
523 std::move(c_obj)(std::move(cx));
524 assert(Fn::check_call<const int&&>(CT_Const | CT_RValue));
525 std::move(c_obj)(42);
526 assert(Fn::check_call<int&&>(CT_Const | CT_RValue));
529 const double y = 3.14;
530 std::string s = "abc";
531 obj(42, std::move(y), s, std::string{"foo"});
532 Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_LValue);
533 std::move(obj)(42, std::move(y), s, std::string{"foo"});
534 Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_RValue);
535 c_obj(42, std::move(y), s, std::string{"foo"});
536 Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_LValue);
537 std::move(c_obj)(42, std::move(y), s, std::string{"foo"});
538 Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_RValue);
542 void call_operator_noexcept_test()
545 using T = ConstCallable<bool>;
547 auto ret = std::not_fn(value);
548 static_assert(!noexcept(ret()), "call should not be noexcept");
549 auto const& cret = ret;
550 static_assert(!noexcept(cret()), "call should not be noexcept");
553 using T = NoExceptCallable<bool>;
555 auto ret = std::not_fn(value);
556 LIBCPP_STATIC_ASSERT(noexcept(!_VSTD::__invoke(value)), "");
557 #if TEST_STD_VER > 14
558 static_assert(noexcept(!std::invoke(value)), "");
560 static_assert(noexcept(ret()), "call should be noexcept");
561 auto const& cret = ret;
562 static_assert(noexcept(cret()), "call should be noexcept");
565 using T = NoExceptCallable<NoExceptEvilBool>;
567 auto ret = std::not_fn(value);
568 static_assert(noexcept(ret()), "call should not be noexcept");
569 auto const& cret = ret;
570 static_assert(noexcept(cret()), "call should not be noexcept");
573 using T = NoExceptCallable<EvilBool>;
575 auto ret = std::not_fn(value);
576 static_assert(!noexcept(ret()), "call should not be noexcept");
577 auto const& cret = ret;
578 static_assert(!noexcept(cret()), "call should not be noexcept");
582 void test_lwg2767() {
583 // See http://wg21.link/LWG2767
584 struct Abstract { virtual void f() const = 0; };
585 struct Derived : public Abstract { void f() const {} };
586 struct F { bool operator()(Abstract&&) { return false; } };
590 bool b = std::not_fn(F{})(std::move(a));
599 other_callable_types_test();
600 throws_in_constructor_test();
601 call_operator_sfinae_test(); // somewhat of an extension
602 call_operator_forwarding_test();
603 call_operator_noexcept_test();