Skip to content

Commit

Permalink
Make list::remove/remove_if/unique all return void before C++20; undo…
Browse files Browse the repository at this point in the history
…es that bit of D58332. Thanks to Mikhail Maltsev for pointing this out

llvm-svn: 365261
  • Loading branch information
mclow committed Jul 6, 2019
1 parent 9812668 commit 1ab3fe8
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 33 deletions.
33 changes: 19 additions & 14 deletions libcxx/include/list
Expand Up @@ -129,11 +129,11 @@ public:
void splice(const_iterator position, list&& x, const_iterator first,
const_iterator last);
size_type remove(const value_type& value);
template <class Pred> size_type remove_if(Pred pred);
size_type unique();
size_type remove(const value_type& value); // void before C++20
template <class Pred> size_type remove_if(Pred pred); // void before C++20
size_type unique(); // void before C++20
template <class BinaryPredicate>
size_type unique(BinaryPredicate binary_pred);
size_type unique(BinaryPredicate binary_pred); // void before C++20
void merge(list& x);
void merge(list&& x);
template <class Compare>
Expand Down Expand Up @@ -857,6 +857,11 @@ public:
typedef typename base::const_iterator const_iterator;
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
#if _LIBCPP_STD_VER > 17
typedef size_type __remove_return_type;
#else
typedef void __remove_return_type;
#endif

_LIBCPP_INLINE_VISIBILITY
list()
Expand Down Expand Up @@ -1070,12 +1075,12 @@ public:
void splice(const_iterator __p, list& __c, const_iterator __i);
void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);

size_type remove(const value_type& __x);
template <class _Pred> size_type remove_if(_Pred __pred);
__remove_return_type remove(const value_type& __x);
template <class _Pred> __remove_return_type remove_if(_Pred __pred);
_LIBCPP_INLINE_VISIBILITY
size_type unique() { return unique(__equal_to<value_type>()); }
__remove_return_type unique() { return unique(__equal_to<value_type>()); }
template <class _BinaryPred>
size_type unique(_BinaryPred __binary_pred);
__remove_return_type unique(_BinaryPred __binary_pred);
_LIBCPP_INLINE_VISIBILITY
void merge(list& __c);
#ifndef _LIBCPP_CXX03_LANG
Expand Down Expand Up @@ -2141,7 +2146,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
}

template <class _Tp, class _Alloc>
typename list<_Tp, _Alloc>::size_type
typename list<_Tp, _Alloc>::__remove_return_type
list<_Tp, _Alloc>::remove(const value_type& __x)
{
list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
Expand All @@ -2161,12 +2166,12 @@ list<_Tp, _Alloc>::remove(const value_type& __x)
++__i;
}

return __deleted_nodes.size();
return (__remove_return_type) __deleted_nodes.size();
}

template <class _Tp, class _Alloc>
template <class _Pred>
typename list<_Tp, _Alloc>::size_type
typename list<_Tp, _Alloc>::__remove_return_type
list<_Tp, _Alloc>::remove_if(_Pred __pred)
{
list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
Expand All @@ -2186,12 +2191,12 @@ list<_Tp, _Alloc>::remove_if(_Pred __pred)
++__i;
}

return __deleted_nodes.size();
return (__remove_return_type) __deleted_nodes.size();
}

template <class _Tp, class _Alloc>
template <class _BinaryPred>
typename list<_Tp, _Alloc>::size_type
typename list<_Tp, _Alloc>::__remove_return_type
list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)
{
list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
Expand All @@ -2206,7 +2211,7 @@ list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)
}
}

return __deleted_nodes.size();
return (__remove_return_type) __deleted_nodes.size();
}

template <class _Tp, class _Alloc>
Expand Down
27 changes: 24 additions & 3 deletions libcxx/test/std/containers/sequences/list/list.ops/remove.pass.cpp
Expand Up @@ -8,7 +8,8 @@

// <list>

// void remove(const value_type& value);
// void remove(const value_type& value); // pre-c++20
// size_type remove(const value_type& value); // c++20 and later

#include <list>
#include <cassert>
Expand Down Expand Up @@ -36,8 +37,16 @@ int main(int, char**) {
{
int a1[] = {1, 2, 3, 4};
int a2[] = {1, 2, 4};
std::list<int> c(a1, a1 + 4);
typedef std::list<int> L;
L c(a1, a1 + 4);
#if TEST_STD_VER > 17
assert(c.remove(3) == 1);
ASSERT_SAME_TYPE(L::size_type, decltype(c.remove(3)));
#else
ASSERT_SAME_TYPE(void, decltype(c.remove(3)));
c.remove(3);
#endif

assert(c == std::list<int>(a2, a2 + 3));
}
{ // LWG issue #526
Expand All @@ -53,7 +62,11 @@ int main(int, char**) {
std::list<S> c;
for (int *ip = a1; ip < a1 + 8; ++ip)
c.push_back(S(*ip));
#if TEST_STD_VER > 17
assert(c.remove(c.front()) == 3);
#else
c.remove(c.front());
#endif
std::list<S>::const_iterator it = c.begin();
for (int *ip = a2; ip < a2 + 5; ++ip, ++it) {
assert(it != c.end());
Expand All @@ -67,15 +80,23 @@ int main(int, char**) {
int a1[] = {1, 2, 3, 4};
int a2[] = {1, 2, 4};
List c(a1, a1 + 4, Alloc::create());
assert(c.remove(3) == 1);
#if TEST_STD_VER > 17
assert(c.remove(3) == 1);
#else
c.remove(3);
#endif
assert(c == List(a2, a2 + 3, Alloc::create()));
}
#if TEST_STD_VER >= 11
{
int a1[] = {1, 2, 3, 4};
int a2[] = {1, 2, 4};
std::list<int, min_allocator<int>> c(a1, a1 + 4);
#if TEST_STD_VER > 17
assert(c.remove(3) == 1);
#else
c.remove(3);
#endif
assert((c == std::list<int, min_allocator<int>>(a2, a2 + 3)));
}
#endif
Expand Down
Expand Up @@ -8,7 +8,8 @@

// <list>

// template <class Pred> void remove_if(Pred pred);
// template <class Pred> void remove_if(Pred pred); // before C++20
// template <class Pred> size_type remove_if(Pred pred); // c++20 and later

#include <list>
#include <cassert>
Expand All @@ -28,10 +29,10 @@ 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_; }
struct PredLWG526 {
PredLWG526 (int i) : i_(i) {};
~PredLWG526() { i_ = -32767; }
bool operator() (const PredLWG526 &p) const { return p.i_ == i_; }

bool operator==(int i) const { return i == i_;}
int i_;
Expand All @@ -44,9 +45,16 @@ int main(int, char**)
{
int a1[] = {1, 2, 3, 4};
int a2[] = {3, 4};
std::list<int> c(a1, a1+4);
typedef std::list<int> L;
L c(a1, a1+4);
Predicate cp(g);
#if TEST_STD_VER > 17
ASSERT_SAME_TYPE(L::size_type, decltype(c.remove_if(std::ref(cp))));
assert(c.remove_if(std::ref(cp)) == 2);
#else
ASSERT_SAME_TYPE(void, decltype(c.remove_if(std::ref(cp))));
c.remove_if(std::ref(cp));
#endif
assert(c == std::list<int>(a2, a2+2));
assert(cp.count() == 4);
}
Expand All @@ -55,14 +63,18 @@ int main(int, char**)
int a2[] = {1, 3};
std::list<int> c(a1, a1+4);
Predicate cp(even);
#if TEST_STD_VER > 17
assert(c.remove_if(std::ref(cp)) == 2);
#else
c.remove_if(std::ref(cp));
#endif
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);
std::list<PredLWG526> c(a1, a1 + 7);
c.remove_if(std::ref(c.front()));
assert(c.size() == 5);
for (size_t i = 0; i < c.size(); ++i)
Expand All @@ -78,7 +90,11 @@ int main(int, char**)
int a2[] = {3, 4};
std::list<int, min_allocator<int>> c(a1, a1+4);
Predicate cp(g);
#if TEST_STD_VER > 17
assert(c.remove_if(std::ref(cp)) == 2);
#else
c.remove_if(std::ref(cp));
#endif
assert((c == std::list<int, min_allocator<int>>(a2, a2+2)));
assert(cp.count() == 4);
}
Expand Down
16 changes: 14 additions & 2 deletions libcxx/test/std/containers/sequences/list/list.ops/unique.pass.cpp
Expand Up @@ -8,7 +8,8 @@

// <list>

// void unique();
// void unique(); // before C++20
// size_type unique(); // C++20 and later

#include <list>
#include <cassert>
Expand All @@ -21,16 +22,27 @@ int main(int, char**)
{
int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
int a2[] = {2, 1, 4, 3};
std::list<int> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
typedef std::list<int> L;
L c(a1, a1+sizeof(a1)/sizeof(a1[0]));
#if TEST_STD_VER > 17
ASSERT_SAME_TYPE(L::size_type, decltype(c.unique()));
assert(c.unique() == 5);
#else
ASSERT_SAME_TYPE(void, decltype(c.unique()));
c.unique();
#endif
assert(c == std::list<int>(a2, a2+4));
}
#if TEST_STD_VER >= 11
{
int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
int a2[] = {2, 1, 4, 3};
std::list<int, min_allocator<int>> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
#if TEST_STD_VER > 17
assert(c.unique() == 5);
#else
c.unique();
#endif
assert((c == std::list<int, min_allocator<int>>(a2, a2+4)));
}
#endif
Expand Down
Expand Up @@ -8,7 +8,8 @@

// <list>

// template <class BinaryPred> void unique(BinaryPred pred);
// template <class BinaryPred> void unique(BinaryPred pred); // before C++20
// template <class BinaryPred> size_type unique(BinaryPred pred); // C++20 and later

#include <list>
#include <cassert>
Expand All @@ -21,10 +22,10 @@ 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_; }
struct PredLWG526 {
PredLWG526 (int i) : i_(i) {};
~PredLWG526() { i_ = -32767; }
bool operator() (const PredLWG526 &lhs, const PredLWG526 &rhs) const { return lhs.i_ == rhs.i_; }

bool operator==(int i) const { return i == i_;}
int i_;
Expand All @@ -35,16 +36,27 @@ int main(int, char**)
{
int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
int a2[] = {2, 1, 4, 3};
std::list<int> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
typedef std::list<int> L;
L c(a1, a1+sizeof(a1)/sizeof(a1[0]));
#if TEST_STD_VER > 17
ASSERT_SAME_TYPE(L::size_type, decltype(c.unique(g)));
assert(c.unique(g) == 5);
#else
ASSERT_SAME_TYPE(void, decltype(c.unique(g)));
c.unique(g);
#endif
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);
std::list<PredLWG526> c(a1, a1 + 9);
#if TEST_STD_VER > 17
assert(c.unique(std::ref(c.front())) == 3);
#else
c.unique(std::ref(c.front()));
#endif
assert(c.size() == 6);
for (size_t i = 0; i < c.size(); ++i)
{
Expand All @@ -58,7 +70,11 @@ int main(int, char**)
int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
int a2[] = {2, 1, 4, 3};
std::list<int, min_allocator<int>> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
#if TEST_STD_VER > 17
assert(c.unique(g) == 5);
#else
c.unique(g);
#endif
assert((c == std::list<int, min_allocator<int>>(a2, a2+4)));
}
#endif
Expand Down

0 comments on commit 1ab3fe8

Please sign in to comment.