PR libstdc++/89416 fix alloc insertable trait for clang (again)
authorJonathan Wakely <jwakely@redhat.com>
Tue, 26 Feb 2019 20:34:46 +0000 (20:34 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 26 Feb 2019 20:34:46 +0000 (20:34 +0000)
PR libstdc++/89416
* include/bits/alloc_traits.h (__is_alloc_insertable_impl): Change
to class template and partial specialization using void_t.
(__is_copy_insertable, __is_move_insertable): Adjust base class.

From-SVN: r269229

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/alloc_traits.h

index 1ace579e6256e48fb7ebfb4e3bdd631301e38fd1..d6ae3226effbcfa3a787b5a721b790a1117ca22d 100644 (file)
@@ -1,3 +1,10 @@
+2019-02-26  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/89416
+       * include/bits/alloc_traits.h (__is_alloc_insertable_impl): Change
+       to class template and partial specialization using void_t.
+       (__is_copy_insertable, __is_move_insertable): Adjust base class.
+
 2019-02-24  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/89416
index 9a3d816c42c0b95aeaf06fa54e8ad553e2836556..b8689daf74b7623f2fc820010cf87cb26fa255b6 100644 (file)
@@ -576,32 +576,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __do_alloc_on_swap(__one, __two, __pocs());
     }
 
-  class __is_alloc_insertable_impl
-  {
-    template<typename _Alloc, typename _Up,
-            typename _Tp = __remove_cvref_t<_Up>,
-            typename = decltype(allocator_traits<_Alloc>::construct(
-                  std::declval<_Alloc&>(), std::declval<_Tp*>(),
-                  std::declval<_Up>()))>
-      static true_type
-      _M_select(int);
-
-    template<typename, typename>
-      static false_type
-      _M_select(...);
-
-  public:
-    template<typename _Alloc, typename _Tp = typename _Alloc::value_type>
-      using copy = decltype(_M_select<_Alloc, const _Tp&>(0));
-
-    template<typename _Alloc, typename _Tp = typename _Alloc::value_type>
-      using move = decltype(_M_select<_Alloc, _Tp>(0));
-  };
+  template<typename _Alloc, typename _Tp,
+          typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
+          typename = void>
+    struct __is_alloc_insertable_impl
+    : false_type
+    { };
+
+  template<typename _Alloc, typename _Tp, typename _ValueT>
+    struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
+      __void_t<decltype(allocator_traits<_Alloc>::construct(
+                  std::declval<_Alloc&>(), std::declval<_ValueT*>(),
+                  std::declval<_Tp>()))>>
+    : true_type
+    { };
 
   // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
+  // (might be wrong if _Alloc::construct exists but is not constrained,
+  // i.e. actually trying to use it would still be invalid. Use with caution.)
   template<typename _Alloc>
     struct __is_copy_insertable
-    : __is_alloc_insertable_impl::template copy<_Alloc>
+    : __is_alloc_insertable_impl<_Alloc,
+                                typename _Alloc::value_type const&>::type
     { };
 
   // std::allocator<_Tp> just requires CopyConstructible
@@ -611,9 +607,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { };
 
   // true if _Alloc::value_type is MoveInsertable into containers using _Alloc
+  // (might be wrong if _Alloc::construct exists but is not constrained,
+  // i.e. actually trying to use it would still be invalid. Use with caution.)
   template<typename _Alloc>
     struct __is_move_insertable
-    : __is_alloc_insertable_impl::template move<_Alloc>
+    : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
     { };
 
   // std::allocator<_Tp> just requires MoveConstructible