Define __void_t and SFINAE-friendly iterator_traits.
authorJonathan Wakely <jwakely@redhat.com>
Tue, 11 Nov 2014 23:57:35 +0000 (23:57 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 11 Nov 2014 23:57:35 +0000 (23:57 +0000)
* include/std/type_traits (__void_t): Define new alias template.
(_GLIBCXX_HAS_NESTED_TYPE): Redefine using __void_t.
* include/std/functional (_Maybe_get_result_type): Likewise.
* include/bits/stl_iterator_base_types.h (__iterator_traits): Likewise.
* include/bits/uses_allocator.h (__uses_allocator_helper): Likewise.
* testsuite/20_util/bind/ref_neg.cc: Adjust dg-error.
* testsuite/20_util/reference_wrapper/typedefs-3.cc: Adjust to changes
in _GLIBCXX_HAS_NESTED_TYPE.

From-SVN: r217395

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_iterator_base_types.h
libstdc++-v3/include/bits/uses_allocator.h
libstdc++-v3/include/std/functional
libstdc++-v3/include/std/type_traits
libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
libstdc++-v3/testsuite/20_util/reference_wrapper/typedefs-3.cc

index f19aabc7e26fb93f3855ddc4782e49098f001ffc..4a17fd0b9b3fe4ca9171e666f80434a9765eb758 100644 (file)
@@ -1,3 +1,14 @@
+2014-11-11  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/std/type_traits (__void_t): Define new alias template.
+       (_GLIBCXX_HAS_NESTED_TYPE): Redefine using __void_t.
+       * include/std/functional (_Maybe_get_result_type): Likewise.
+       * include/bits/stl_iterator_base_types.h (__iterator_traits): Likewise.
+       * include/bits/uses_allocator.h (__uses_allocator_helper): Likewise.
+       * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error.
+       * testsuite/20_util/reference_wrapper/typedefs-3.cc: Adjust to changes
+       in _GLIBCXX_HAS_NESTED_TYPE.
+
 2014-11-11  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/std/functional (_Mem_fn_traits): Add partial specializations
index bd559874381369ae1f7355a76f55287967aceca8..ba3f92322780395e54f84459357fd3144c22d7b2 100644 (file)
@@ -64,7 +64,7 @@
 #include <bits/c++config.h>
 
 #if __cplusplus >= 201103L
-# include <type_traits>  // For _GLIBCXX_HAS_NESTED_TYPE, is_convertible
+# include <type_traits>  // For __void_t, is_convertible
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -138,15 +138,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  provide tighter, more correct semantics.
   */
 #if __cplusplus >= 201103L
-
-_GLIBCXX_HAS_NESTED_TYPE(iterator_category)
-
-  template<typename _Iterator,
-          bool = __has_iterator_category<_Iterator>::value>
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2408. SFINAE-friendly common_type/iterator_traits is missing in C++14
+  template<typename _Iterator, typename = __void_t<>>
     struct __iterator_traits { };
 
   template<typename _Iterator>
-    struct __iterator_traits<_Iterator, true>
+    struct __iterator_traits<_Iterator,
+                            __void_t<typename _Iterator::iterator_category,
+                                     typename _Iterator::value_type,
+                                     typename _Iterator::difference_type,
+                                     typename _Iterator::pointer,
+                                     typename _Iterator::reference>>
     {
       typedef typename _Iterator::iterator_category iterator_category;
       typedef typename _Iterator::value_type        value_type;
index 7281508fc06e40899c8d7ec576592d41aaec6e13..a50ce10a5ca5fe9b2bc063970f6509ae6d29f76b 100644 (file)
@@ -40,15 +40,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr allocator_arg_t allocator_arg = allocator_arg_t();
 
-_GLIBCXX_HAS_NESTED_TYPE(allocator_type)
-
-  template<typename _Tp, typename _Alloc,
-          bool = __has_allocator_type<_Tp>::value>
+  template<typename _Tp, typename _Alloc, typename = __void_t<>>
     struct __uses_allocator_helper
     : false_type { };
 
   template<typename _Tp, typename _Alloc>
-    struct __uses_allocator_helper<_Tp, _Alloc, true>
+    struct __uses_allocator_helper<_Tp, _Alloc,
+                                  __void_t<typename _Tp::allocator_type>>
     : is_convertible<_Alloc, typename _Tp::allocator_type>::type
     { };
 
index 92489b7d4b9a7922a2b51940dc529a0db4516e0e..e711350a5dfe8dbf5c86aac6d6cc7d331681e6b4 100644 (file)
@@ -67,24 +67,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _Mem_fn<_Tp _Class::*>
     mem_fn(_Tp _Class::*) noexcept;
 
-_GLIBCXX_HAS_NESTED_TYPE(result_type)
-
   /// If we have found a result_type, extract it.
-  template<bool _Has_result_type, typename _Functor>
+  template<typename _Functor, typename = __void_t<>>
     struct _Maybe_get_result_type
     { };
 
   template<typename _Functor>
-    struct _Maybe_get_result_type<true, _Functor>
+    struct _Maybe_get_result_type<_Functor,
+                                 __void_t<typename _Functor::result_type>>
     { typedef typename _Functor::result_type result_type; };
 
   /**
    *  Base class for any function object that has a weak result type, as
-   *  defined in 3.3/3 of TR1.
+   *  defined in 20.8.2 [func.require] of C++11.
   */
   template<typename _Functor>
     struct _Weak_result_type_impl
-    : _Maybe_get_result_type<__has_result_type<_Functor>::value, _Functor>
+    : _Maybe_get_result_type<_Functor>
     { };
 
   /// Retrieve the result type for a function type.
index cecc7dc2697de995e508aa94ac8381e4b02a0cd6..6b72a3a2a18c2e6627192c5b6f0af9d64e4ca6d6 100644 (file)
@@ -2404,34 +2404,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     using result_of_t = typename result_of<_Tp>::type;
 #endif
 
+  template<typename...> using __void_t = void;
+
   /// @} group metaprogramming
-       
+
   /**
    *  Use SFINAE to determine if the type _Tp has a publicly-accessible
    *  member type _NTYPE.
    */
 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE)                               \
-  template<typename _Tp>                                               \
-    class __has_##_NTYPE##_helper                                      \
-    {                                                                  \
-      template<typename _Up>                                           \
-       struct _Wrap_type                                               \
-       { };                                                            \
-                                                                       \
-      template<typename _Up>                                           \
-       static true_type __test(_Wrap_type<typename _Up::_NTYPE>*);     \
-                                                                       \
-      template<typename _Up>                                           \
-       static false_type __test(...);                                  \
-                                                                       \
-    public:                                                            \
-      typedef decltype(__test<_Tp>(0)) type;                           \
-    };                                                                 \
-                                                                       \
-  template<typename _Tp>                                               \
+  template<typename _Tp, typename = __void_t<>>                                \
     struct __has_##_NTYPE                                              \
-    : public __has_##_NTYPE##_helper                                   \
-                       <typename remove_cv<_Tp>::type>::type           \
+    : false_type                                                       \
+    { };                                                               \
+  template<typename _Tp>                                               \
+    struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>>         \
+    : true_type                                                                \
     { };
 
 _GLIBCXX_END_NAMESPACE_VERSION
index 7810968663d1ead1b7191319e6b6e7118624a826..fde434f2db2ae5bed8a2db79ad7924e105ee5341 100644 (file)
@@ -30,10 +30,10 @@ void test01()
 {
   const int dummy = 0;
   std::bind(&inc, _1)(0);               // { dg-error  "no match" }
-  // { dg-error "rvalue|const" "" { target *-*-* } 1126 }
-  // { dg-error "rvalue|const" "" { target *-*-* } 1140 }
-  // { dg-error "rvalue|const" "" { target *-*-* } 1154 }
-  // { dg-error "rvalue|const" "" { target *-*-* } 1168 }
+  // { dg-error "rvalue|const" "" { target *-*-* } 1125 }
+  // { dg-error "rvalue|const" "" { target *-*-* } 1139 }
+  // { dg-error "rvalue|const" "" { target *-*-* } 1153 }
+  // { dg-error "rvalue|const" "" { target *-*-* } 1167 }
   std::bind(&inc, std::ref(dummy))();  // { dg-error  "no match" }
 }
 
index 7d6a799412715913978290cec81a1aeccd95722f..909b305d9a0fa0f7b4822f5d935c4b8820b8ec81 100644 (file)
@@ -46,8 +46,7 @@ struct S012 : S0, S1, S2 { };
 
 using std::true_type;
 using std::false_type;
-using std::integral_constant;
-using std::remove_cv;
+using std::__void_t;
 
 _GLIBCXX_HAS_NESTED_TYPE(argument_type)
 _GLIBCXX_HAS_NESTED_TYPE(first_argument_type)