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 -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 false_type -__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args); +__has_allocator_construct_test(const _Alloc&, _Pointer&&, _Args&& ...); template -struct __has_construct - : integral_constant(), - 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 +using __alloc_construct_tag = typename + conditional< + __has_allocator_construct<_Alloc, _Tp*, _Args...>::value, + integral_constant, + __lazy_conditional< + is_constructible<_Tp, _Args...>, + integral_constant, + integral_constant + > + >::type::type; + +template +using __is_alloc_constructible = integral_constant::value != 0 +>; + +template +inline _LIBCPP_INLINE_VISIBILITY +void __alloc_construct_imp(integral_constant, _Alloc&& __a, _Tp* __p, _Args&&... __args) { + _VSTD::forward<_Alloc>(__a).construct(__p, _VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __alloc_construct_imp(integral_constant, _Alloc&&, _Tp* __p, _Args&&... __args) { + ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...); +} + +template +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 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 -struct __has_construct - : false_type -{ -}; +template +struct __has_allocator_construct : false_type {}; -#else // _LIBCPP_HAS_NO_VARIADICS - -template -struct __has_construct - : false_type -{ -}; - -#endif // _LIBCPP_HAS_NO_VARIADICS +template +struct __is_alloc_constructible : true_type {}; template struct __has_destroy @@ -1437,7 +1459,7 @@ { }; -#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE +#endif // _LIBCPP_CXX03_LANG template ::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 - _LIBCPP_INLINE_VISIBILITY - static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args) - {__construct(__has_construct(), - __a, __p, _VSTD::forward<_Args>(__args)...);} + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if<__is_alloc_constructible::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 _LIBCPP_INLINE_VISIBILITY @@ -1530,7 +1554,7 @@ { ::new ((void*)__p) _Tp(__a0, __a1, __a2); } -#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY @@ -1564,7 +1588,7 @@ typename enable_if < (is_same >::value - || !__has_construct::value) && + || !__has_allocator_construct::value) && is_trivially_move_constructible<_Tp>::value, void >::type @@ -1594,7 +1618,7 @@ typename enable_if < (is_same >::value - || !__has_construct::value) && + || !__has_allocator_construct::value) && is_trivially_move_constructible<_Tp>::value, void >::type @@ -1628,7 +1652,7 @@ typename enable_if < (is_same >::value - || !__has_construct::value) && + || !__has_allocator_construct::value) && is_trivially_move_constructible<_Tp>::value, void >::type @@ -1652,16 +1676,7 @@ {return __a.allocate(__n);} #ifndef _LIBCPP_HAS_NO_VARIADICS - template - _LIBCPP_INLINE_VISIBILITY - static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args) - {__a.construct(__p, _VSTD::forward<_Args>(__args)...);} - template - _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 @@ -1740,12 +1755,11 @@ {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) template - _LIBCPP_INLINE_VISIBILITY - void - construct(_Up* __p, _Args&&... __args) - { + _LIBCPP_INLINE_VISIBILITY + typename enable_if::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 - _LIBCPP_INLINE_VISIBILITY - void - construct(_Up* __p, _Args&&... __args) - { + _LIBCPP_INLINE_VISIBILITY + typename enable_if::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 Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -410,6 +410,9 @@ template struct _LIBCPP_TYPE_VIS_ONLY conditional {typedef _Then type;}; +template +struct _LIBCPP_TYPE_VIS_ONLY __lazy_conditional : conditional<_Pred::value, _If, _Then> {}; + #if _LIBCPP_STD_VER > 11 template using conditional_t = typename conditional<_Bp, _If, _Then>::type; #endif