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;