Define macro to simplify std::_Not_fn definition
authorJonathan Wakely <jwakely@redhat.com>
Thu, 9 Mar 2017 20:36:42 +0000 (20:36 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 9 Mar 2017 20:36:42 +0000 (20:36 +0000)
* include/std/functional (_Not_fn): Define macro to simplify
repetitive function definitions.

From-SVN: r246013

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/functional

index dabac4a..9da31bc 100644 (file)
@@ -1,5 +1,8 @@
 2017-03-09  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/std/functional (_Not_fn): Define macro to simplify
+       repetitive function definitions.
+
        * doc/xml/manual/status_cxx2017.xml: Document std::byte support.
        * include/c_global/cstddef (std::byte): Define for C++17.
        * testsuite/18_support/byte/global_neg.cc: New test.
index ea36dd0..366a7fb 100644 (file)
@@ -902,15 +902,12 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
   template<typename _Fn>
     class _Not_fn
     {
-      template<typename _Tp>
-       using __is_nothrow_negatable
-         = __bool_constant<noexcept(!std::declval<_Tp>())>;
-
       template<typename _Fn2, typename... _Args>
-       using __noexcept_cond = __and_<
-         __is_nothrow_callable<_Fn2(_Args&&...)>,
-         __is_nothrow_negatable<result_of_t<_Fn2(_Args&&...)>>
-       >;
+       using __inv_res_t = result_of_t<_Fn2(_Args&&...)>;
+
+      template<typename _Tp>
+       static decltype(!std::declval<_Tp>())
+       _S_not() noexcept(noexcept(!std::declval<_Tp>()));
 
     public:
       template<typename _Fn2>
@@ -921,39 +918,23 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
       _Not_fn(_Not_fn&& __fn) = default;
       ~_Not_fn() = default;
 
-      template<typename... _Args>
-       auto
-       operator()(_Args&&... __args) &
-       noexcept(__noexcept_cond<_Fn&, _Args&&...>::value)
-       -> decltype(!std::declval<result_of_t<_Fn&(_Args&&...)>>())
-       { return !std::__invoke(_M_fn, std::forward<_Args>(__args)...); }
-
-      template<typename... _Args>
-       auto
-       operator()(_Args&&... __args) const &
-       noexcept(__noexcept_cond<const _Fn&, _Args&&...>::value)
-       -> decltype(!std::declval<result_of_t<const _Fn&(_Args&&...)>>())
-       { return !std::__invoke(_M_fn, std::forward<_Args>(__args)...); }
-
-      template<typename... _Args>
-       auto
-       operator()(_Args&&... __args) &&
-       noexcept(__noexcept_cond<_Fn&&, _Args&&...>::value)
-       -> decltype(!std::declval<result_of_t<_Fn&&(_Args&&...)>>())
-       {
-         return !std::__invoke(std::move(_M_fn),
-                               std::forward<_Args>(__args)...);
-       }
-
-      template<typename... _Args>
-       auto
-       operator()(_Args&&... __args) const &&
-       noexcept(__noexcept_cond<const _Fn&&, _Args&&...>::value)
-       -> decltype(!std::declval<result_of_t<const _Fn&&(_Args&&...)>>())
-       {
-         return !std::__invoke(std::move(_M_fn),
-                               std::forward<_Args>(__args)...);
+      // Macro to define operator() with given cv-qualifiers ref-qualifiers,
+      // forwarding _M_fn and the function arguments with the same qualifiers,
+      // and deducing the return type and exception-specification.
+#define _GLIBCXX_NOT_FN_CALL_OP( _QUALS )                              \
+      template<typename... _Args>                                      \
+       decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())           \
+       operator()(_Args&&... __args) _QUALS                            \
+       noexcept(noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \
+       {                                                               \
+         return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn),      \
+                               std::forward<_Args>(__args)...);        \
        }
+      _GLIBCXX_NOT_FN_CALL_OP( & )
+      _GLIBCXX_NOT_FN_CALL_OP( const & )
+      _GLIBCXX_NOT_FN_CALL_OP( && )
+      _GLIBCXX_NOT_FN_CALL_OP( const && )
+#undef _GLIBCXX_NOT_FN_CALL
 
     private:
       _Fn _M_fn;