duplicates_iterator.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* Copyright 2003-2018 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)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <iterator>
  15. namespace boost{
  16. namespace multi_index{
  17. namespace detail{
  18. /* duplicates_operator is given a range of ordered elements and
  19. * passes only over those which are duplicated.
  20. */
  21. template<typename Node,typename Predicate>
  22. class duplicates_iterator
  23. {
  24. public:
  25. typedef typename Node::value_type value_type;
  26. typedef typename Node::difference_type difference_type;
  27. typedef const typename Node::value_type* pointer;
  28. typedef const typename Node::value_type& reference;
  29. typedef std::forward_iterator_tag iterator_category;
  30. duplicates_iterator(Node* node_,Node* end_,Predicate pred_):
  31. node(node_),begin_chunk(0),end(end_),pred(pred_)
  32. {
  33. advance();
  34. }
  35. duplicates_iterator(Node* end_,Predicate pred_):
  36. node(end_),begin_chunk(end_),end(end_),pred(pred_)
  37. {
  38. }
  39. reference operator*()const
  40. {
  41. return node->value();
  42. }
  43. pointer operator->()const
  44. {
  45. return &node->value();
  46. }
  47. duplicates_iterator& operator++()
  48. {
  49. Node::increment(node);
  50. sync();
  51. return *this;
  52. }
  53. duplicates_iterator operator++(int)
  54. {
  55. duplicates_iterator tmp(*this);
  56. ++(*this);
  57. return tmp;
  58. }
  59. Node* get_node()const{return node;}
  60. private:
  61. void sync()
  62. {
  63. if(node!=end&&pred(begin_chunk->value(),node->value()))advance();
  64. }
  65. void advance()
  66. {
  67. for(Node* node2=node;node!=end;node=node2){
  68. Node::increment(node2);
  69. if(node2!=end&&!pred(node->value(),node2->value()))break;
  70. }
  71. begin_chunk=node;
  72. }
  73. Node* node;
  74. Node* begin_chunk;
  75. Node* end;
  76. Predicate pred;
  77. };
  78. template<typename Node,typename Predicate>
  79. bool operator==(
  80. const duplicates_iterator<Node,Predicate>& x,
  81. const duplicates_iterator<Node,Predicate>& y)
  82. {
  83. return x.get_node()==y.get_node();
  84. }
  85. template<typename Node,typename Predicate>
  86. bool operator!=(
  87. const duplicates_iterator<Node,Predicate>& x,
  88. const duplicates_iterator<Node,Predicate>& y)
  89. {
  90. return !(x==y);
  91. }
  92. } /* namespace multi_index::detail */
  93. } /* namespace multi_index */
  94. } /* namespace boost */
  95. #endif