/Src/Dependencies/Boost/boost/range/adaptor/adjacent_filtered.hpp

http://hadesmem.googlecode.com/ · C++ Header · 238 lines · 194 code · 32 blank · 12 comment · 12 complexity · 6bed31c3358d7911d13bb4466967d540 MD5 · raw file

  1. // Boost.Range library
  2. //
  3. // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
  11. #define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
  12. #include <boost/config.hpp>
  13. #ifdef BOOST_MSVC
  14. #pragma warning( push )
  15. #pragma warning( disable : 4355 )
  16. #endif
  17. #include <boost/range/adaptor/argument_fwd.hpp>
  18. #include <boost/range/iterator_range.hpp>
  19. #include <boost/range/begin.hpp>
  20. #include <boost/range/end.hpp>
  21. #include <boost/iterator/iterator_adaptor.hpp>
  22. #include <boost/next_prior.hpp>
  23. namespace boost
  24. {
  25. namespace range_detail
  26. {
  27. template< class Iter, class Pred, bool default_pass >
  28. class skip_iterator
  29. : public boost::iterator_adaptor<
  30. skip_iterator<Iter,Pred,default_pass>,
  31. Iter,
  32. BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
  33. boost::forward_traversal_tag,
  34. BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
  35. BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
  36. >
  37. , private Pred
  38. {
  39. private:
  40. typedef boost::iterator_adaptor<
  41. skip_iterator<Iter,Pred,default_pass>,
  42. Iter,
  43. BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
  44. boost::forward_traversal_tag,
  45. BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
  46. BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
  47. > base_t;
  48. public:
  49. typedef Pred pred_t;
  50. typedef Iter iter_t;
  51. skip_iterator() : m_last() {}
  52. skip_iterator(iter_t it, iter_t last, const Pred& pred)
  53. : base_t(it)
  54. , pred_t(pred)
  55. , m_last(last)
  56. {
  57. move_to_next_valid();
  58. }
  59. template<class OtherIter>
  60. skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
  61. : base_t(other.base())
  62. , pred_t(other)
  63. , m_last(other.m_last) {}
  64. void move_to_next_valid()
  65. {
  66. iter_t& it = this->base_reference();
  67. pred_t& bi_pred = *this;
  68. if (it != m_last)
  69. {
  70. if (default_pass)
  71. {
  72. iter_t nxt = ::boost::next(it);
  73. while (nxt != m_last && !bi_pred(*it, *nxt))
  74. {
  75. ++it;
  76. ++nxt;
  77. }
  78. }
  79. else
  80. {
  81. iter_t nxt = ::boost::next(it);
  82. for(; nxt != m_last; ++it, ++nxt)
  83. {
  84. if (bi_pred(*it, *nxt))
  85. {
  86. break;
  87. }
  88. }
  89. if (nxt == m_last)
  90. {
  91. it = m_last;
  92. }
  93. }
  94. }
  95. }
  96. void increment()
  97. {
  98. iter_t& it = this->base_reference();
  99. BOOST_ASSERT( it != m_last );
  100. ++it;
  101. move_to_next_valid();
  102. }
  103. iter_t m_last;
  104. };
  105. template< class P, class R, bool default_pass >
  106. struct adjacent_filtered_range
  107. : iterator_range< skip_iterator<
  108. BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
  109. P,
  110. default_pass
  111. >
  112. >
  113. {
  114. private:
  115. typedef skip_iterator<
  116. BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
  117. P,
  118. default_pass
  119. >
  120. skip_iter;
  121. typedef iterator_range<skip_iter>
  122. base_range;
  123. typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
  124. public:
  125. adjacent_filtered_range( const P& p, R& r )
  126. : base_range(skip_iter(boost::begin(r), boost::end(r), p),
  127. skip_iter(boost::end(r), boost::end(r), p))
  128. {
  129. }
  130. };
  131. template< class T >
  132. struct adjacent_holder : holder<T>
  133. {
  134. adjacent_holder( T r ) : holder<T>(r)
  135. { }
  136. };
  137. template< class T >
  138. struct adjacent_excl_holder : holder<T>
  139. {
  140. adjacent_excl_holder( T r ) : holder<T>(r)
  141. { }
  142. };
  143. template< class ForwardRng, class BinPredicate >
  144. inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
  145. operator|( ForwardRng& r,
  146. const adjacent_holder<BinPredicate>& f )
  147. {
  148. return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
  149. }
  150. template< class ForwardRng, class BinPredicate >
  151. inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
  152. operator|( const ForwardRng& r,
  153. const adjacent_holder<BinPredicate>& f )
  154. {
  155. return adjacent_filtered_range<BinPredicate,
  156. const ForwardRng, true>( f.val, r );
  157. }
  158. template< class ForwardRng, class BinPredicate >
  159. inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
  160. operator|( ForwardRng& r,
  161. const adjacent_excl_holder<BinPredicate>& f )
  162. {
  163. return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
  164. }
  165. template< class ForwardRng, class BinPredicate >
  166. inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
  167. operator|( const ForwardRng& r,
  168. const adjacent_excl_holder<BinPredicate>& f )
  169. {
  170. return adjacent_filtered_range<BinPredicate,
  171. const ForwardRng, false>( f.val, r );
  172. }
  173. } // 'range_detail'
  174. // Bring adjacent_filter_range into the boost namespace so that users of
  175. // this library may specify the return type of the '|' operator and
  176. // adjacent_filter()
  177. using range_detail::adjacent_filtered_range;
  178. namespace adaptors
  179. {
  180. namespace
  181. {
  182. const range_detail::forwarder<range_detail::adjacent_holder>
  183. adjacent_filtered =
  184. range_detail::forwarder<range_detail::adjacent_holder>();
  185. const range_detail::forwarder<range_detail::adjacent_excl_holder>
  186. adjacent_filtered_excl =
  187. range_detail::forwarder<range_detail::adjacent_excl_holder>();
  188. }
  189. template<class ForwardRng, class BinPredicate>
  190. inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
  191. adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
  192. {
  193. return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
  194. }
  195. template<class ForwardRng, class BinPredicate>
  196. inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
  197. adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
  198. {
  199. return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
  200. }
  201. } // 'adaptors'
  202. }
  203. #ifdef BOOST_MSVC
  204. #pragma warning( pop )
  205. #endif
  206. #endif