diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-06-27 00:40:41 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-06-27 00:40:41 +0000 |
commit | 9372d8bc613b2ec6fa2dbaa63d84ecc1ffaf70fc (patch) | |
tree | 779853d5156b902eb0c1e0365bbb6f8b0c77c3a6 /libcxx/test/std/utilities/function.objects | |
parent | 06e9017d7b199fc91840ecdf21b67a7006c5004f (diff) | |
download | bcm5719-llvm-9372d8bc613b2ec6fa2dbaa63d84ecc1ffaf70fc.tar.gz bcm5719-llvm-9372d8bc613b2ec6fa2dbaa63d84ecc1ffaf70fc.zip |
Implement P0358r1. Fixes for not_fn.
llvm-svn: 273837
Diffstat (limited to 'libcxx/test/std/utilities/function.objects')
-rw-r--r-- | libcxx/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp | 97 |
1 files changed, 69 insertions, 28 deletions
diff --git a/libcxx/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp b/libcxx/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp index 94839957094..c12fa792097 100644 --- a/libcxx/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp @@ -88,7 +88,6 @@ struct NoExceptCallable { Ret value; }; - struct CopyAssignableWrapper { CopyAssignableWrapper(CopyAssignableWrapper const&) = default; CopyAssignableWrapper(CopyAssignableWrapper&&) = default; @@ -124,32 +123,44 @@ struct MemFunCallable { bool value; }; -enum CallType { +enum CallType : unsigned { CT_None, - CT_Const, - CT_NonConst + CT_NonConst = 1, + CT_Const = 2, + CT_LValue = 4, + CT_RValue = 8 }; +inline constexpr CallType operator|(CallType LHS, CallType RHS) { + return static_cast<CallType>(static_cast<unsigned>(LHS) | static_cast<unsigned>(RHS)); +} + struct ForwardingCallObject { template <class ...Args> bool operator()(Args&&... args) & { - set_call<Args&&...>(CT_NonConst); + set_call<Args&&...>(CT_NonConst | CT_LValue); return true; } template <class ...Args> bool operator()(Args&&... args) const & { - set_call<Args&&...>(CT_Const); + set_call<Args&&...>(CT_Const | CT_LValue); return true; } // Don't allow the call operator to be invoked as an rvalue. template <class ...Args> - bool operator()(Args&&... args) && = delete; + bool operator()(Args&&... args) && { + set_call<Args&&...>(CT_NonConst | CT_RValue); + return true; + } template <class ...Args> - bool operator()(Args&&... args) const && = delete; + bool operator()(Args&&... args) const && { + set_call<Args&&...>(CT_Const | CT_RValue); + return true; + } template <class ...Args> static void set_call(CallType type) { @@ -450,52 +461,82 @@ void call_operator_forwarding_test() const auto& c_obj = obj; { // test zero args obj(); - assert(Fn::check_call<>(CT_NonConst)); + assert(Fn::check_call<>(CT_NonConst | CT_LValue)); + std::move(obj)(); + assert(Fn::check_call<>(CT_NonConst | CT_RValue)); c_obj(); - assert(Fn::check_call<>(CT_Const)); + assert(Fn::check_call<>(CT_Const | CT_LValue)); + std::move(c_obj)(); + assert(Fn::check_call<>(CT_Const | CT_RValue)); } { // test value categories int x = 42; const int cx = 42; obj(x); - assert(Fn::check_call<int&>(CT_NonConst)); + assert(Fn::check_call<int&>(CT_NonConst | CT_LValue)); obj(cx); - assert(Fn::check_call<const int&>(CT_NonConst)); + assert(Fn::check_call<const int&>(CT_NonConst | CT_LValue)); obj(std::move(x)); - assert(Fn::check_call<int&&>(CT_NonConst)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); obj(std::move(cx)); - assert(Fn::check_call<const int&&>(CT_NonConst)); + assert(Fn::check_call<const int&&>(CT_NonConst | CT_LValue)); obj(42); - assert(Fn::check_call<int&&>(CT_NonConst)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + } + { // test value categories - rvalue + int x = 42; + const int cx = 42; + std::move(obj)(x); + assert(Fn::check_call<int&>(CT_NonConst | CT_RValue)); + std::move(obj)(cx); + assert(Fn::check_call<const int&>(CT_NonConst | CT_RValue)); + std::move(obj)(std::move(x)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + std::move(obj)(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_NonConst | CT_RValue)); + std::move(obj)(42); + assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); } { // test value categories - const call int x = 42; const int cx = 42; c_obj(x); - assert(Fn::check_call<int&>(CT_Const)); + assert(Fn::check_call<int&>(CT_Const | CT_LValue)); c_obj(cx); - assert(Fn::check_call<const int&>(CT_Const)); + assert(Fn::check_call<const int&>(CT_Const | CT_LValue)); c_obj(std::move(x)); - assert(Fn::check_call<int&&>(CT_Const)); + assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); c_obj(std::move(cx)); - assert(Fn::check_call<const int&&>(CT_Const)); + assert(Fn::check_call<const int&&>(CT_Const | CT_LValue)); c_obj(42); - assert(Fn::check_call<int&&>(CT_Const)); + assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + } + { // test value categories - const call rvalue + int x = 42; + const int cx = 42; + std::move(c_obj)(x); + assert(Fn::check_call<int&>(CT_Const | CT_RValue)); + std::move(c_obj)(cx); + assert(Fn::check_call<const int&>(CT_Const | CT_RValue)); + std::move(c_obj)(std::move(x)); + assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + std::move(c_obj)(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_Const | CT_RValue)); + std::move(c_obj)(42); + assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); } { // test multi arg int x = 42; const double y = 3.14; std::string s = "abc"; obj(42, std::move(y), s, std::string{"foo"}); - Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_LValue); + std::move(obj)(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_RValue); c_obj(42, std::move(y), s, std::string{"foo"}); - Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const); - } - { // call as rvalue test. This should not invoke the functor as an rvalue. - std::move(obj)(); - assert(Fn::check_call<>(CT_NonConst)); - std::move(c_obj)(); - assert(Fn::check_call<>(CT_Const)); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_LValue); + std::move(c_obj)(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_RValue); } } |