EricWF updated this revision to Diff 63635.
EricWF added a comment.

- Don't use `is_constructible` in the `__is_alloc_constructible` 
implementation. `is_constructible<T, ...>` requires  `is_destructible<T>`, but 
that isn't required within allocators.  Instead this trait checks the validity 
of the placement new expression.

- Add tests for `__is_alloc_constructible`. Not complete but a good start.

- Implement sample changes to `<vector>` that fix PR28412 
(https://llvm.org/bugs/show_bug.cgi?id=28412). See 
`tagging_allocator_instantation.pass.cpp` for the example test.


http://reviews.llvm.org/D22255

Files:
  include/memory
  include/type_traits
  include/vector
  
test/libcxx/utilities/memory/allocator.traits/__is_alloc_constructible.pass.cpp
  test/libcxx/utilities/memory/allocator.traits/vector_instant.pass.cpp
  test/support/tagging_allocator.hpp

Index: test/support/tagging_allocator.hpp
===================================================================
--- /dev/null
+++ test/support/tagging_allocator.hpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TAGGING_ALLOCATOR_HPP
+#define TAGGING_ALLOCATOR_HPP
+
+# include <cstdlib>
+# include <cassert>
+# include <new>
+
+#include "test_macros.h"
+struct Tag { };
+
+template<typename T>
+  class TaggingAllocator
+  {
+  public:
+    using value_type = T;
+
+    TaggingAllocator() = default;
+
+    template<typename U>
+      TaggingAllocator(const TaggingAllocator<U>&) { }
+
+    T*
+    allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }
+
+    void
+    deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); }
+
+    template<typename U, typename... Args>
+
+      auto construct(U* p, Args&&... args) ->
+        decltype((void)::new((void*)p) U(Tag{}, std::forward<Args>(args)...))
+      { ::new((void*)p) U(Tag{}, std::forward<Args>(args)...); }
+
+    template<typename U, typename... Args>
+    auto destroy(U* p) -> decltype((void)p->~U()) { p->~U(); }
+  };
+
+template<typename T, typename U>
+  bool
+  operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
+  { return true; }
+
+template<typename T, typename U>
+  bool
+  operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&)
+  { return false; }
+
+template <class ...Args>
+struct TaggedValueType
+{
+  // All constructors must be passed the Tag type.
+
+  // DefaultInsertable into vector<X, TaggingAllocator<X>>,
+  explicit TaggedValueType(Tag) { }
+  // CopyInsertable into vector<X, TaggingAllocator<X>>,
+  TaggedValueType(Tag, const TaggedValueType&) { }
+  // MoveInsertable into vector<X, TaggingAllocator<X>>, and
+  TaggedValueType(Tag, TaggedValueType&&) { }
+
+  // EmplaceConstructible into vector<X, TaggingAllocator<X>> from args.
+  explicit TaggedValueType(Tag, Args...) { }
+
+  // not DefaultConstructible, CopyConstructible or MoveConstructible.
+  TaggedValueType() = delete;
+  TaggedValueType(const TaggedValueType&) = delete;
+  TaggedValueType(TaggedValueType&&) = delete;
+
+  // CopyAssignable.
+  TaggedValueType& operator=(const TaggedValueType&) { return *this; }
+
+  // MoveAssignable.
+  TaggedValueType& operator=(TaggedValueType&&) { return *this; }
+
+private:
+  // Not Destructible.
+  ~TaggedValueType() { }
+
+  // Erasable from vector<X, TaggingAllocator<X>>.
+  template <class T>
+  friend class TaggingAllocator;
+};
+
+
+template <>
+struct TaggedValueType<>
+{
+  // All constructors must be passed the Tag type.
+
+  // DefaultInsertable into vector<X, TaggingAllocator<X>>,
+  explicit TaggedValueType(Tag) { }
+  // CopyInsertable into vector<X, TaggingAllocator<X>>,
+  TaggedValueType(Tag, const TaggedValueType&) { }
+  // MoveInsertable into vector<X, TaggingAllocator<X>>, and
+  TaggedValueType(Tag, TaggedValueType&&) { }
+
+  // not DefaultConstructible, CopyConstructible or MoveConstructible.
+  TaggedValueType() = delete;
+  TaggedValueType(const TaggedValueType&) = delete;
+  TaggedValueType(TaggedValueType&&) = delete;
+
+  // CopyAssignable.
+  TaggedValueType& operator=(const TaggedValueType&) { return *this; }
+
+  // MoveAssignable.
+  TaggedValueType& operator=(TaggedValueType&&) { return *this; }
+
+private:
+  // Not Destructible.
+  ~TaggedValueType() { }
+
+  // Erasable from vector<X, TaggingAllocator<X>>.
+  template <class T>
+  friend class TaggingAllocator;
+};
+
+#endif /* TAGGING_ALLOCATOR_HPP */
Index: test/libcxx/utilities/memory/allocator.traits/vector_instant.pass.cpp
===================================================================
--- /dev/null
+++ test/libcxx/utilities/memory/allocator.traits/vector_instant.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <memory>
+
+
+#include <vector>
+#include "tagging_allocator.hpp"
+
+using VT = TaggedValueType<int>;
+using Alloc = TaggingAllocator<VT>;
+
+template class std::vector<VT, Alloc>;
+
+int main() {
+
+}
\ No newline at end of file
Index: test/libcxx/utilities/memory/allocator.traits/__is_alloc_constructible.pass.cpp
===================================================================
--- /dev/null
+++ test/libcxx/utilities/memory/allocator.traits/__is_alloc_constructible.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <memory>
+
+// template <class Alloc, class T, class ...Args>
+// struct __is_alloc_constructible;
+
+#include <memory>
+#include "tagging_allocator.hpp"
+
+template <class ...Args>
+struct ConstructibleFrom {
+  explicit ConstructibleFrom(Args...) {}
+};
+
+void test_std_allocator() {
+    {
+        using A = std::allocator<char*>; // value_type different than constructed type
+
+        static_assert(std::__is_alloc_constructible<A&, int>::value, "");
+
+        static_assert(std::__is_alloc_constructible<A&, int, int>::value, "");
+
+        static_assert(std::__is_alloc_constructible<A&, int, int const&>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int&&>::value, "");
+        static_assert(!std::__is_alloc_constructible<A&, int, char*>::value,
+                      "bad argument");
+        static_assert(!std::__is_alloc_constructible<A&, int, int, int>::value,
+                      "too many arguments");
+        A a;
+        int x = 101;
+        const int cx = -1;
+        int dummy;
+        a.construct(&dummy);
+        assert(dummy == 0);
+        a.construct(&dummy, 42);
+        assert(dummy == 42);
+        a.construct(&dummy, x);
+        assert(dummy == x);
+        a.construct(&dummy, cx);
+        assert(dummy == cx);
+    }
+    {
+        using A = std::allocator<int>;
+        static_assert(std::__is_alloc_constructible<A&, int>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int const&>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int&&>::value, "");
+        static_assert(!std::__is_alloc_constructible<A&, int, char*>::value,
+                      "bad argument");
+        static_assert(!std::__is_alloc_constructible<A&, int, int, int>::value,
+                      "too many arguments");
+        A a;
+        int x = 101;
+        const int cx = -1;
+        int dummy;
+        a.construct(&dummy);
+        assert(dummy == 0);
+        a.construct(&dummy, 42);
+        assert(dummy == 42);
+        a.construct(&dummy, x);
+        assert(dummy == x);
+        a.construct(&dummy, cx);
+        assert(dummy == cx);
+    }
+    {
+        using A = std::allocator<const int>;
+        static_assert(std::__is_alloc_constructible<A&, int>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int const&>::value, "");
+        static_assert(std::__is_alloc_constructible<A&, int, int&&>::value, "");
+        static_assert(!std::__is_alloc_constructible<A&, int, char*>::value,
+                      "bad argument");
+        static_assert(!std::__is_alloc_constructible<A&, int, int, int>::value,
+                      "too many arguments");
+        A a;
+        int x = 101;
+        const int cx = -1;
+        int dummy;
+        a.construct(&dummy);
+        assert(dummy == 0);
+        a.construct(&dummy, 42);
+        assert(dummy == 42);
+        a.construct(&dummy, x);
+        assert(dummy == x);
+        a.construct(&dummy, cx);
+        assert(dummy == cx);
+    }
+}
+
+void test_allocator_traits_tagged_alloc() {
+    using VT = TaggedValueType<int>;
+    using A = TaggingAllocator<VT>;
+    A a;
+    VT* ptr = (VT*)std::malloc(sizeof(VT));
+    a.construct(ptr);
+    a.destroy(ptr);
+    static_assert(std::__has_allocator_construct<A, VT*>::value, "");
+    static_assert(std::__is_alloc_constructible<A, VT>::value, "");
+    static_assert(std::__is_alloc_destructible<A, VT>::value, "");
+    static_assert(!std::is_constructible<VT, Tag>::value,
+                  "is_constructible<T> requires is_destructible<T>, which is not true");
+}
+
+int main()
+{
+    test_std_allocator();
+    test_allocator_traits_tagged_alloc();
+}
Index: include/vector
===================================================================
--- include/vector
+++ include/vector
@@ -576,7 +576,8 @@
         <
              __is_input_iterator  <_InputIterator>::value &&
             !__is_forward_iterator<_InputIterator>::value &&
-            is_constructible<
+            __is_alloc_constructible<
+                 allocator_type,
                  value_type,
                  typename iterator_traits<_InputIterator>::reference>::value,
             void
@@ -586,7 +587,8 @@
         typename enable_if
         <
             __is_forward_iterator<_ForwardIterator>::value &&
-            is_constructible<
+            __is_alloc_constructible<
+                 allocator_type,
                  value_type,
                  typename iterator_traits<_ForwardIterator>::reference>::value,
             void
@@ -707,7 +709,8 @@
         <
              __is_input_iterator  <_InputIterator>::value &&
             !__is_forward_iterator<_InputIterator>::value &&
-            is_constructible<
+            __is_alloc_constructible<
+                 allocator_type,
                  value_type,
                  typename iterator_traits<_InputIterator>::reference>::value,
             iterator
@@ -717,7 +720,8 @@
         typename enable_if
         <
             __is_forward_iterator<_ForwardIterator>::value &&
-            is_constructible<
+            __is_alloc_constructible<
+                 allocator_type,
                  value_type,
                  typename iterator_traits<_ForwardIterator>::reference>::value,
             iterator
@@ -1364,7 +1368,8 @@
 <
      __is_input_iterator  <_InputIterator>::value &&
     !__is_forward_iterator<_InputIterator>::value &&
-    is_constructible<
+    __is_alloc_constructible<
+      _Allocator,
        _Tp,
        typename iterator_traits<_InputIterator>::reference>::value,
     void
@@ -1381,7 +1386,8 @@
 typename enable_if
 <
     __is_forward_iterator<_ForwardIterator>::value &&
-    is_constructible<
+    __is_alloc_constructible<
+        _Allocator,
        _Tp,
        typename iterator_traits<_ForwardIterator>::reference>::value,
     void
@@ -1881,8 +1887,8 @@
 <
      __is_input_iterator  <_InputIterator>::value &&
     !__is_forward_iterator<_InputIterator>::value &&
-    is_constructible<
-       _Tp,
+    __is_alloc_constructible<
+       _Allocator, _Tp,
        typename iterator_traits<_InputIterator>::reference>::value,
     typename vector<_Tp, _Allocator>::iterator
 >::type
@@ -1938,8 +1944,8 @@
 typename enable_if
 <
     __is_forward_iterator<_ForwardIterator>::value &&
-    is_constructible<
-       _Tp,
+    __is_alloc_constructible<
+       _Allocator, _Tp,
        typename iterator_traits<_ForwardIterator>::reference>::value,
     typename vector<_Tp, _Allocator>::iterator
 >::type
Index: include/type_traits
===================================================================
--- include/type_traits
+++ include/type_traits
@@ -410,6 +410,9 @@
 template <class _If, class _Then>
     struct _LIBCPP_TYPE_VIS_ONLY conditional<false, _If, _Then> {typedef _Then type;};
 
+template <class _Pred, class _If, class _Then>
+struct _LIBCPP_TYPE_VIS_ONLY __lazy_conditional : conditional<_Pred::value, _If, _Then> {};
+
 #if _LIBCPP_STD_VER > 11
 template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
 #endif
Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -1318,49 +1318,134 @@
 
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
 
-#if !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+#if !defined(_LIBCPP_CXX03_LANG)
+
+namespace __alloc_helpers {
+
+
+template <class _Alloc, class _Pointer>
+auto __has_allocator_destroy_test(_Alloc& __a, _Pointer&& __p)
+    -> decltype(__a.destroy(__p), true_type());
+
+false_type __has_allocator_destroy_test(...);
+
+template <class _Alloc, class _Tp>
+struct __has_allocator_destroy : decltype(__alloc_helpers::__has_allocator_destroy_test(
+                                              _VSTD::declval<_Alloc&>(),
+                                              _VSTD::declval<_Tp*>()))
+{
+};
+
+template <class _Alloc, class _Tp>
+using __alloc_destroy_tag = typename
+    conditional<
+        __has_allocator_destroy<_Alloc, _Tp>::value,
+        integral_constant<int, 1>,
+        __lazy_conditional<
+            is_destructible<_Tp>,
+            integral_constant<int, 2>,
+            integral_constant<int, 0>
+        >
+    >::type::type;
+
+
+template <class _Alloc, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void __alloc_destroy_imp(integral_constant<int, 1>, _Alloc& __a, _Tp* __p) {
+    __a.destroy(__p);
+}
+
+template <class _Alloc, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void __alloc_destroy_imp(integral_constant<int, 2>, _Alloc&, _Tp* __p) {
+    __p->~_Tp();
+}
+
+template <class _Alloc, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void __alloc_destroy(_Alloc& __a, _Tp* __p) {
+    __alloc_helpers::__alloc_destroy_imp(__alloc_destroy_tag<_Alloc, _Tp>(), __a, __p);
+}
 
 template <class _Alloc, class _Tp, class ..._Args>
-decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(),
-                                           _VSTD::declval<_Args>()...),
-                                           true_type())
-__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args);
+auto __has_allocator_construct_test(_Alloc& __a, _Tp* __p, _Args&& ...__args)
+    -> decltype(__a.construct(__p, _VSTD::forward<_Args>(__args)...)
+              , true_type());
 
-template <class _Alloc, class _Pointer, class ..._Args>
-false_type
-__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args);
+false_type __has_allocator_construct_test(...);
 
 template <class _Alloc, class _Pointer, class ..._Args>
-struct __has_construct
-    : integral_constant<bool,
-        is_same<
-            decltype(__has_construct_test(declval<_Alloc>(),
-                                          declval<_Pointer>(),
-                                          declval<_Args>()...)),
-            true_type>::value>
+struct __has_allocator_construct : decltype(__alloc_helpers::__has_allocator_construct_test(
+                                            _VSTD::declval<_Alloc&>(),
+                                            _VSTD::declval<_Pointer>(),
+                                            _VSTD::declval<_Args>()...))
 {
 };
 
-template <class _Alloc, class _Pointer>
-auto
-__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
-    -> decltype(__a.destroy(__p), true_type());
+template <class _Tp, class ..._Args>
+auto __has_placement_new_test(_Tp* __p, _Args&& ...__args)
+    -> decltype(::new((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...)
+              , true_type());
 
-template <class _Alloc, class _Pointer>
-auto
-__has_destroy_test(const _Alloc& __a, _Pointer&& __p)
-    -> false_type;
+false_type __has_placement_new_test(...);
 
-template <class _Alloc, class _Pointer>
-struct __has_destroy
-    : integral_constant<bool,
-        is_same<
-            decltype(__has_destroy_test(declval<_Alloc>(),
-                                        declval<_Pointer>())),
-            true_type>::value>
+template <class _Tp, class ..._Args>
+struct __has_placement_new : decltype(__alloc_helpers::__has_placement_new_test(
+                                            (_Tp*)nullptr,
+                                            _VSTD::declval<_Args>()...))
 {
 };
 
+
+template <class _Alloc, class _Tp, class ..._Args>
+using __alloc_construct_tag = typename
+    conditional<
+        __has_allocator_construct<_Alloc, _Tp*, _Args...>::value,
+        integral_constant<int, 1>,
+        __lazy_conditional<
+            __has_placement_new<_Tp, _Args...>,
+            integral_constant<int, 2>,
+            integral_constant<int, 0>
+        >
+    >::type::type;
+
+
+template <class _Alloc, class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __alloc_construct_imp(integral_constant<int, 1>, _Alloc& __a, _Tp* __p, _Args&&... __args) {
+    __a.construct(__p, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Alloc, class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __alloc_construct_imp(integral_constant<int, 2>, _Alloc&, _Tp* __p, _Args&&... __args) {
+    ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Alloc, class _Tp, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __alloc_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) {
+    __alloc_helpers::__alloc_construct_imp(
+        __alloc_construct_tag<_Alloc, _Tp, _Args...>(),
+        __a, __p, _VSTD::forward<_Args>(__args)...);
+}
+
+
+} // end namespace __alloc_helpers
+
+using __alloc_helpers::__has_allocator_construct;
+
+template <class _Alloc, class _Tp>
+using __is_alloc_destructible = integral_constant<bool,
+    __alloc_helpers::__alloc_destroy_tag<_Alloc, _Tp>::value != 0
+>;
+
+template <class _Alloc, class _Tp, class ..._Args>
+using __is_alloc_constructible = integral_constant<bool,
+    __alloc_helpers::__alloc_construct_tag<_Alloc, _Tp, _Args...>::value != 0 &&
+    __alloc_helpers::__alloc_destroy_tag<_Alloc, _Tp>::value != 0
+>;
+
 template <class _Alloc>
 auto
 __has_max_size_test(_Alloc&& __a)
@@ -1399,28 +1484,17 @@
 {
 };
 
-#else  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
-
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Alloc, class _Pointer, class ..._Args>
-struct __has_construct
-    : false_type
-{
-};
-
-#else  // _LIBCPP_HAS_NO_VARIADICS
+#else  // _LIBCPP_CXX03_LANG
 
-template <class _Alloc, class _Pointer, class _Args>
-struct __has_construct
-    : false_type
-{
-};
+template <class _Alloc, class _Pointer, class _Tp>
+struct __has_allocator_construct : false_type {};
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+template <class _Alloc, class _Pointer,
+          class _T1 = void, class _T2 = void, class _T3 = void>
+struct __is_alloc_constructible : true_type {};
 
 template <class _Alloc, class _Pointer>
-struct __has_destroy
+struct __has_allocator_destroy
     : false_type
 {
 };
@@ -1437,7 +1511,7 @@
 {
 };
 
-#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#endif  // _LIBCPP_CXX03_LANG
 
 template <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>
 struct __alloc_traits_difference_type
@@ -1497,12 +1571,14 @@
     static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT
         {__a.deallocate(__p, __n);}
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#ifndef _LIBCPP_CXX03_LANG
     template <class _Tp, class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-        static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
-            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
-                         __a, __p, _VSTD::forward<_Args>(__args)...);}
+    _LIBCPP_INLINE_VISIBILITY
+    static
+    typename enable_if<__is_alloc_constructible<allocator_type&, _Tp, _Args...>::value>::type
+    construct(allocator_type& __a, _Tp* __p, _Args&&... __args) {
+        __alloc_helpers::__alloc_construct(__a, __p, _VSTD::forward<_Args>(__args)...);
+    }
 #else  // _LIBCPP_HAS_NO_VARIADICS
     template <class _Tp>
         _LIBCPP_INLINE_VISIBILITY
@@ -1530,12 +1606,20 @@
             {
                 ::new ((void*)__p) _Tp(__a0, __a1, __a2);
             }
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_CXX03_LANG
 
+#ifndef _LIBCPP_CXX03_LANG
     template <class _Tp>
-        _LIBCPP_INLINE_VISIBILITY
-        static void destroy(allocator_type& __a, _Tp* __p)
-            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
+    _LIBCPP_INLINE_VISIBILITY static
+    typename enable_if<__is_alloc_destructible<allocator_type, _Tp>::value>::type
+    destroy(allocator_type& __a, _Tp* __p)
+    { __alloc_helpers::__alloc_destroy(__a, __p); }
+#else
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY static
+    static void destroy(allocator_type&, _Tp* __p)
+    { __p->~_Tp(); }
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     static size_type max_size(const allocator_type& __a) _NOEXCEPT
@@ -1564,7 +1648,7 @@
         typename enable_if
         <
             (is_same<allocator_type, allocator<_Tp> >::value
-                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+                || !__has_allocator_construct<allocator_type, _Tp*, _Tp>::value) &&
              is_trivially_move_constructible<_Tp>::value,
             void
         >::type
@@ -1594,7 +1678,7 @@
         typename enable_if
         <
             (is_same<allocator_type, allocator<_Tp> >::value
-                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+                || !__has_allocator_construct<allocator_type, _Tp*, _Tp>::value) &&
              is_trivially_move_constructible<_Tp>::value,
             void
         >::type
@@ -1628,7 +1712,7 @@
         typename enable_if
         <
             (is_same<allocator_type, allocator<_Tp> >::value
-                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+                || !__has_allocator_construct<allocator_type, _Tp*, _Tp>::value) &&
              is_trivially_move_constructible<_Tp>::value,
             void
         >::type
@@ -1651,18 +1735,6 @@
         const_void_pointer, false_type)
         {return __a.allocate(__n);}
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-    template <class _Tp, class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-        static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)
-            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
-    template <class _Tp, class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-        static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)
-            {
-                ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
-            }
-#endif  // _LIBCPP_HAS_NO_VARIADICS
 
     template <class _Tp>
         _LIBCPP_INLINE_VISIBILITY
@@ -1740,12 +1812,11 @@
         {return size_type(~0) / sizeof(_Tp);}
 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
     template <class _Up, class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-        void
-        construct(_Up* __p, _Args&&... __args)
-        {
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<is_constructible<_Up, _Args...>::value>::type
+    construct(_Up* __p, _Args&&... __args) {
             ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
-        }
+    }
 #else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
         _LIBCPP_INLINE_VISIBILITY
         void
@@ -1836,12 +1907,11 @@
         {return size_type(~0) / sizeof(_Tp);}
 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
     template <class _Up, class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-        void
-        construct(_Up* __p, _Args&&... __args)
-        {
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<is_constructible<_Up, _Args...>::value>::type
+    construct(_Up* __p, _Args&&... __args) {
             ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
-        }
+    }
 #else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
         _LIBCPP_INLINE_VISIBILITY
         void
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to