"`P2212R2 <https://wg21.link/P2212R2>`__","LWG","Relax Requirements for time_point::clock","February 2021","",""
"`P2259R1 <https://wg21.link/P2259R1>`__","LWG","Repairing input range adaptors and counted_iterator","February 2021","",""
"","","","","",""
+"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
+"","","","","",""
deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
deque(const deque& __c);
- deque(const deque& __c, const allocator_type& __a);
+ deque(const deque& __c, const __identity_t<allocator_type>& __a);
deque& operator=(const deque& __c);
_LIBCPP_INLINE_VISIBILITY
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
_LIBCPP_INLINE_VISIBILITY
- deque(deque&& __c, const allocator_type& __a);
+ deque(deque&& __c, const __identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
deque& operator=(deque&& __c)
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
}
template <class _Tp, class _Allocator>
-deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
+deque<_Tp, _Allocator>::deque(const deque& __c, const __identity_t<allocator_type>& __a)
: __base(__a)
{
__append(__c.begin(), __c.end());
template <class _Tp, class _Allocator>
inline
-deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
+deque<_Tp, _Allocator>::deque(deque&& __c, const __identity_t<allocator_type>& __a)
: __base(_VSTD::move(__c), __a)
{
if (__a != __c.__alloc())
__is_cpp17_input_iterator<_InputIterator>::value
>::type* = nullptr);
forward_list(const forward_list& __x);
- forward_list(const forward_list& __x, const allocator_type& __a);
+ forward_list(const forward_list& __x, const __identity_t<allocator_type>& __a);
forward_list& operator=(const forward_list& __x);
forward_list(forward_list&& __x)
_NOEXCEPT_(is_nothrow_move_constructible<base>::value)
: base(_VSTD::move(__x)) {}
- forward_list(forward_list&& __x, const allocator_type& __a);
+ forward_list(forward_list&& __x, const __identity_t<allocator_type>& __a);
forward_list(initializer_list<value_type> __il);
forward_list(initializer_list<value_type> __il, const allocator_type& __a);
template <class _Tp, class _Alloc>
forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
- const allocator_type& __a)
+ const __identity_t<allocator_type>& __a)
: base(__a)
{
insert_after(cbefore_begin(), __x.begin(), __x.end());
#ifndef _LIBCPP_CXX03_LANG
template <class _Tp, class _Alloc>
forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
- const allocator_type& __a)
+ const __identity_t<allocator_type>& __a)
: base(_VSTD::move(__x), __a)
{
if (base::__alloc() != __x.__alloc())
typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
list(const list& __c);
- list(const list& __c, const allocator_type& __a);
+ list(const list& __c, const __identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
list& operator=(const list& __c);
#ifndef _LIBCPP_CXX03_LANG
list(list&& __c)
_NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
_LIBCPP_INLINE_VISIBILITY
- list(list&& __c, const allocator_type& __a);
+ list(list&& __c, const __identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
list& operator=(list&& __c)
_NOEXCEPT_(
}
template <class _Tp, class _Alloc>
-list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a)
+list<_Tp, _Alloc>::list(const list& __c, const __identity_t<allocator_type>& __a)
: base(__a)
{
#if _LIBCPP_DEBUG_LEVEL == 2
template <class _Tp, class _Alloc>
inline
-list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)
+list<_Tp, _Alloc>::list(list&& __c, const __identity_t<allocator_type>& __a)
: base(__a)
{
#if _LIBCPP_DEBUG_LEVEL == 2
template<class _Container,
class _Alloc,
class = _EnableIf<!__is_allocator<_Container>::value>,
- class = _EnableIf<__is_allocator<_Alloc>::value>
+ class = _EnableIf<uses_allocator<_Container, _Alloc>::value>
>
queue(_Container, _Alloc)
-> queue<typename _Container::value_type, _Container>;
class _Alloc,
class = _EnableIf<!__is_allocator<_Compare>::value>,
class = _EnableIf<!__is_allocator<_Container>::value>,
- class = _EnableIf<__is_allocator<_Alloc>::value>
+ class = _EnableIf<uses_allocator<_Container, _Alloc>::value>
>
priority_queue(_Compare, _Container, _Alloc)
-> priority_queue<typename _Container::value_type, _Container, _Compare>;
template<class _Container,
class _Alloc,
class = _EnableIf<!__is_allocator<_Container>::value>,
- class = _EnableIf<__is_allocator<_Alloc>::value>
+ class = _EnableIf<uses_allocator<_Container, _Alloc>::value>
>
stack(_Container, _Alloc)
-> stack<typename _Container::value_type, _Container>;
}
vector(const vector& __x);
- vector(const vector& __x, const allocator_type& __a);
+ vector(const vector& __x, const __identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(const vector& __x);
#endif
_LIBCPP_INLINE_VISIBILITY
- vector(vector&& __x, const allocator_type& __a);
+ vector(vector&& __x, const __identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __x)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
}
template <class _Tp, class _Allocator>
-vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a)
+vector<_Tp, _Allocator>::vector(const vector& __x, const __identity_t<allocator_type>& __a)
: __base(__a)
{
#if _LIBCPP_DEBUG_LEVEL == 2
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
-vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)
+vector<_Tp, _Allocator>::vector(vector&& __x, const __identity_t<allocator_type>& __a)
: __base(__a)
{
#if _LIBCPP_DEBUG_LEVEL == 2
#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
#endif
- vector(vector&& __v, const allocator_type& __a);
+ vector(vector&& __v, const __identity_t<allocator_type>& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __v)
_NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
}
template <class _Allocator>
-vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
+vector<bool, _Allocator>::vector(vector&& __v, const __identity_t<allocator_type>& __a)
: __begin_(nullptr),
__size_(0),
__cap_alloc_(0, __a)
assert(m.get_allocator().get_id() == 45);
}
+ {
+ // Examples from LWG3025
+ std::map m{std::pair{1, 1}, {2, 2}, {3, 3}};
+ ASSERT_SAME_TYPE(decltype(m), std::map<int, int>);
+
+ std::map m2{m.begin(), m.end()};
+ ASSERT_SAME_TYPE(decltype(m2), std::map<int, int>);
+ }
+
+ {
+ // Examples from LWG3531
+ std::map m1{{std::pair{1, 2}, {3, 4}}, std::less<int>()};
+ ASSERT_SAME_TYPE(decltype(m1), std::map<int, int>);
+
+ using value_type = std::pair<const int, int>;
+ std::map m2{{value_type{1, 2}, {3, 4}}, std::less<int>()};
+ ASSERT_SAME_TYPE(decltype(m2), std::map<int, int>);
+ }
+
return 0;
}
assert(m.get_allocator().get_id() == 45);
}
+ {
+ // Examples from LWG3025
+ std::multimap m{std::pair{1, 1}, {2, 2}, {3, 3}};
+ ASSERT_SAME_TYPE(decltype(m), std::multimap<int, int>);
+
+ std::multimap m2{m.begin(), m.end()};
+ ASSERT_SAME_TYPE(decltype(m2), std::multimap<int, int>);
+ }
+
+ {
+ // Examples from LWG3531
+ std::multimap m1{{std::pair{1, 2}, {3, 4}}, std::less<int>()};
+ ASSERT_SAME_TYPE(decltype(m1), std::multimap<int, int>);
+
+ using value_type = std::pair<const int, int>;
+ std::multimap m2{{value_type{1, 2}, {3, 4}}, std::less<int>()};
+ ASSERT_SAME_TYPE(decltype(m2), std::multimap<int, int>);
+ }
+
return 0;
}
}
{
-// This one is odd - you can pass an allocator in to use, but the allocator
-// has to match the type of the one used by the underlying container
- typedef long double T;
- typedef std::greater<T> Comp;
- typedef test_allocator<T> Alloc;
- typedef std::deque<T, Alloc> Cont;
-
- Cont c{2,3,0,1};
- std::priority_queue<T, Cont, Comp> source(Comp(), c);
- std::priority_queue pri(source, Alloc(2)); // queue(queue &, allocator)
- static_assert(std::is_same_v<decltype(pri)::value_type, T>, "");
- static_assert(std::is_same_v<decltype(pri)::container_type, Cont>, "");
- assert(pri.size() == 4);
- assert(pri.top() == 0);
+ typedef short T;
+ typedef std::greater<T> Comp;
+ typedef test_allocator<T> Alloc;
+ typedef std::deque<T, Alloc> Cont;
+ typedef test_allocator<int> ConvertibleToAlloc;
+ static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
+ !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
+
+ {
+ Comp comp;
+ Cont cont;
+ std::priority_queue pri(comp, cont, Alloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+
+ {
+ Comp comp;
+ Cont cont;
+ std::priority_queue pri(comp, cont, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+
+ {
+ Comp comp;
+ Cont cont;
+ std::priority_queue pri(comp, std::move(cont), Alloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+
+ {
+ Comp comp;
+ Cont cont;
+ std::priority_queue pri(comp, std::move(cont), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+ }
+
+ {
+ typedef short T;
+ typedef std::greater<T> Comp;
+ typedef test_allocator<T> Alloc;
+ typedef std::deque<T, Alloc> Cont;
+ typedef test_allocator<int> ConvertibleToAlloc;
+ static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
+ !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
+
+ {
+ std::priority_queue<T, Cont, Comp> source;
+ std::priority_queue pri(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+
+ {
+ std::priority_queue<T, Cont, Comp> source;
+ std::priority_queue pri(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+
+ {
+ std::priority_queue<T, Cont, Comp> source;
+ std::priority_queue pri(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
+
+ {
+ std::priority_queue<T, Cont, Comp> source;
+ std::priority_queue pri(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(pri), std::priority_queue<T, Cont, Comp>>);
+ }
}
- return 0;
+ return 0;
}
}
{
-// This one is odd - you can pass an allocator in to use, but the allocator
-// has to match the type of the one used by the underlying container
- typedef short T;
- typedef test_allocator<T> Alloc;
- typedef std::deque<T, Alloc> Container;
-
- Container c{0,1,2,3};
- std::queue<T, Container> source(c);
- std::queue que(source, Alloc(2)); // queue(queue &, allocator)
- static_assert(std::is_same_v<decltype(que)::value_type, T>, "");
- static_assert(std::is_same_v<decltype(que)::container_type, Container>, "");
- assert(que.size() == 4);
- assert(que.back() == 3);
+ typedef short T;
+ typedef test_allocator<T> Alloc;
+ typedef std::list<T, Alloc> Cont;
+ typedef test_allocator<int> ConvertibleToAlloc;
+ static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
+ !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
+
+ {
+ Cont cont;
+ std::queue que(cont, Alloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+
+ {
+ Cont cont;
+ std::queue que(cont, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+
+ {
+ Cont cont;
+ std::queue que(std::move(cont), Alloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+
+ {
+ Cont cont;
+ std::queue que(std::move(cont), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
}
+ {
+ typedef short T;
+ typedef test_allocator<T> Alloc;
+ typedef std::list<T, Alloc> Cont;
+ typedef test_allocator<int> ConvertibleToAlloc;
+ static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
+ !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
+
+ {
+ std::queue<T, Cont> source;
+ std::queue que(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+
+ {
+ std::queue<T, Cont> source;
+ std::queue que(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+
+ {
+ std::queue<T, Cont> source;
+ std::queue que(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+
+ {
+ std::queue<T, Cont> source;
+ std::queue que(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(que), std::queue<T, Cont>>);
+ }
+ }
- return 0;
+ return 0;
}
#include <stack>
+#include <deque>
#include <vector>
#include <list>
#include <iterator>
}
{
-// This one is odd - you can pass an allocator in to use, but the allocator
-// has to match the type of the one used by the underlying container
- typedef short T;
- typedef test_allocator<T> Alloc;
- typedef std::deque<T, Alloc> Container;
-
- Container c{0,1,2,3};
- std::stack<T, Container> source(c);
- std::stack stk(source, Alloc(2)); // stack(stack &, allocator)
- static_assert(std::is_same_v<decltype(stk)::value_type, T>, "");
- static_assert(std::is_same_v<decltype(stk)::container_type, Container>, "");
- assert(stk.size() == 4);
- assert(stk.top() == 3);
+ typedef short T;
+ typedef test_allocator<T> Alloc;
+ typedef std::list<T, Alloc> Cont;
+ typedef test_allocator<int> ConvertibleToAlloc;
+ static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
+ !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
+
+ {
+ Cont cont;
+ std::stack stk(cont, Alloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+
+ {
+ Cont cont;
+ std::stack stk(cont, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+
+ {
+ Cont cont;
+ std::stack stk(std::move(cont), Alloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+
+ {
+ Cont cont;
+ std::stack stk(std::move(cont), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
}
+ {
+ typedef short T;
+ typedef test_allocator<T> Alloc;
+ typedef std::list<T, Alloc> Cont;
+ typedef test_allocator<int> ConvertibleToAlloc;
+ static_assert(std::uses_allocator_v<Cont, ConvertibleToAlloc> &&
+ !std::is_same_v<typename Cont::allocator_type, ConvertibleToAlloc>);
+
+ {
+ std::stack<T, Cont> source;
+ std::stack stk(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+
+ {
+ std::stack<T, Cont> source;
+ std::stack stk(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+
+ {
+ std::stack<T, Cont> source;
+ std::stack stk(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+
+ {
+ std::stack<T, Cont> source;
+ std::stack stk(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(stk), std::stack<T, Cont>>);
+ }
+ }
- return 0;
+ return 0;
}
//
//===----------------------------------------------------------------------===//
-// <array>
+// <deque>
// UNSUPPORTED: c++03, c++11, c++14
// UNSUPPORTED: libcpp-no-deduction-guides
assert(deq.size() == 0);
}
- return 0;
+ {
+ typedef test_allocator<short> Alloc;
+ typedef test_allocator<int> ConvertibleToAlloc;
+
+ {
+ std::deque<short, Alloc> source;
+ std::deque deq(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(deq), decltype(source)>);
+ }
+
+ {
+ std::deque<short, Alloc> source;
+ std::deque deq(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(deq), decltype(source)>);
+ }
+
+ {
+ std::deque<short, Alloc> source;
+ std::deque deq(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(deq), decltype(source)>);
+ }
+
+ {
+ std::deque<short, Alloc> source;
+ std::deque deq(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(deq), decltype(source)>);
+ }
+ }
+
+ return 0;
}
// template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
-// deque(InputIterator, InputIterator, Allocator = Allocator())
-// -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
+// forward_list(InputIterator, InputIterator, Allocator = Allocator())
+// -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;
//
assert(std::distance(fwl.begin(), fwl.end()) == 0); // no size for forward_list
}
- return 0;
+ {
+ typedef test_allocator<short> Alloc;
+ typedef test_allocator<int> ConvertibleToAlloc;
+
+ {
+ std::forward_list<short, Alloc> source;
+ std::forward_list fwl(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(fwl), decltype(source)>);
+ }
+
+ {
+ std::forward_list<short, Alloc> source;
+ std::forward_list fwl(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(fwl), decltype(source)>);
+ }
+
+ {
+ std::forward_list<short, Alloc> source;
+ std::forward_list fwl(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(fwl), decltype(source)>);
+ }
+
+ {
+ std::forward_list<short, Alloc> source;
+ std::forward_list fwl(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(fwl), decltype(source)>);
+ }
+ }
+
+ return 0;
}
assert(lst.size() == 0);
}
- return 0;
+ {
+ typedef test_allocator<short> Alloc;
+ typedef test_allocator<int> ConvertibleToAlloc;
+
+ {
+ std::list<short, Alloc> source;
+ std::list lst(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(lst), decltype(source)>);
+ }
+
+ {
+ std::list<short, Alloc> source;
+ std::list lst(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(lst), decltype(source)>);
+ }
+
+ {
+ std::list<short, Alloc> source;
+ std::list lst(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(lst), decltype(source)>);
+ }
+
+ {
+ std::list<short, Alloc> source;
+ std::list lst(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(lst), decltype(source)>);
+ }
+ }
+
+ return 0;
}
// template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
-// deque(InputIterator, InputIterator, Allocator = Allocator())
-// -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
+// vector(InputIterator, InputIterator, Allocator = Allocator())
+// -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
//
assert(vec.size() == 0);
}
- return 0;
+ {
+ typedef test_allocator<short> Alloc;
+ typedef test_allocator<int> ConvertibleToAlloc;
+
+ {
+ std::vector<short, Alloc> source;
+ std::vector vec(source, Alloc(2));
+ static_assert(std::is_same_v<decltype(vec), decltype(source)>);
+ }
+
+ {
+ std::vector<short, Alloc> source;
+ std::vector vec(source, ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(vec), decltype(source)>);
+ }
+
+ {
+ std::vector<short, Alloc> source;
+ std::vector vec(std::move(source), Alloc(2));
+ static_assert(std::is_same_v<decltype(vec), decltype(source)>);
+ }
+
+ {
+ std::vector<short, Alloc> source;
+ std::vector vec(std::move(source), ConvertibleToAlloc(2));
+ static_assert(std::is_same_v<decltype(vec), decltype(source)>);
+ }
+ }
+
+ return 0;
}
assert(m.get_allocator().get_id() == 48);
}
+ {
+ // Examples from LWG3025
+ std::unordered_map m{std::pair{1, 1}, {2, 2}, {3, 3}};
+ ASSERT_SAME_TYPE(decltype(m), std::unordered_map<int, int>);
+
+ std::unordered_map m2{m.begin(), m.end()};
+ ASSERT_SAME_TYPE(decltype(m2), std::unordered_map<int, int>);
+ }
+
+ {
+ // Examples from LWG3531
+ std::unordered_map m1{{std::pair{1, 2}, {3, 4}}, 0};
+ ASSERT_SAME_TYPE(decltype(m1), std::unordered_map<int, int>);
+
+ using value_type = std::pair<const int, int>;
+ std::unordered_map m2{{value_type{1, 2}, {3, 4}}, 0};
+ ASSERT_SAME_TYPE(decltype(m2), std::unordered_map<int, int>);
+ }
+
return 0;
}
assert(m.get_allocator().get_id() == 48);
}
+ {
+ // Examples from LWG3025
+ std::unordered_multimap m{std::pair{1, 1}, {2, 2}, {3, 3}};
+ ASSERT_SAME_TYPE(decltype(m), std::unordered_multimap<int, int>);
+
+ std::unordered_multimap m2{m.begin(), m.end()};
+ ASSERT_SAME_TYPE(decltype(m2), std::unordered_multimap<int, int>);
+ }
+
+ {
+ // Examples from LWG3531
+ std::unordered_multimap m1{{std::pair{1, 2}, {3, 4}}, 0};
+ ASSERT_SAME_TYPE(decltype(m1), std::unordered_multimap<int, int>);
+
+ using value_type = std::pair<const int, int>;
+ std::unordered_multimap m2{{value_type{1, 2}, {3, 4}}, 0};
+ ASSERT_SAME_TYPE(decltype(m2), std::unordered_multimap<int, int>);
+ }
+
return 0;
}