1 | /* Copyright 2003-2005 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(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 | node=node2;
|
---|
89 | }
|
---|
90 | begin_chunk=node;
|
---|
91 | }
|
---|
92 |
|
---|
93 | Node* node;
|
---|
94 | Node* begin_chunk;
|
---|
95 | Node* end;
|
---|
96 | Predicate pred;
|
---|
97 | };
|
---|
98 |
|
---|
99 | template<typename Node,typename Predicate>
|
---|
100 | bool operator==(
|
---|
101 | const duplicates_iterator<Node,Predicate>& x,
|
---|
102 | const duplicates_iterator<Node,Predicate>& y)
|
---|
103 | {
|
---|
104 | return x.get_node()==y.get_node();
|
---|
105 | }
|
---|
106 |
|
---|
107 | template<typename Node,typename Predicate>
|
---|
108 | bool operator!=(
|
---|
109 | const duplicates_iterator<Node,Predicate>& x,
|
---|
110 | const duplicates_iterator<Node,Predicate>& y)
|
---|
111 | {
|
---|
112 | return !(x==y);
|
---|
113 | }
|
---|
114 |
|
---|
115 | } /* namespace multi_index::detail */
|
---|
116 |
|
---|
117 | } /* namespace multi_index */
|
---|
118 |
|
---|
119 | } /* namespace boost */
|
---|
120 |
|
---|
121 | #endif
|
---|