[PATCH] Define macro to simplify std::_Not_fn definition

Jonathan Wakely jwakely@redhat.com
Thu Mar 9 20:40:00 GMT 2017


While updating our C++17 features to add the new std::invoke_result
trait I got annoyed with the repetition in std::_Not_fn, as it makes
it hard to check it's defined correctly. Specifically, we need to
repeat the cv-qualifier and ref-qualifiers in multiple places in each
overload.

This introduces a macro that is expanded with one of "&" or "const &"
or "&&" or "const &&" and so ensures it's used consistently.

This only affects C++17 std::not_fn and std::experimental::not_fn so
I'm committing it now.

	* include/std/functional (_Not_fn): Define macro to simplify
	repetitive function definitions.

Tested powerpc64le-linux, committed to trunk.

-------------- next part --------------
commit 0eb6e44bcabb995d29b5569f27f221dd92027c00
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 9 20:15:55 2017 +0000

    Define macro to simplify std::_Not_fn definition
    
    	* include/std/functional (_Not_fn): Define macro to simplify
    	repetitive function definitions.

diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index ea36dd0..366a7fb 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -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;


More information about the Gcc-patches mailing list