libstdc++: Implement LWG 3506 for std::priority_queue

The LWG 3506 issue ads allocator-extended versions of the constructors
that take iterator arguments.

Signed-off-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	* include/bits/stl_queue.h (priority_queue): Add
	allocator-extended overloads for constructors taking iterator.
	* testsuite/23_containers/priority_queue/lwg3506.cc: New test.
This commit is contained in:
Jonathan Wakely 2021-05-13 14:30:26 +01:00
parent e79bde6ada
commit 6ccffeb56b
2 changed files with 97 additions and 0 deletions

View File

@ -626,6 +626,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3506. Missing allocator-extended constructors for priority_queue
template<typename _InputIterator, typename _Alloc,
typename = std::_RequireInputIter<_InputIterator>,
typename _Requires = _Uses<_Alloc>>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Alloc& __alloc)
: c(__first, __last, __alloc), comp()
{ std::make_heap(c.begin(), c.end(), comp); }
template<typename _InputIterator, typename _Alloc,
typename = std::_RequireInputIter<_InputIterator>,
typename _Requires = _Uses<_Alloc>>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x, const _Alloc& __alloc)
: c(__first, __last, __alloc), comp(__x)
{ std::make_heap(c.begin(), c.end(), comp); }
template<typename _InputIterator, typename _Alloc,
typename = std::_RequireInputIter<_InputIterator>,
typename _Requires = _Uses<_Alloc>>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x, const _Sequence& __s,
const _Alloc& __alloc)
: c(__s, __alloc), comp(__x)
{
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
template<typename _InputIterator, typename _Alloc,
typename _Requires = _Uses<_Alloc>>
priority_queue(_InputIterator __first, _InputIterator __last,
const _Compare& __x, _Sequence&& __s,
const _Alloc& __alloc)
: c(std::move(__s), __alloc), comp(__x)
{
__glibcxx_requires_valid_range(__first, __last);
c.insert(c.end(), __first, __last);
std::make_heap(c.begin(), c.end(), comp);
}
#endif
/**

View File

@ -0,0 +1,54 @@
// { dg-do run { target c++11 } }
#include <queue>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
void
test_lwg3506()
{
// LWG 3506 Missing allocator-extended constructors for priority_queue
using Alloc = __gnu_test::uneq_allocator<int>;
using Container = std::vector<int, Alloc>;
struct Queue : std::priority_queue<int, Container>
{
using priority_queue::priority_queue;
Alloc get_allocator() const { return c.get_allocator(); }
};
using Compare = Queue::value_compare;
const Alloc a1(1), a2(2), a3(3), a4(4);
const int vals[] = { 5, 3, 9, 1, 7 };
Container cont({ 20, 30, 40 }, Alloc(99));
Queue q1(vals, vals+5, a1);
VERIFY( q1.get_allocator() == a1 );
VERIFY( q1.size() == 5 );
VERIFY( q1.top() == 9 );
Queue q2(vals, vals+5, Compare(), a2);
VERIFY( q2.get_allocator() == a2 );
VERIFY( q2.size() == 5 );
VERIFY( q2.top() == 9 );
Queue q3(vals, vals+5, Compare(), cont, a3);
VERIFY( q3.get_allocator() == a3 );
VERIFY( q3.size() == 8 );
VERIFY( q3.top() == 40 );
Queue q4(vals, vals+5, Compare(), std::move(cont), a4);
VERIFY( q4.get_allocator() == a4 );
VERIFY( q4.size() == 8 );
VERIFY( q4.top() == 40 );
VERIFY( cont.empty() );
}
int main()
{
test_lwg3506();
}