More <functional> refactoring. This uses the void_t "detection idiom"
to test for the members, with fewer templates and fewer lines of code.

There are now no more uses of _GLIBCXX_HAS_NESTED_TYPE, so we could
consider removing it from <type_traits>. I find it more
straightforward to use void_t directly.

        * include/std/functional (_Reference_wrapper_base_impl): Remove.
        (_Refwrap_base_arg1, _Refwrap_base_arg2): New helpers using __void_t.
        (_Reference_wrapper_base): Inherit from new helpers.

Tested powerpc64le-linux, committed to trunk.


commit b4a72c015b219874d9327925977352bfe5691109
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Oct 13 21:03:37 2016 +0100

    Simplify reference_wrapper nested typedefs
    
    	* include/std/functional (_Reference_wrapper_base_impl): Remove.
    	(_Refwrap_base_arg1, _Refwrap_base_arg2): New helpers using __void_t.
    	(_Reference_wrapper_base): Inherit from new helpers.

diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 8fc60dc..d39b519 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -207,51 +207,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 #endif
 
-  /**
-   *  Knowing which of unary_function and binary_function _Tp derives
-   *  from, derives from the same and ensures that reference_wrapper
-   *  will have a weak result type. See cases below.
-   */
-  template<bool _Unary, bool _Binary, typename _Tp>
-    struct _Reference_wrapper_base_impl;
-
-  // None of the nested argument types.
-  template<typename _Tp>
-    struct _Reference_wrapper_base_impl<false, false, _Tp>
-    : _Weak_result_type<_Tp>
+  // Detect nested argument_type.
+  template<typename _Tp, typename = __void_t<>>
+    struct _Refwrap_base_arg1
     { };
 
-  // Nested argument_type only.
+  // Nested argument_type.
   template<typename _Tp>
-    struct _Reference_wrapper_base_impl<true, false, _Tp>
-    : _Weak_result_type<_Tp>
+    struct _Refwrap_base_arg1<_Tp,
+			      __void_t<typename _Tp::argument_type>>
     {
       typedef typename _Tp::argument_type argument_type;
     };
 
-  // Nested first_argument_type and second_argument_type only.
+  // Detect nested first_argument_type and second_argument_type.
+  template<typename _Tp, typename = __void_t<>>
+    struct _Refwrap_base_arg2
+    { };
+
+  // Nested first_argument_type and second_argument_type.
   template<typename _Tp>
-    struct _Reference_wrapper_base_impl<false, true, _Tp>
-    : _Weak_result_type<_Tp>
+    struct _Refwrap_base_arg2<_Tp,
+			      __void_t<typename _Tp::first_argument_type,
+				       typename _Tp::second_argument_type>>
     {
       typedef typename _Tp::first_argument_type first_argument_type;
       typedef typename _Tp::second_argument_type second_argument_type;
     };
 
-  // All the nested argument types.
-   template<typename _Tp>
-    struct _Reference_wrapper_base_impl<true, true, _Tp>
-    : _Weak_result_type<_Tp>
-    {
-      typedef typename _Tp::argument_type argument_type;
-      typedef typename _Tp::first_argument_type first_argument_type;
-      typedef typename _Tp::second_argument_type second_argument_type;
-    };
-
-  _GLIBCXX_HAS_NESTED_TYPE(argument_type)
-  _GLIBCXX_HAS_NESTED_TYPE(first_argument_type)
-  _GLIBCXX_HAS_NESTED_TYPE(second_argument_type)
-
   /**
    *  Derives from unary_function or binary_function when it
    *  can. Specializations handle all of the easy cases. The primary
@@ -260,11 +243,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   template<typename _Tp>
     struct _Reference_wrapper_base
-    : _Reference_wrapper_base_impl<
-      __has_argument_type<_Tp>::value,
-      __has_first_argument_type<_Tp>::value
-      && __has_second_argument_type<_Tp>::value,
-      _Tp>
+    : _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp>
     { };
 
   // - a function type (unary)

Reply via email to