EricWF created this revision.
EricWF added a reviewer: mclow.lists.
EricWF added a subscriber: cfe-commits.

Example Usage: To check the `EmplaceConstructible` Container requirement you 
would ask:

`__is_alloc_constructible<allocator_type&, value_type, Args...>::value` 

http://reviews.llvm.org/D22255

Files:
  include/memory
  include/type_traits

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,29 +1318,62 @@
 
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
 
-#if !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+#if !defined(_LIBCPP_CXX03_LANG)
 
 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(_VSTD::forward<_Alloc>(__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);
+__has_allocator_construct_test(const _Alloc&, _Pointer&&, _Args&& ...);
 
 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(_VSTD::__has_allocator_construct_test(
+                                            _VSTD::declval<_Alloc>(),
+                                            _VSTD::declval<_Pointer>(),
+                                            _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<
+            is_constructible<_Tp, _Args...>,
+            integral_constant<int, 2>,
+            integral_constant<int, 0>
+        >
+    >::type::type;
+
+template <class _Alloc, class _Tp, class ..._Args>
+using __is_alloc_constructible = integral_constant<bool,
+    __alloc_construct_tag<_Alloc, _Tp, _Args...>::value != 0
+>;
+
+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) {
+    _VSTD::forward<_Alloc>(__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) {
+    _VSTD::__alloc_construct_imp(__alloc_construct_tag<_Alloc, _Tp, _Args...>(),
+        _VSTD::forward<_Alloc>(__a), __p, _VSTD::forward<_Args>(__args)...);
+}
+
 template <class _Alloc, class _Pointer>
 auto
 __has_destroy_test(_Alloc&& __a, _Pointer&& __p)
@@ -1399,25 +1432,14 @@
 {
 };
 
-#else  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#else  // _LIBCPP_CXX03_LANG
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-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 {};
 
-#else  // _LIBCPP_HAS_NO_VARIADICS
-
-template <class _Alloc, class _Pointer, class _Args>
-struct __has_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
@@ -1437,7 +1459,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 +1519,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) {
+        _VSTD::__alloc_construct(__a, __p, _VSTD::forward<_Args>(__args)...);
+    }
 #else  // _LIBCPP_HAS_NO_VARIADICS
     template <class _Tp>
         _LIBCPP_INLINE_VISIBILITY
@@ -1530,7 +1554,7 @@
             {
                 ::new ((void*)__p) _Tp(__a0, __a1, __a2);
             }
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_CXX03_LANG
 
     template <class _Tp>
         _LIBCPP_INLINE_VISIBILITY
@@ -1564,7 +1588,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 +1618,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 +1652,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
@@ -1652,16 +1676,7 @@
         {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>
@@ -1740,12 +1755,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 +1850,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