forked from OSchip/llvm-project
Make forward_list::remove/remove_if/unique all return void before C++20; undoes that bit of D58332. Thanks to Mikhail Maltsev for pointing this out
llvm-svn: 365290
This commit is contained in:
parent
d3bbc06ac7
commit
f814dcbafb
|
@ -120,10 +120,12 @@ public:
|
|||
const_iterator first, const_iterator last);
|
||||
void splice_after(const_iterator p, forward_list&& x,
|
||||
const_iterator first, const_iterator last);
|
||||
size_type remove(const value_type& v);
|
||||
template <class Predicate> size_type remove_if(Predicate pred);
|
||||
size_type unique();
|
||||
template <class BinaryPredicate> size_type unique(BinaryPredicate binary_pred);
|
||||
size_type remove(const value_type& v); // void before C++20
|
||||
template <class Predicate>
|
||||
size_type remove_if(Predicate pred); // void before C++20
|
||||
size_type unique(); // void before C++20
|
||||
template <class BinaryPredicate>
|
||||
size_type unique(BinaryPredicate binary_pred); // void before C++20
|
||||
void merge(forward_list& x);
|
||||
void merge(forward_list&& x);
|
||||
template <class Compare> void merge(forward_list& x, Compare comp);
|
||||
|
@ -647,6 +649,11 @@ public:
|
|||
|
||||
typedef typename base::iterator iterator;
|
||||
typedef typename base::const_iterator const_iterator;
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
typedef size_type __remove_return_type;
|
||||
#else
|
||||
typedef void __remove_return_type;
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
forward_list()
|
||||
|
@ -819,11 +826,11 @@ public:
|
|||
void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
|
||||
void splice_after(const_iterator __p, forward_list& __x,
|
||||
const_iterator __f, const_iterator __l);
|
||||
size_type remove(const value_type& __v);
|
||||
template <class _Predicate> size_type remove_if(_Predicate __pred);
|
||||
__remove_return_type remove(const value_type& __v);
|
||||
template <class _Predicate> __remove_return_type remove_if(_Predicate __pred);
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_type unique() {return unique(__equal_to<value_type>());}
|
||||
template <class _BinaryPredicate> size_type unique(_BinaryPredicate __binary_pred);
|
||||
__remove_return_type unique() {return unique(__equal_to<value_type>());}
|
||||
template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred);
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
|
||||
|
@ -1496,7 +1503,7 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
|
|||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
typename forward_list<_Tp, _Alloc>::size_type
|
||||
typename forward_list<_Tp, _Alloc>::__remove_return_type
|
||||
forward_list<_Tp, _Alloc>::remove(const value_type& __v)
|
||||
{
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
|
@ -1519,12 +1526,12 @@ forward_list<_Tp, _Alloc>::remove(const value_type& __v)
|
|||
++__i;
|
||||
}
|
||||
|
||||
return __count_removed;
|
||||
return (__remove_return_type) __count_removed;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
template <class _Predicate>
|
||||
typename forward_list<_Tp, _Alloc>::size_type
|
||||
typename forward_list<_Tp, _Alloc>::__remove_return_type
|
||||
forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
|
||||
{
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
|
@ -1547,12 +1554,12 @@ forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
|
|||
++__i;
|
||||
}
|
||||
|
||||
return __count_removed;
|
||||
return (__remove_return_type) __count_removed;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
template <class _BinaryPredicate>
|
||||
typename forward_list<_Tp, _Alloc>::size_type
|
||||
typename forward_list<_Tp, _Alloc>::__remove_return_type
|
||||
forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
|
||||
{
|
||||
forward_list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing
|
||||
|
@ -1567,7 +1574,7 @@ forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
|
|||
__i = __j;
|
||||
}
|
||||
|
||||
return __count_removed;
|
||||
return (__remove_return_type) __count_removed;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
|
|
|
@ -129,11 +129,12 @@ public:
|
|||
void splice(const_iterator position, list&& x, const_iterator first,
|
||||
const_iterator last);
|
||||
|
||||
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
|
||||
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); // void before C++20
|
||||
size_type unique(BinaryPredicate binary_pred); // void before C++20
|
||||
void merge(list& x);
|
||||
void merge(list&& x);
|
||||
template <class Compare>
|
||||
|
@ -858,9 +859,9 @@ public:
|
|||
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;
|
||||
typedef size_type __remove_return_type;
|
||||
#else
|
||||
typedef void __remove_return_type;
|
||||
typedef void __remove_return_type;
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
// <forward_list>
|
||||
|
||||
// void remove(const value_type& v);
|
||||
// void remove(const value_type& v); // C++17 and before
|
||||
// size_type remove(const value_type& v); // C++20 and after
|
||||
|
||||
#include <forward_list>
|
||||
#include <iterator>
|
||||
|
@ -17,6 +18,21 @@
|
|||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
template <class L>
|
||||
void do_remove(L &l, const typename L::value_type &value, typename L::size_type expected)
|
||||
{
|
||||
typename L::size_type old_size = std::distance(l.begin(), l.end());
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_SAME_TYPE(decltype(l.remove(value)), typename L::size_type);
|
||||
assert(l.remove(value) == expected);
|
||||
#else
|
||||
ASSERT_SAME_TYPE(decltype(l.remove(value)), void);
|
||||
l.remove(value);
|
||||
#endif
|
||||
assert(old_size - std::distance(l.begin(), l.end()) == expected);
|
||||
}
|
||||
|
||||
|
||||
struct S {
|
||||
S(int i) : i_(new int(i)) {}
|
||||
S(const S &rhs) : i_(new int(*rhs.i_)) {}
|
||||
|
@ -37,7 +53,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 5, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(0) == 4);
|
||||
do_remove(c1, 0, 4);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -46,7 +62,7 @@ int main(int, char**)
|
|||
const T t1[] = {0, 0, 0, 0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2;
|
||||
assert(c1.remove(0) == 4);
|
||||
do_remove(c1, 0, 4);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -56,7 +72,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 5, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(0) == 0);
|
||||
do_remove(c1, 0, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -64,7 +80,7 @@ int main(int, char**)
|
|||
typedef std::forward_list<T> C;
|
||||
C c1;
|
||||
C c2;
|
||||
assert(c1.remove(0) == 0);
|
||||
do_remove(c1, 0, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -74,7 +90,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 5, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(0) == 1);
|
||||
do_remove(c1, 0, 1);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{ // LWG issue #526
|
||||
|
@ -84,7 +100,7 @@ int main(int, char**)
|
|||
int t2[] = { 2, 3, 5, 8, 11};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(c1.front()) == 2);
|
||||
do_remove(c1, c1.front(), 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -95,7 +111,7 @@ int main(int, char**)
|
|||
C c;
|
||||
for(int *ip = std::end(t1); ip != std::begin(t1);)
|
||||
c.push_front(S(*--ip));
|
||||
assert(c.remove(c.front()) == 3);
|
||||
do_remove(c, c.front(), 3);
|
||||
C::const_iterator it = c.begin();
|
||||
for(int *ip = std::begin(t2); ip != std::end(t2); ++ip, ++it) {
|
||||
assert ( it != c.end());
|
||||
|
@ -111,7 +127,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 5, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(0) == 4);
|
||||
do_remove(c1, 0, 4);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -120,7 +136,7 @@ int main(int, char**)
|
|||
const T t1[] = {0, 0, 0, 0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2;
|
||||
assert(c1.remove(0) == 4);
|
||||
do_remove(c1, 0, 4);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -130,7 +146,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 5, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(0) == 0);
|
||||
do_remove(c1, 0, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -138,7 +154,7 @@ int main(int, char**)
|
|||
typedef std::forward_list<T, min_allocator<T>> C;
|
||||
C c1;
|
||||
C c2;
|
||||
assert(c1.remove(0) == 0);
|
||||
do_remove(c1, 0, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -148,7 +164,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 5, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.remove(0) == 1);
|
||||
do_remove(c1, 0, 1);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
// <forward_list>
|
||||
|
||||
// template <class Predicate> void remove_if(Predicate pred);
|
||||
// template <class Predicate> void remove_if(Predicate pred); // C++17 and before
|
||||
// template <class Predicate> size_type remove_if(Predicate pred); // C++20 and after
|
||||
|
||||
#include <forward_list>
|
||||
#include <iterator>
|
||||
|
@ -20,15 +21,29 @@
|
|||
#include "counting_predicates.hpp"
|
||||
|
||||
|
||||
template <class L, class Predicate>
|
||||
void do_remove_if(L &l, Predicate pred, typename L::size_type expected)
|
||||
{
|
||||
typename L::size_type old_size = std::distance(l.begin(), l.end());
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_SAME_TYPE(decltype(l.remove_if(pred)), typename L::size_type);
|
||||
assert(l.remove_if(pred) == expected);
|
||||
#else
|
||||
ASSERT_SAME_TYPE(decltype(l.remove_if(pred)), void);
|
||||
l.remove_if(pred);
|
||||
#endif
|
||||
assert(old_size - std::distance(l.begin(), l.end()) == expected);
|
||||
}
|
||||
|
||||
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_;
|
||||
|
@ -45,7 +60,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 4);
|
||||
do_remove_if(c1, std::ref(cp), 4);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -57,7 +72,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2;
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 4);
|
||||
do_remove_if(c1, std::ref(cp), 4);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -70,7 +85,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 0);
|
||||
do_remove_if(c1, std::ref(cp), 0);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -81,7 +96,7 @@ int main(int, char**)
|
|||
C c1;
|
||||
C c2;
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 0);
|
||||
do_remove_if(c1, std::ref(cp), 0);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == 0);
|
||||
}
|
||||
|
@ -94,7 +109,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 1);
|
||||
do_remove_if(c1, std::ref(cp), 1);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -102,8 +117,8 @@ int main(int, char**)
|
|||
{ // 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()));
|
||||
std::forward_list<PredLWG526> c(a1, a1 + 7);
|
||||
do_remove_if(c, std::ref(c.front()), 2);
|
||||
for (size_t i = 0; i < 5; ++i)
|
||||
{
|
||||
assert(!c.empty());
|
||||
|
@ -123,7 +138,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 4);
|
||||
do_remove_if(c1, std::ref(cp), 4);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -135,7 +150,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2;
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 4);
|
||||
do_remove_if(c1, std::ref(cp), 4);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -148,7 +163,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 0);
|
||||
do_remove_if(c1, std::ref(cp), 0);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
@ -159,7 +174,7 @@ int main(int, char**)
|
|||
C c1;
|
||||
C c2;
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 0);
|
||||
do_remove_if(c1, std::ref(cp), 0);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == 0);
|
||||
}
|
||||
|
@ -172,7 +187,7 @@ int main(int, char**)
|
|||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
Predicate cp(g);
|
||||
assert(c1.remove_if(std::ref(cp)) == 1);
|
||||
do_remove_if(c1, std::ref(cp), 1);
|
||||
assert(c1 == c2);
|
||||
assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
// <forward_list>
|
||||
|
||||
// void unique();
|
||||
// void unique(); // C++17 and before
|
||||
// size_type unique(); // C++20 and after
|
||||
|
||||
#include <forward_list>
|
||||
#include <iterator>
|
||||
|
@ -17,6 +18,20 @@
|
|||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
template <class L>
|
||||
void do_unique(L &l, typename L::size_type expected)
|
||||
{
|
||||
typename L::size_type old_size = std::distance(l.begin(), l.end());
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_SAME_TYPE(decltype(l.unique()), typename L::size_type);
|
||||
assert(l.unique() == expected);
|
||||
#else
|
||||
ASSERT_SAME_TYPE(decltype(l.unique()), void);
|
||||
l.unique();
|
||||
#endif
|
||||
assert(old_size - std::distance(l.begin(), l.end()) == expected);
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
|
@ -26,7 +41,7 @@ int main(int, char**)
|
|||
const T t2[] = {0, 5, 0, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 3);
|
||||
do_unique(c1, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -36,7 +51,7 @@ int main(int, char**)
|
|||
const T t2[] = {0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 3);
|
||||
do_unique(c1, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -46,7 +61,7 @@ int main(int, char**)
|
|||
const T t2[] = {5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 2);
|
||||
do_unique(c1, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -54,7 +69,7 @@ int main(int, char**)
|
|||
typedef std::forward_list<T> C;
|
||||
C c1;
|
||||
C c2;
|
||||
assert(c1.unique() == 0);
|
||||
do_unique(c1, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -64,7 +79,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 2);
|
||||
do_unique(c1, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
#if TEST_STD_VER >= 11
|
||||
|
@ -75,7 +90,7 @@ int main(int, char**)
|
|||
const T t2[] = {0, 5, 0, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 3);
|
||||
do_unique(c1, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -85,7 +100,7 @@ int main(int, char**)
|
|||
const T t2[] = {0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 3);
|
||||
do_unique(c1, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -95,7 +110,7 @@ int main(int, char**)
|
|||
const T t2[] = {5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 2);
|
||||
do_unique(c1, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -103,7 +118,7 @@ int main(int, char**)
|
|||
typedef std::forward_list<T, min_allocator<T>> C;
|
||||
C c1;
|
||||
C c2;
|
||||
assert(c1.unique() == 0);
|
||||
do_unique(c1, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -113,7 +128,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
assert(c1.unique() == 2);
|
||||
do_unique(c1, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
// <forward_list>
|
||||
|
||||
// template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
|
||||
// template <class BinaryPredicate> void unique(BinaryPredicate binary_pred); // C++17 and before
|
||||
// template <class BinaryPredicate> size_type unique(BinaryPredicate binary_pred); // C++20 and after
|
||||
|
||||
#include <forward_list>
|
||||
#include <iterator>
|
||||
|
@ -17,10 +18,25 @@
|
|||
#include "test_macros.h"
|
||||
#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_; }
|
||||
template <class L, class Predicate>
|
||||
void do_unique(L &l, Predicate pred, typename L::size_type expected)
|
||||
{
|
||||
typename L::size_type old_size = std::distance(l.begin(), l.end());
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_SAME_TYPE(decltype(l.unique(pred)), typename L::size_type);
|
||||
assert(l.unique(pred) == expected);
|
||||
#else
|
||||
ASSERT_SAME_TYPE(decltype(l.unique(pred)), void);
|
||||
l.unique(pred);
|
||||
#endif
|
||||
assert(old_size - std::distance(l.begin(), l.end()) == expected);
|
||||
}
|
||||
|
||||
|
||||
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_;
|
||||
|
@ -41,7 +57,7 @@ int main(int, char**)
|
|||
const T t2[] = {0, 5, 0, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -51,7 +67,7 @@ int main(int, char**)
|
|||
const T t2[] = {0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -61,7 +77,7 @@ int main(int, char**)
|
|||
const T t2[] = {5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -69,7 +85,7 @@ int main(int, char**)
|
|||
typedef std::forward_list<T> C;
|
||||
C c1;
|
||||
C c2;
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -79,22 +95,22 @@ int main(int, char**)
|
|||
const T t2[] = {5, 0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 2);
|
||||
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()));
|
||||
std::forward_list<PredLWG526> c1(a1, a1 + 8);
|
||||
do_unique(c1, std::ref(c1.front()), 2);
|
||||
for (size_t i = 0; i < 6; ++i)
|
||||
{
|
||||
assert(!c.empty());
|
||||
assert(c.front() == a2[i]);
|
||||
c.pop_front();
|
||||
assert(!c1.empty());
|
||||
assert(c1.front() == a2[i]);
|
||||
c1.pop_front();
|
||||
}
|
||||
assert(c.empty());
|
||||
assert(c1.empty());
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
|
@ -105,7 +121,7 @@ int main(int, char**)
|
|||
const T t2[] = {0, 5, 0, 5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -115,7 +131,7 @@ int main(int, char**)
|
|||
const T t2[] = {0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 3);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -125,7 +141,7 @@ int main(int, char**)
|
|||
const T t2[] = {5};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -133,7 +149,7 @@ int main(int, char**)
|
|||
typedef std::forward_list<T, min_allocator<T>> C;
|
||||
C c1;
|
||||
C c2;
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 0);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
{
|
||||
|
@ -143,7 +159,7 @@ int main(int, char**)
|
|||
const T t2[] = {5, 0};
|
||||
C c1(std::begin(t1), std::end(t1));
|
||||
C c2(std::begin(t2), std::end(t2));
|
||||
c1.unique(g);
|
||||
do_unique(c1, g, 2);
|
||||
assert(c1 == c2);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue