Files

242 lines
5.7 KiB
C++
Raw Permalink Normal View History

2026-03-23 20:54:41 +08:00
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
#ifndef BOOST_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/intrusive/detail/algorithm.hpp>
#include <boost/move/utility_core.hpp>
namespace boost {
namespace container {
using boost::intrusive::algo_equal;
using boost::intrusive::algo_lexicographical_compare;
template<class Func>
class binder1st
{
public:
typedef typename Func::second_argument_type argument_type;
typedef typename Func::result_type result_type;
binder1st(const Func& func, const typename Func::first_argument_type& arg)
: op(func), value(arg)
{}
result_type operator()(const argument_type& arg) const
{ return op(value, arg); }
result_type operator()(argument_type& arg) const
{ return op(value, arg); }
private:
Func op;
typename Func::first_argument_type value;
};
template<class Func, class T>
inline binder1st<Func> bind1st(const Func& func, const T& arg)
{ return boost::container::binder1st<Func>(func, arg); }
template<class Func>
class binder2nd
{
public:
typedef typename Func::first_argument_type argument_type;
typedef typename Func::result_type result_type;
binder2nd(const Func& func, const typename Func::second_argument_type& arg)
: op(func), value(arg)
{}
result_type operator()(const argument_type& arg) const
{ return op(arg, value); }
result_type operator()(argument_type& arg) const
{ return op(arg, value); }
private:
Func op;
typename Func::second_argument_type value;
};
template<class Func, class T>
inline binder2nd<Func> bind2nd(const Func& func, const T& arg)
{
return (boost::container::binder2nd<Func>(func, arg));
}
template<class Func>
class unary_negate
{
public:
typedef typename Func::argument_type argument_type;
typedef typename Func::result_type result_type;
explicit unary_negate(const Func& func)
: m_func(func)
{}
bool operator()(const typename Func::argument_type& arg) const
{ return !m_func(arg); }
private:
Func m_func;
};
template<class Func> inline
unary_negate<Func> not1(const Func& func)
{
return boost::container::unary_negate<Func>(func);
}
template<class InputIt, class UnaryPredicate>
InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first) {
if (p(*first)) {
return first;
}
}
return last;
}
template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
ForwardIt1 find_end (ForwardIt1 first1, ForwardIt1 last1
,ForwardIt2 first2, ForwardIt2 last2
,BinaryPredicate p)
{
if (first2==last2)
return last1; // specified in C++11
ForwardIt1 ret = last1;
while (first1!=last1)
{
ForwardIt1 it1 = first1;
ForwardIt2 it2 = first2;
while ( p(*it1, *it2) ) {
++it1; ++it2;
if (it2==last2) {
ret=first1;
break;
}
if (it1==last1)
return ret;
}
++first1;
}
return ret;
}
template<class InputIt, class ForwardIt, class BinaryPredicate>
InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p)
{
for (; first1 != last1; ++first1) {
for (ForwardIt it = first2; it != last2; ++it) {
if (p(*first1, *it)) {
return first1;
}
}
}
return last1;
}
template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p)
{
for (; ; ++first1) {
ForwardIt1 it = first1;
for (ForwardIt2 it2 = first2; ; ++it, ++it2) {
if (it2 == last2) {
return first1;
}
if (it == last1) {
return last1;
}
if (!p(*it, *it2)) {
break;
}
}
}
}
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;
}
template <class Cont, class Pred>
typename Cont::size_type container_erase_if(Cont& c, Pred p)
{
typedef typename Cont::size_type size_type;
typedef typename Cont::iterator it_t;
size_type prev_size = c.size();
it_t it = c.begin();
//end() must be called each loop for non-node containers
while ( it != c.end() ) {
if (p(*it)) {
it = c.erase(it);
}
else {
++it;
}
}
return prev_size - c.size();
}
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP