duplicates_iterator.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Copyright 2003-2008 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
  10. #if defined(_MSC_VER)&&(_MSC_VER>=1200)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <cstddef>
  15. #include <iterator>
  16. namespace boost{
  17. namespace multi_index{
  18. namespace detail{
  19. /* duplicates_operator is given a range of ordered elements and
  20. * passes only over those which are duplicated.
  21. */
  22. template<typename Node,typename Predicate>
  23. class duplicates_iterator
  24. {
  25. public:
  26. typedef typename Node::value_type value_type;
  27. typedef std::ptrdiff_t difference_type;
  28. typedef const typename Node::value_type* pointer;
  29. typedef const typename Node::value_type& reference;
  30. typedef std::forward_iterator_tag iterator_category;
  31. duplicates_iterator(Node* node_,Node* end_,Predicate pred_):
  32. node(node_),begin_chunk(0),end(end_),pred(pred_)
  33. {
  34. advance();
  35. }
  36. duplicates_iterator(Node* end_,Predicate pred_):
  37. node(end_),begin_chunk(end_),end(end_),pred(pred_)
  38. {
  39. }
  40. reference operator*()const
  41. {
  42. return node->value();
  43. }
  44. pointer operator->()const
  45. {
  46. return &node->value();
  47. }
  48. duplicates_iterator& operator++()
  49. {
  50. Node::increment(node);
  51. sync();
  52. return *this;
  53. }
  54. duplicates_iterator operator++(int)
  55. {
  56. duplicates_iterator tmp(*this);
  57. ++(*this);
  58. return tmp;
  59. }
  60. Node* get_node()const{return node;}
  61. private:
  62. void sync()
  63. {
  64. if(node!=end&&pred(begin_chunk->value(),node->value()))advance();
  65. }
  66. void advance()
  67. {
  68. for(Node* node2=node;node!=end;node=node2){
  69. Node::increment(node2);
  70. if(node2!=end&&!pred(node->value(),node2->value()))break;
  71. }
  72. begin_chunk=node;
  73. }
  74. Node* node;
  75. Node* begin_chunk;
  76. Node* end;
  77. Predicate pred;
  78. };
  79. template<typename Node,typename Predicate>
  80. bool operator==(
  81. const duplicates_iterator<Node,Predicate>& x,
  82. const duplicates_iterator<Node,Predicate>& y)
  83. {
  84. return x.get_node()==y.get_node();
  85. }
  86. template<typename Node,typename Predicate>
  87. bool operator!=(
  88. const duplicates_iterator<Node,Predicate>& x,
  89. const duplicates_iterator<Node,Predicate>& y)
  90. {
  91. return !(x==y);
  92. }
  93. } /* namespace multi_index::detail */
  94. } /* namespace multi_index */
  95. } /* namespace boost */
  96. #endif