diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h --- a/libcxx/include/__memory/allocator_traits.h +++ b/libcxx/include/__memory/allocator_traits.h @@ -349,14 +349,6 @@ } }; -// A version of `allocator_traits` for internal usage that SFINAEs away if the -// given allocator doesn't have a nested `value_type`. This helps avoid hard -// errors when forming implicit deduction guides for a container that has an -// invalid Allocator type. See https://wg21.link/LWGXXXXX. -// TODO(varconst): use the actual link once available. -template -struct _LIBCPP_TEMPLATE_VIS __allocator_traits : allocator_traits<_Alloc> {}; - template struct __rebind_alloc_helper { #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/deque b/libcxx/include/deque --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -915,16 +915,16 @@ __deque_base(const __deque_base& __c); __deque_base& operator=(const __deque_base& __c); public: - typedef _Allocator allocator_type; - typedef allocator_traits __alloc_traits; - typedef typename __alloc_traits::size_type size_type; + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; - typedef _Tp value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; + typedef _Tp value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; static const difference_type __block_size; @@ -1259,20 +1259,20 @@ static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); - typedef __deque_base __base; + typedef __deque_base __base; - typedef typename __base::__alloc_traits __alloc_traits; - typedef typename __base::reference reference; - typedef typename __base::const_reference const_reference; - typedef typename __base::iterator iterator; - typedef typename __base::const_iterator const_iterator; - typedef typename __allocator_traits::size_type size_type; - typedef typename __base::difference_type difference_type; + typedef typename __base::__alloc_traits __alloc_traits; + typedef typename __base::reference reference; + typedef typename __base::const_reference const_reference; + typedef typename __base::iterator iterator; + typedef typename __base::const_iterator const_iterator; + typedef typename __base::size_type size_type; + typedef typename __base::difference_type difference_type; - typedef typename __base::pointer pointer; - typedef typename __base::const_pointer const_pointer; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef typename __base::pointer pointer; + typedef typename __base::const_pointer const_pointer; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; using typename __base::__deque_range; using typename __base::__deque_block_range; @@ -1289,7 +1289,14 @@ explicit deque(size_type __n, const _Allocator& __a); #endif deque(size_type __n, const value_type& __v); - deque(size_type __n, const value_type& __v, const allocator_type& __a); + + template ::value> > + deque(size_type __n, const value_type& __v, const allocator_type& __a) : __base(__a) + { + if (__n > 0) + __append(__n, __v); + } + template deque(_InputIter __f, _InputIter __l, typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0); @@ -1608,14 +1615,6 @@ __append(__n, __v); } -template -deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a) - : __base(__a) -{ - if (__n > 0) - __append(__n, __v); -} - template template deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -186,6 +186,7 @@ #include #include #include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -643,12 +644,12 @@ static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename __allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; typedef typename base::iterator iterator; typedef typename base::const_iterator const_iterator; @@ -669,7 +670,12 @@ explicit forward_list(size_type __n, const allocator_type& __a); #endif forward_list(size_type __n, const value_type& __v); - forward_list(size_type __n, const value_type& __v, const allocator_type& __a); + template ::value>> + forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) + { + insert_after(cbefore_begin(), __n, __v); + } + template forward_list(_InputIterator __f, _InputIterator __l, typename enable_if< @@ -943,14 +949,6 @@ insert_after(cbefore_begin(), __n, __v); } -template -forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v, - const allocator_type& __a) - : base(__a) -{ - insert_after(cbefore_begin(), __n, __v); -} - template template forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -845,24 +845,24 @@ typedef typename base::__link_pointer __link_pointer; public: - typedef _Tp value_type; - typedef _Alloc allocator_type; + typedef _Tp value_type; + typedef _Alloc allocator_type; static_assert((is_same::value), "Invalid allocator::value_type"); - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename __allocator_traits::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::iterator iterator; - typedef typename base::const_iterator const_iterator; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; #if _LIBCPP_STD_VER > 17 - typedef size_type __remove_return_type; + typedef size_type __remove_return_type; #else - typedef void __remove_return_type; + typedef void __remove_return_type; #endif _LIBCPP_INLINE_VISIBILITY @@ -885,7 +885,16 @@ explicit list(size_type __n, const allocator_type& __a); #endif list(size_type __n, const value_type& __x); - list(size_type __n, const value_type& __x, const allocator_type& __a); + template ::value> > + list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) + { +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__insert_c(this); +#endif + for (; __n > 0; --__n) + push_back(__x); + } + template list(_InpIter __f, _InpIter __l, typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); @@ -1241,17 +1250,6 @@ push_back(__x); } -template -list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a) - : base(__a) -{ -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - for (; __n > 0; --__n) - push_back(__x); -} - template template list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -821,7 +821,7 @@ basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG - template ::value, nullptr_t> > + template ::value> > _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); @@ -831,9 +831,15 @@ # endif } - template ::value, nullptr_t> > + template ::value> > _LIBCPP_INLINE_VISIBILITY - basic_string(const _CharT* __s, const _Allocator& __a); + basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__default_init_tag(), __a) { + _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); + __init(__s, traits_type::length(__s)); +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__insert_c(this); +#endif + } #if _LIBCPP_STD_VER > 20 basic_string(nullptr_t) = delete; @@ -846,9 +852,14 @@ _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c); - template ::value, nullptr_t> > + template ::value> > _LIBCPP_INLINE_VISIBILITY - basic_string(size_type __n, _CharT __c, const _Allocator& __a); + basic_string(size_type __n, _CharT __c, const _Allocator& __a) : __r_(__default_init_tag(), __a) { + __init(__n, __c); +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__insert_c(this); +#endif + } basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()); @@ -1887,18 +1898,6 @@ traits_type::assign(__p[__sz], value_type()); } -template -template -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) - : __r_(__default_init_tag(), __a) -{ - _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); - __init(__s, traits_type::length(__s)); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif -} - template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) @@ -2048,17 +2047,6 @@ #endif } -template -template -basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) - : __r_(__default_init_tag(), __a) -{ - __init(__n, __c); -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif -} - template basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -350,23 +350,23 @@ : private __vector_base<_Tp, _Allocator> { private: - typedef __vector_base<_Tp, _Allocator> __base; - typedef allocator<_Tp> __default_allocator_type; + typedef __vector_base<_Tp, _Allocator> __base; + typedef allocator<_Tp> __default_allocator_type; public: - typedef vector __self; - typedef _Tp value_type; - typedef _Allocator allocator_type; - typedef allocator_traits __alloc_traits; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __allocator_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef __wrap_iter iterator; - typedef __wrap_iter const_iterator; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef vector __self; + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef allocator_traits __alloc_traits; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; + typedef __wrap_iter iterator; + typedef __wrap_iter const_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); @@ -395,7 +395,21 @@ explicit vector(size_type __n, const allocator_type& __a); #endif vector(size_type __n, const value_type& __x); - vector(size_type __n, const value_type& __x, const allocator_type& __a); + + template ::value> > + vector(size_type __n, const value_type& __x, const allocator_type& __a) + : __base(__a) + { +#if _LIBCPP_DEBUG_LEVEL == 2 + __get_db()->__insert_c(this); +#endif + if (__n > 0) + { + __vallocate(__n); + __construct_at_end(__n, __x); + } + } + template vector(_InputIterator __first, typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value && @@ -1126,20 +1140,6 @@ } } -template -vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a) - : __base(__a) -{ -#if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__insert_c(this); -#endif - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n, __x); - } -} - template template vector<_Tp, _Allocator>::vector(_InputIterator __first,