forked from OSchip/llvm-project
Fix list/forward_list implementations of remove_if and unique to deal with predicates that are part of the sequence passed in. We already do this for remove.
llvm-svn: 358534
This commit is contained in:
parent
b2930b8631
commit
896b0c7b99
|
@ -1505,7 +1505,7 @@ template <class _Tp, class _Alloc>
|
|||
void
|
||||
forward_list<_Tp, _Alloc>::remove(const value_type& __v)
|
||||
{
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
iterator __e = end();
|
||||
for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
|
||||
{
|
||||
|
@ -1529,6 +1529,7 @@ template <class _Predicate>
|
|||
void
|
||||
forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
|
||||
{
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
iterator __e = end();
|
||||
for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;)
|
||||
{
|
||||
|
@ -1537,7 +1538,7 @@ forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
|
|||
iterator __j = _VSTD::next(__i, 2);
|
||||
for (; __j != __e && __pred(*__j); ++__j)
|
||||
;
|
||||
erase_after(__i, __j);
|
||||
__deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
|
||||
if (__j == __e)
|
||||
break;
|
||||
__i = __j;
|
||||
|
@ -1552,13 +1553,14 @@ template <class _BinaryPredicate>
|
|||
void
|
||||
forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
|
||||
{
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
for (iterator __i = begin(), __e = end(); __i != __e;)
|
||||
{
|
||||
iterator __j = _VSTD::next(__i);
|
||||
for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
|
||||
;
|
||||
if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer())
|
||||
erase_after(__i, __j);
|
||||
__deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
|
||||
__i = __j;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2167,6 +2167,7 @@ template <class _Pred>
|
|||
void
|
||||
list<_Tp, _Alloc>::remove_if(_Pred __pred)
|
||||
{
|
||||
list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
for (iterator __i = begin(), __e = end(); __i != __e;)
|
||||
{
|
||||
if (__pred(*__i))
|
||||
|
@ -2174,7 +2175,8 @@ list<_Tp, _Alloc>::remove_if(_Pred __pred)
|
|||
iterator __j = _VSTD::next(__i);
|
||||
for (; __j != __e && __pred(*__j); ++__j)
|
||||
;
|
||||
__i = erase(__i, __j);
|
||||
__deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j);
|
||||
__i = __j;
|
||||
if (__i != __e)
|
||||
++__i;
|
||||
}
|
||||
|
@ -2196,13 +2198,16 @@ template <class _BinaryPred>
|
|||
void
|
||||
list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)
|
||||
{
|
||||
list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
for (iterator __i = begin(), __e = end(); __i != __e;)
|
||||
{
|
||||
iterator __j = _VSTD::next(__i);
|
||||
for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
|
||||
;
|
||||
if (++__i != __j)
|
||||
__i = erase(__i, __j);
|
||||
if (++__i != __j) {
|
||||
__deleted_nodes.splice(__deleted_nodes.end(), *this, __i, __j);
|
||||
__i = __j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,15 @@ bool g(int i)
|
|||
return i < 3;
|
||||
}
|
||||
|
||||
struct PredLWG529 {
|
||||
PredLWG529 (int i) : i_(i) {};
|
||||
~PredLWG529() { i_ = -32767; }
|
||||
bool operator() (const PredLWG529 &p) const { return p.i_ == i_; }
|
||||
|
||||
bool operator==(int i) const { return i == i_;}
|
||||
int i_;
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
|
@ -88,6 +97,21 @@ int main(int, char**)
|
|||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
||||
{ // LWG issue #526
|
||||
int a1[] = {1, 2, 1, 3, 5, 8, 11};
|
||||
int a2[] = { 2, 3, 5, 8, 11};
|
||||
std::forward_list<PredLWG529> c(a1, a1 + 7);
|
||||
c.remove_if(std::ref(c.front()));
|
||||
for (size_t i = 0; i < 5; ++i)
|
||||
{
|
||||
assert(!c.empty());
|
||||
assert(c.front() == a2[i]);
|
||||
c.pop_front();
|
||||
}
|
||||
assert(c.empty());
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
typedef int T;
|
||||
|
|
|
@ -16,6 +16,16 @@
|
|||
|
||||
#include "min_allocator.h"
|
||||
|
||||
struct PredLWG529 {
|
||||
PredLWG529 (int i) : i_(i) {};
|
||||
~PredLWG529() { i_ = -32767; }
|
||||
bool operator() (const PredLWG529 &lhs, const PredLWG529 &rhs) const { return lhs.i_ == rhs.i_; }
|
||||
|
||||
bool operator==(int i) const { return i == i_;}
|
||||
int i_;
|
||||
};
|
||||
|
||||
|
||||
bool g(int x, int y)
|
||||
{
|
||||
return x == y;
|
||||
|
@ -71,6 +81,21 @@ int main(int, char**)
|
|||
c1.unique(g);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
|
||||
{ // LWG issue #526
|
||||
int a1[] = {1, 1, 1, 2, 3, 5, 2, 11};
|
||||
int a2[] = {1, 2, 3, 5, 2, 11};
|
||||
std::forward_list<PredLWG529> c(a1, a1 + 8);
|
||||
c.unique(std::ref(c.front()));
|
||||
for (size_t i = 0; i < 6; ++i)
|
||||
{
|
||||
assert(!c.empty());
|
||||
assert(c.front() == a2[i]);
|
||||
c.pop_front();
|
||||
}
|
||||
assert(c.empty());
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
typedef int T;
|
||||
|
|
|
@ -27,6 +27,15 @@ bool g(int i)
|
|||
return i < 3;
|
||||
}
|
||||
|
||||
struct PredLWG529 {
|
||||
PredLWG529 (int i) : i_(i) {};
|
||||
~PredLWG529() { i_ = -32767; }
|
||||
bool operator() (const PredLWG529 &p) const { return p.i_ == i_; }
|
||||
|
||||
bool operator==(int i) const { return i == i_;}
|
||||
int i_;
|
||||
};
|
||||
|
||||
typedef unary_counting_predicate<bool(*)(int), int> Predicate;
|
||||
|
||||
int main(int, char**)
|
||||
|
@ -49,6 +58,19 @@ int main(int, char**)
|
|||
assert(c == std::list<int>(a2, a2+2));
|
||||
assert(cp.count() == 4);
|
||||
}
|
||||
{ // LWG issue #526
|
||||
int a1[] = {1, 2, 1, 3, 5, 8, 11};
|
||||
int a2[] = {2, 3, 5, 8, 11};
|
||||
std::list<PredLWG529> c(a1, a1 + 7);
|
||||
c.remove_if(std::ref(c.front()));
|
||||
assert(c.size() == 5);
|
||||
for (size_t i = 0; i < c.size(); ++i)
|
||||
{
|
||||
assert(c.front() == a2[i]);
|
||||
c.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
int a1[] = {1, 2, 3, 4};
|
||||
|
|
|
@ -20,6 +20,15 @@ bool g(int x, int y)
|
|||
return x == y;
|
||||
}
|
||||
|
||||
struct PredLWG529 {
|
||||
PredLWG529 (int i) : i_(i) {};
|
||||
~PredLWG529() { i_ = -32767; }
|
||||
bool operator() (const PredLWG529 &lhs, const PredLWG529 &rhs) const { return lhs.i_ == rhs.i_; }
|
||||
|
||||
bool operator==(int i) const { return i == i_;}
|
||||
int i_;
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
|
@ -29,6 +38,20 @@ int main(int, char**)
|
|||
c.unique(g);
|
||||
assert(c == std::list<int>(a2, a2+4));
|
||||
}
|
||||
|
||||
{ // LWG issue #526
|
||||
int a1[] = {1, 1, 1, 2, 3, 5, 5, 2, 11};
|
||||
int a2[] = {1, 2, 3, 5, 2, 11};
|
||||
std::list<PredLWG529> c(a1, a1 + 9);
|
||||
c.unique(std::ref(c.front()));
|
||||
assert(c.size() == 6);
|
||||
for (size_t i = 0; i < c.size(); ++i)
|
||||
{
|
||||
assert(c.front() == a2[i]);
|
||||
c.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
|
||||
|
|
Loading…
Reference in New Issue