[libcxx] r273837 - Implement P0358r1. Fixes for not_fn.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 26 17:40:41 PDT 2016


Author: ericwf
Date: Sun Jun 26 19:40:41 2016
New Revision: 273837

URL: http://llvm.org/viewvc/llvm-project?rev=273837&view=rev
Log:
Implement P0358r1. Fixes for not_fn.

Modified:
    libcxx/trunk/include/functional
    libcxx/trunk/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp

Modified: libcxx/trunk/include/functional
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/functional?rev=273837&r1=273836&r2=273837&view=diff
==============================================================================
--- libcxx/trunk/include/functional (original)
+++ libcxx/trunk/include/functional Sun Jun 26 19:40:41 2016
@@ -2618,18 +2618,33 @@ public:
 
     template <class ..._Args>
     _LIBCPP_INLINE_VISIBILITY
-    auto operator()(_Args&& ...__args)
+    auto operator()(_Args&& ...__args) &
             noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
         -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
         { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
 
     template <class ..._Args>
     _LIBCPP_INLINE_VISIBILITY
-    auto operator()(_Args&& ...__args) const
+    auto operator()(_Args&& ...__args) &&
+            noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)))
+        -> decltype(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))
+        { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); }
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Args&& ...__args) const&
             noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
         -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
         { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
 
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Args&& ...__args) const&&
+            noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)))
+        -> decltype(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))
+        { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); }
+
 private:
     template <class _RawFunc,
               class = enable_if_t<!is_same<decay_t<_RawFunc>, __not_fn_imp>::value>>

Modified: libcxx/trunk/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp?rev=273837&r1=273836&r2=273837&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp Sun Jun 26 19:40:41 2016
@@ -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);
     }
 }
 




More information about the cfe-commits mailing list