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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits