mirror of
https://github.com/boostorg/container.git
synced 2026-01-19 04:02:17 +00:00
Added C++20 remove and remove_if overloads to vector-like containers
This commit is contained in:
@@ -3065,6 +3065,28 @@ template <typename InputIterator, typename Allocator>
|
||||
deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class O, class U>
|
||||
inline typename deque<T, A, O>::size_type erase(deque<T, A, O>& c, const U& v)
|
||||
{
|
||||
typename deque<T, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class O, class Pred>
|
||||
inline typename deque<T, A, O>::size_type erase_if(deque<T, A, O>& c, Pred pred)
|
||||
{
|
||||
typename deque<T, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
} //namespace container
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/algorithm.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -179,6 +180,39 @@ ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1,
|
||||
}
|
||||
}
|
||||
|
||||
template<class InpIt, class U>
|
||||
InpIt find(InpIt first, InpIt last, const U& value)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
if (*first == value)
|
||||
return first;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
template<class FwdIt, class U>
|
||||
FwdIt remove(FwdIt first, FwdIt last, const U& value)
|
||||
{
|
||||
first = find(first, last, value);
|
||||
if (first != last)
|
||||
for (FwdIt i = first; ++i != last;)
|
||||
if (!(*i == value))
|
||||
*first++ = boost::move(*i);
|
||||
return first;
|
||||
}
|
||||
|
||||
template<class FwdIt, class Pred>
|
||||
FwdIt remove_if(FwdIt first, FwdIt last, Pred p)
|
||||
{
|
||||
first = find_if(first, last, p);
|
||||
if (first != last)
|
||||
for (FwdIt i = first; ++i != last;)
|
||||
if (!p(*i))
|
||||
*first++ = boost::move(*i);
|
||||
return first;
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -3040,6 +3040,28 @@ class devector
|
||||
#endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class O, class U>
|
||||
inline typename devector<T, A, O>::size_type erase(devector<T, A, O>& c, const U& v)
|
||||
{
|
||||
typename devector<T, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class O, class Pred>
|
||||
inline typename devector<T, A, O>::size_type erase_if(devector<T, A, O>& c, Pred pred)
|
||||
{
|
||||
typename devector<T, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
}} // namespace boost::container
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -675,6 +675,28 @@ class small_vector
|
||||
{ this->base_type::prot_shrink_to_fit_small(this->internal_capacity()); }
|
||||
};
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, std::size_t N, class A, class O, class U>
|
||||
inline typename small_vector<T, N, A, O>::size_type erase(small_vector<T, N, A, O>& c, const U& v)
|
||||
{
|
||||
typename small_vector<T, N, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, std::size_t N, class A, class O, class Pred>
|
||||
inline typename small_vector<T, N, A, O>::size_type erase_if(small_vector<T, N, A, O>& c, Pred pred)
|
||||
{
|
||||
typename small_vector<T, N, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -2251,6 +2251,28 @@ stable_vector(InputIterator, InputIterator, Allocator const&) ->
|
||||
|
||||
#undef BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class U>
|
||||
inline typename stable_vector<T, A>::size_type erase(stable_vector<T, A>& c, const U& v)
|
||||
{
|
||||
typename stable_vector<T, A>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class Pred>
|
||||
inline typename stable_vector<T, A>::size_type erase_if(stable_vector<T, A>& c, Pred pred)
|
||||
{
|
||||
typename stable_vector<T, A>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
|
||||
@@ -1333,6 +1333,28 @@ inline void swap(static_vector<V, C1, O1> & x, static_vector<V, C2, O2> & y
|
||||
|
||||
#endif // BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, std::size_t N, class O, class U>
|
||||
inline typename static_vector<T, N, O>::size_type erase(static_vector<T, N, O>& c, const U& v)
|
||||
{
|
||||
typename static_vector<T, N, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, std::size_t N, class O, class Pred>
|
||||
inline typename static_vector<T, N, O>::size_type erase_if(static_vector<T, N, O>& c, Pred pred)
|
||||
{
|
||||
typename static_vector<T, N, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
}} // namespace boost::container
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
@@ -3550,6 +3550,28 @@ getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocat
|
||||
return getline(is, s, '\n');
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class Tr, class A, class U>
|
||||
inline typename basic_string<T, Tr, A>::size_type erase(basic_string<T, Tr, A>& c, const U& v)
|
||||
{
|
||||
typename basic_string<T, Tr, A>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class Tr, class A, class Pred>
|
||||
inline typename basic_string<T, Tr, A>::size_type erase_if(basic_string<T, Tr, A>& c, Pred pred)
|
||||
{
|
||||
typename basic_string<T, Tr, A>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
//GCC 12 has a regression for array-bounds warnings
|
||||
|
||||
@@ -3351,6 +3351,27 @@ vector(InputIterator, InputIterator, Allocator const&) ->
|
||||
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class O, class U>
|
||||
inline typename vector<T, A, O>::size_type erase(vector<T, A, O>& c, const U& v)
|
||||
{
|
||||
typename vector<T, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
template <class T, class A, class O, class Pred>
|
||||
inline typename vector<T, A, O>::size_type erase_if(vector<T, A, O>& c, Pred pred)
|
||||
{
|
||||
typename vector<T, A, O>::size_type old_size = c.size();
|
||||
c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
|
||||
return old_size - c.size();
|
||||
}
|
||||
|
||||
}} //namespace boost::container
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/algorithm.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/move/make_unique.hpp>
|
||||
@@ -558,6 +559,31 @@ int vector_move_assignable_only(boost::container::dtl::true_type)
|
||||
boostvector.resize(100u);
|
||||
if(!test_nth_index_of(boostvector))
|
||||
return 1;
|
||||
|
||||
//test erase/erase_if
|
||||
IntType aux_vect[50];
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect[i] = i;
|
||||
}
|
||||
int aux_vect2[50];
|
||||
for(int i = 0; i < 50; ++i){
|
||||
aux_vect2[i] = i;
|
||||
}
|
||||
|
||||
boostvector.clear();
|
||||
stdvector.clear();
|
||||
boostvector.insert(boostvector.end()
|
||||
,boost::make_move_iterator(&aux_vect[0])
|
||||
,boost::make_move_iterator(aux_vect + 50));
|
||||
stdvector.insert(stdvector.end(), aux_vect2, aux_vect2 + 50);
|
||||
|
||||
if (1 != erase(boostvector, 25))
|
||||
return 1;
|
||||
stdvector.erase(boost::container::find(stdvector.begin(), stdvector.end(), 25));
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
|
||||
|
||||
if (0 != erase(boostvector, 25))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user