Author: Arthur O'Dwyer Date: 2020-12-28T13:24:07-05:00 New Revision: 30f589c912115b4653f596eb3fd5bf62412f8aa7
URL: https://github.com/llvm/llvm-project/commit/30f589c912115b4653f596eb3fd5bf62412f8aa7 DIFF: https://github.com/llvm/llvm-project/commit/30f589c912115b4653f596eb3fd5bf62412f8aa7.diff LOG: [libc++] Constexpr-proof some machinery in not_fn.pass.cpp. NFCI. We don't need to use global variables here; we can store the "State" of this machinery on the stack, so that it's constexpr-friendly. Added: Modified: libcxx/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp Removed: ################################################################################ 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 56ed61500d3c..75f7f9fd4f02 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 @@ -135,59 +135,60 @@ inline constexpr CallType operator|(CallType LHS, CallType RHS) { } struct ForwardingCallObject { + struct State { + CallType last_call_type = CT_None; + TypeID const& (*last_call_args)() = nullptr; + + template <class ...Args> + constexpr void set_call(CallType type) { + assert(last_call_type == CT_None); + assert(last_call_args == nullptr); + last_call_type = type; + last_call_args = &makeArgumentID<Args...>; + } + + template <class ...Args> + constexpr bool check_call(CallType type) { + bool result = + last_call_type == type + && last_call_args + && *last_call_args == &makeArgumentID<Args...>; + last_call_type = CT_None; + last_call_args = nullptr; + return result; + } + }; + + State *st_; + + explicit constexpr ForwardingCallObject(State& st) : st_(&st) {} template <class ...Args> - bool operator()(Args&&...) & { - set_call<Args&&...>(CT_NonConst | CT_LValue); + constexpr bool operator()(Args&&...) & { + st_->set_call<Args&&...>(CT_NonConst | CT_LValue); return true; } template <class ...Args> - bool operator()(Args&&...) const & { - set_call<Args&&...>(CT_Const | CT_LValue); + constexpr bool operator()(Args&&...) const & { + st_->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&&...) && { - set_call<Args&&...>(CT_NonConst | CT_RValue); + constexpr bool operator()(Args&&...) && { + st_->set_call<Args&&...>(CT_NonConst | CT_RValue); return true; } template <class ...Args> - bool operator()(Args&&...) const && { - set_call<Args&&...>(CT_Const | CT_RValue); + constexpr bool operator()(Args&&...) const && { + st_->set_call<Args&&...>(CT_Const | CT_RValue); return true; } - - template <class ...Args> - static void set_call(CallType type) { - assert(last_call_type == CT_None); - assert(last_call_args == nullptr); - last_call_type = type; - last_call_args = &makeArgumentID<Args...>(); - } - - template <class ...Args> - static bool check_call(CallType type) { - bool result = - last_call_type == type - && last_call_args - && *last_call_args == makeArgumentID<Args...>(); - last_call_type = CT_None; - last_call_args = nullptr; - return result; - } - - static CallType last_call_type; - static TypeID const* last_call_args; }; -CallType ForwardingCallObject::last_call_type = CT_None; -TypeID const* ForwardingCallObject::last_call_args = nullptr; - - /////////////////////////////////////////////////////////////////////////////// // BOOL TEST TYPES @@ -467,85 +468,86 @@ void call_operator_sfinae_test() { void call_operator_forwarding_test() { using Fn = ForwardingCallObject; - auto obj = std::not_fn(Fn{}); + Fn::State st; + auto obj = std::not_fn(Fn{st}); const auto& c_obj = obj; { // test zero args obj(); - assert(Fn::check_call<>(CT_NonConst | CT_LValue)); + assert(st.check_call<>(CT_NonConst | CT_LValue)); std::move(obj)(); - assert(Fn::check_call<>(CT_NonConst | CT_RValue)); + assert(st.check_call<>(CT_NonConst | CT_RValue)); c_obj(); - assert(Fn::check_call<>(CT_Const | CT_LValue)); + assert(st.check_call<>(CT_Const | CT_LValue)); std::move(c_obj)(); - assert(Fn::check_call<>(CT_Const | CT_RValue)); + assert(st.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 | CT_LValue)); + assert(st.check_call<int&>(CT_NonConst | CT_LValue)); obj(cx); - assert(Fn::check_call<const int&>(CT_NonConst | CT_LValue)); + assert(st.check_call<const int&>(CT_NonConst | CT_LValue)); obj(std::move(x)); - assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + assert(st.check_call<int&&>(CT_NonConst | CT_LValue)); obj(std::move(cx)); - assert(Fn::check_call<const int&&>(CT_NonConst | CT_LValue)); + assert(st.check_call<const int&&>(CT_NonConst | CT_LValue)); obj(42); - assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + assert(st.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)); + assert(st.check_call<int&>(CT_NonConst | CT_RValue)); std::move(obj)(cx); - assert(Fn::check_call<const int&>(CT_NonConst | CT_RValue)); + assert(st.check_call<const int&>(CT_NonConst | CT_RValue)); std::move(obj)(std::move(x)); - assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + assert(st.check_call<int&&>(CT_NonConst | CT_RValue)); std::move(obj)(std::move(cx)); - assert(Fn::check_call<const int&&>(CT_NonConst | CT_RValue)); + assert(st.check_call<const int&&>(CT_NonConst | CT_RValue)); std::move(obj)(42); - assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + assert(st.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 | CT_LValue)); + assert(st.check_call<int&>(CT_Const | CT_LValue)); c_obj(cx); - assert(Fn::check_call<const int&>(CT_Const | CT_LValue)); + assert(st.check_call<const int&>(CT_Const | CT_LValue)); c_obj(std::move(x)); - assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + assert(st.check_call<int&&>(CT_Const | CT_LValue)); c_obj(std::move(cx)); - assert(Fn::check_call<const int&&>(CT_Const | CT_LValue)); + assert(st.check_call<const int&&>(CT_Const | CT_LValue)); c_obj(42); - assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + assert(st.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)); + assert(st.check_call<int&>(CT_Const | CT_RValue)); std::move(c_obj)(cx); - assert(Fn::check_call<const int&>(CT_Const | CT_RValue)); + assert(st.check_call<const int&>(CT_Const | CT_RValue)); std::move(c_obj)(std::move(x)); - assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + assert(st.check_call<int&&>(CT_Const | CT_RValue)); std::move(c_obj)(std::move(cx)); - assert(Fn::check_call<const int&&>(CT_Const | CT_RValue)); + assert(st.check_call<const int&&>(CT_Const | CT_RValue)); std::move(c_obj)(42); - assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + assert(st.check_call<int&&>(CT_Const | CT_RValue)); } { // test multi arg 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 | CT_LValue); + assert((st.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); + assert((st.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 | CT_LValue); + assert((st.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); + assert((st.check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_RValue))); } } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits