algorithm.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2014.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/container for documentation.
  10. //
  11. //////////////////////////////////////////////////////////////////////////////
  12. #ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
  13. #define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/intrusive/detail/algorithm.hpp>
  21. #include <boost/move/utility_core.hpp>
  22. namespace boost {
  23. namespace container {
  24. using boost::intrusive::algo_equal;
  25. using boost::intrusive::algo_lexicographical_compare;
  26. template<class Func>
  27. class binder1st
  28. {
  29. public:
  30. typedef typename Func::second_argument_type argument_type;
  31. typedef typename Func::result_type result_type;
  32. binder1st(const Func& func, const typename Func::first_argument_type& arg)
  33. : op(func), value(arg)
  34. {}
  35. result_type operator()(const argument_type& arg) const
  36. { return op(value, arg); }
  37. result_type operator()(argument_type& arg) const
  38. { return op(value, arg); }
  39. private:
  40. Func op;
  41. typename Func::first_argument_type value;
  42. };
  43. template<class Func, class T>
  44. inline binder1st<Func> bind1st(const Func& func, const T& arg)
  45. { return boost::container::binder1st<Func>(func, arg); }
  46. template<class Func>
  47. class binder2nd
  48. {
  49. public:
  50. typedef typename Func::first_argument_type argument_type;
  51. typedef typename Func::result_type result_type;
  52. binder2nd(const Func& func, const typename Func::second_argument_type& arg)
  53. : op(func), value(arg)
  54. {}
  55. result_type operator()(const argument_type& arg) const
  56. { return op(arg, value); }
  57. result_type operator()(argument_type& arg) const
  58. { return op(arg, value); }
  59. private:
  60. Func op;
  61. typename Func::second_argument_type value;
  62. };
  63. template<class Func, class T>
  64. inline binder2nd<Func> bind2nd(const Func& func, const T& arg)
  65. {
  66. return (boost::container::binder2nd<Func>(func, arg));
  67. }
  68. template<class Func>
  69. class unary_negate
  70. {
  71. public:
  72. typedef typename Func::argument_type argument_type;
  73. typedef typename Func::result_type result_type;
  74. explicit unary_negate(const Func& func)
  75. : m_func(func)
  76. {}
  77. bool operator()(const typename Func::argument_type& arg) const
  78. { return !m_func(arg); }
  79. private:
  80. Func m_func;
  81. };
  82. template<class Func> inline
  83. unary_negate<Func> not1(const Func& func)
  84. {
  85. return boost::container::unary_negate<Func>(func);
  86. }
  87. template<class InputIt, class UnaryPredicate>
  88. InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
  89. {
  90. for (; first != last; ++first) {
  91. if (p(*first)) {
  92. return first;
  93. }
  94. }
  95. return last;
  96. }
  97. template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
  98. ForwardIt1 find_end (ForwardIt1 first1, ForwardIt1 last1
  99. ,ForwardIt2 first2, ForwardIt2 last2
  100. ,BinaryPredicate p)
  101. {
  102. if (first2==last2)
  103. return last1; // specified in C++11
  104. ForwardIt1 ret = last1;
  105. while (first1!=last1)
  106. {
  107. ForwardIt1 it1 = first1;
  108. ForwardIt2 it2 = first2;
  109. while ( p(*it1, *it2) ) {
  110. ++it1; ++it2;
  111. if (it2==last2) {
  112. ret=first1;
  113. break;
  114. }
  115. if (it1==last1)
  116. return ret;
  117. }
  118. ++first1;
  119. }
  120. return ret;
  121. }
  122. template<class InputIt, class ForwardIt, class BinaryPredicate>
  123. InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p)
  124. {
  125. for (; first1 != last1; ++first1) {
  126. for (ForwardIt it = first2; it != last2; ++it) {
  127. if (p(*first1, *it)) {
  128. return first1;
  129. }
  130. }
  131. }
  132. return last1;
  133. }
  134. template<class ForwardIt1, class ForwardIt2, class BinaryPredicate>
  135. ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1,
  136. ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p)
  137. {
  138. for (; ; ++first1) {
  139. ForwardIt1 it = first1;
  140. for (ForwardIt2 it2 = first2; ; ++it, ++it2) {
  141. if (it2 == last2) {
  142. return first1;
  143. }
  144. if (it == last1) {
  145. return last1;
  146. }
  147. if (!p(*it, *it2)) {
  148. break;
  149. }
  150. }
  151. }
  152. }
  153. template<class InpIt, class U>
  154. InpIt find(InpIt first, InpIt last, const U& value)
  155. {
  156. for (; first != last; ++first)
  157. if (*first == value)
  158. return first;
  159. return last;
  160. }
  161. template<class FwdIt, class U>
  162. FwdIt remove(FwdIt first, FwdIt last, const U& value)
  163. {
  164. first = find(first, last, value);
  165. if (first != last)
  166. for (FwdIt i = first; ++i != last;)
  167. if (!(*i == value))
  168. *first++ = boost::move(*i);
  169. return first;
  170. }
  171. template<class FwdIt, class Pred>
  172. FwdIt remove_if(FwdIt first, FwdIt last, Pred p)
  173. {
  174. first = find_if(first, last, p);
  175. if (first != last)
  176. for (FwdIt i = first; ++i != last;)
  177. if (!p(*i))
  178. *first++ = boost::move(*i);
  179. return first;
  180. }
  181. template <class Cont, class Pred>
  182. typename Cont::size_type container_erase_if(Cont& c, Pred p)
  183. {
  184. typedef typename Cont::size_type size_type;
  185. typedef typename Cont::iterator it_t;
  186. size_type prev_size = c.size();
  187. it_t it = c.begin();
  188. //end() must be called each loop for non-node containers
  189. while ( it != c.end() ) {
  190. if (p(*it)) {
  191. it = c.erase(it);
  192. }
  193. else {
  194. ++it;
  195. }
  196. }
  197. return prev_size - c.size();
  198. }
  199. } //namespace container {
  200. } //namespace boost {
  201. #endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP