7cc126c998d56d56600d52386160329db442394d
[senf.git] / boost / multi_index / detail / duplicates_iterator.hpp
1 /* Copyright 2003-2006 Joaquín M López Muñoz.
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
9 #ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
10 #define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
11
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
13 #pragma once
14 #endif
15
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <cstddef>
18 #include <iterator>
19
20 namespace boost{
21
22 namespace multi_index{
23
24 namespace detail{
25
26 /* duplicates_operator is given a range of ordered elements and
27  * passes only over those which are duplicated.
28  */
29
30 template<typename Node,typename Predicate>
31 class duplicates_iterator
32 {
33 public:
34   typedef typename Node::value_type        value_type;
35   typedef std::ptrdiff_t                   difference_type;
36   typedef const typename Node::value_type* pointer;
37   typedef const typename Node::value_type& reference;
38   typedef std::forward_iterator_tag        iterator_category;
39
40   duplicates_iterator(Node* node_,Node* end_,Predicate pred_):
41     node(node_),begin_chunk(0),end(end_),pred(pred_)
42   {
43     advance();
44   }
45
46   duplicates_iterator(Node* end_,Predicate pred_):
47     node(end_),begin_chunk(end_),end(end_),pred(pred_)
48   {
49   }
50
51   reference operator*()const
52   {
53     return node->value();
54   }
55
56   pointer operator->()const
57   {
58     return &node->value();
59   }
60
61   duplicates_iterator& operator++()
62   {
63     Node::increment(node);
64     sync();
65     return *this;
66   }
67
68   duplicates_iterator operator++(int)
69   {
70     duplicates_iterator tmp(*this);
71     ++(*this);
72     return tmp;
73   }
74
75   Node* get_node()const{return node;}
76
77 private:
78   void sync()
79   {
80     if(node!=end&&pred(begin_chunk->value(),node->value()))advance();
81   }
82
83   void advance()
84   {
85     for(Node* node2=node;node!=end;node=node2){
86       Node::increment(node2);
87       if(node2!=end&&!pred(node->value(),node2->value()))break;
88     }
89     begin_chunk=node;
90   }
91
92   Node*     node;
93   Node*     begin_chunk;
94   Node*     end;
95   Predicate pred;
96 };
97
98 template<typename Node,typename Predicate>
99 bool operator==(
100   const duplicates_iterator<Node,Predicate>& x,
101   const duplicates_iterator<Node,Predicate>& y)
102 {
103   return x.get_node()==y.get_node();
104 }
105
106 template<typename Node,typename Predicate>
107 bool operator!=(
108   const duplicates_iterator<Node,Predicate>& x,
109   const duplicates_iterator<Node,Predicate>& y)
110 {
111   return !(x==y);
112 }
113
114 } /* namespace multi_index::detail */
115
116 } /* namespace multi_index */
117
118 } /* namespace boost */
119
120 #endif