diff --git a/doc/container.qbk b/doc/container.qbk
index a774967..a2f2aea 100644
--- a/doc/container.qbk
+++ b/doc/container.qbk
@@ -1401,6 +1401,7 @@ collect them containers and build [*Boost.Container], a library targeted to a wi
* If available, uses C++17's utilities under the `__cpp_aligned_new` feature.
* Uses alternative aligned allocation functions (`posix_memalign`, `aligned_alloc`, `_aligned_malloc`...) otherwise.
* Implemented overaligned allocation support for `adaptive_pool`and `node_allocator`
+* Changed return type of `erase`/`erase_if`/`unique` members of `list` and `slist` to `size_type` to follow C++20 changes to `std::list`.
* Updated `basic_string`:
* Added missing `string_view` members and updated `operator[]` to be able to return the terminating null.
* Added C++20 `starts_with`/`ends_with` and C++23 `contains` overloads.
diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp
index c1840a3..0a75cb4 100644
--- a/include/boost/container/list.hpp
+++ b/include/boost/container/list.hpp
@@ -1168,10 +1168,12 @@ class list
//!
//! Complexity: Linear time. It performs exactly size() comparisons for equality.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
- void remove(const T& value)
- { this->remove_if(equal_to_value_type(value)); }
+ size_type remove(const T& value)
+ { return this->remove_if(equal_to_value_type(value)); }
//! Effects: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1180,30 +1182,36 @@ class list
//!
//! Complexity: Linear time. It performs exactly size() calls to the predicate.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
template
- void remove_if(Pred pred)
+ size_type remove_if(Pred pred)
{
typedef value_to_node_compare value_to_node_compare_type;
- this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
+ return this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! Effects: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Throws: If comparison throws.
//!
//! Complexity: Linear time (size()-1 comparisons equality comparisons).
//!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
- void unique()
- { this->unique(value_equal_t()); }
+ size_type unique()
+ { return this->unique(value_equal_t()); }
//! Effects: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Throws: If pred throws.
//!
//! Complexity: Linear time (size()-1 comparisons calls to pred()).
@@ -1211,10 +1219,10 @@ class list
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
template
- void unique(BinaryPredicate binary_pred)
+ size_type unique(BinaryPredicate binary_pred)
{
typedef value_to_node_compare value_to_node_compare_type;
- this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
+ return this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
}
//! Requires: The lists x and *this must be distinct.
@@ -1492,22 +1500,14 @@ class list
//! Complexity: Linear.
template
inline typename list::size_type erase(list& c, const U& v)
-{
- typename list::size_type old_size = c.size();
- c.remove_if(equal_to_value(v));
- return old_size - c.size();
-}
+{ return c.remove_if(equal_to_value(v)); }
//! Effects: Erases all elements that satisfy the predicate pred from the container c.
//!
//! Complexity: Linear.
template
inline typename list::size_type erase_if(list& c, Pred pred)
-{
- typename list::size_type old_size = c.size();
- c.remove_if(pred);
- return old_size - c.size();
-}
+{ return c.remove_if(pred); }
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
template
diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp
index f3ee9c2..0e00737 100644
--- a/include/boost/container/slist.hpp
+++ b/include/boost/container/slist.hpp
@@ -1126,10 +1126,12 @@ class slist
//!
//! Complexity: Linear time. It performs exactly size() comparisons for equality.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
- void remove(const T& value)
- { this->remove_if(equal_to_value_type(value)); }
+ size_type remove(const T& value)
+ { return this->remove_if(equal_to_value_type(value)); }
//! Effects: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1138,30 +1140,36 @@ class slist
//!
//! Complexity: Linear time. It performs exactly size() calls to the predicate.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
template
- void remove_if(Pred pred)
+ size_type remove_if(Pred pred)
{
typedef value_to_node_compare value_to_node_compare_type;
- this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
+ return this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! Effects: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Throws: If comparison throws.
//!
//! Complexity: Linear time (size()-1 comparisons equality comparisons).
//!
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
- void unique()
- { this->unique(value_equal_t()); }
+ size_type unique()
+ { return this->unique(value_equal_t()); }
//! Effects: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list.
//!
+ //! Returns: The number of removed elements.
+ //!
//! Throws: If pred throws.
//!
//! Complexity: Linear time (size()-1 comparisons calls to pred()).
@@ -1169,10 +1177,10 @@ class slist
//! Note: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
template
- void unique(Pred pred)
+ size_type unique(Pred pred)
{
typedef value_to_node_compare value_to_node_compare_type;
- this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
+ return this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! Requires: The lists x and *this must be distinct.
@@ -1663,22 +1671,14 @@ class slist
//! Complexity: Linear.
template
inline typename slist::size_type erase(slist& c, const U& v)
-{
- typename slist::size_type old_size = c.size();
- c.remove_if(equal_to_value(v));
- return old_size - c.size();
-}
+{ return c.remove_if(equal_to_value(v)); }
//! Effects: Erases all elements that satisfy the predicate pred from the container c.
//!
//! Complexity: Linear.
template
inline typename slist::size_type erase_if(slist& c, Pred pred)
-{
- typename slist::size_type old_size = c.size();
- c.remove_if(pred);
- return old_size - c.size();
-}
+{ return c.remove_if(pred); }
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
diff --git a/test/list_test.hpp b/test/list_test.hpp
index 73f81da..238c92c 100644
--- a/test/list_test.hpp
+++ b/test/list_test.hpp
@@ -119,6 +119,24 @@ bool list_copyable_only(V1 &boostlist, V2 &stdlist, boost::container::dtl::true_
return 1;
stdlist.erase(boost::container::find(stdlist.begin(), stdlist.end(), 24));
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
+
+ //remove
+ if (1 != boostlist.remove(IntType(23)))
+ return 1;
+ if (0 != boostlist.remove(IntType(23)))
+ return 1;
+
+ stdlist.erase(boost::container::find(stdlist.begin(), stdlist.end(), 23));
+ if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
+
+ //remove_if
+ if (1 != boostlist.remove_if(equal_to_value(22)))
+ return 1;
+ if (0 != boostlist.remove_if(equal_to_value(22)))
+ return 1;
+ stdlist.erase(boost::container::find(stdlist.begin(), stdlist.end(), 22));
+ if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
+
}
{ //List(const List &, alloc)
::boost::movelib::unique_ptr const pv1 = ::boost::movelib::make_unique(boostlist, typename V1::allocator_type());
@@ -377,8 +395,13 @@ int list_test (bool copied_allocators_equal = true)
return 1;
}
- boostlist.unique();
- stdlist.unique();
+ {
+ std::size_t old_sz = boostlist.size();
+ std::size_t bremoved = boostlist.unique();
+ if (bremoved != (old_sz - boostlist.size()))
+ return 1;
+ stdlist.unique();
+ }
if(!CheckEqualContainers(boostlist, stdlist))
return 1;