| /* Copyright 2003-2008 Joaquin M Lopez Munoz. |
| * Distributed under the Boost Software License, Version 1.0. |
| * (See accompanying file LICENSE_1_0.txt or copy at |
| * http://www.boost.org/LICENSE_1_0.txt) |
| * |
| * See http://www.boost.org/libs/multi_index for library home page. |
| */ |
| |
| #ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP |
| #define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP |
| |
| #if defined(_MSC_VER)&&(_MSC_VER>=1200) |
| #pragma once |
| #endif |
| |
| #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ |
| #include <cstddef> |
| #include <iterator> |
| |
| namespace boost{ |
| |
| namespace multi_index{ |
| |
| namespace detail{ |
| |
| /* duplicates_operator is given a range of ordered elements and |
| * passes only over those which are duplicated. |
| */ |
| |
| template<typename Node,typename Predicate> |
| class duplicates_iterator |
| { |
| public: |
| typedef typename Node::value_type value_type; |
| typedef std::ptrdiff_t difference_type; |
| typedef const typename Node::value_type* pointer; |
| typedef const typename Node::value_type& reference; |
| typedef std::forward_iterator_tag iterator_category; |
| |
| duplicates_iterator(Node* node_,Node* end_,Predicate pred_): |
| node(node_),begin_chunk(0),end(end_),pred(pred_) |
| { |
| advance(); |
| } |
| |
| duplicates_iterator(Node* end_,Predicate pred_): |
| node(end_),begin_chunk(end_),end(end_),pred(pred_) |
| { |
| } |
| |
| reference operator*()const |
| { |
| return node->value(); |
| } |
| |
| pointer operator->()const |
| { |
| return &node->value(); |
| } |
| |
| duplicates_iterator& operator++() |
| { |
| Node::increment(node); |
| sync(); |
| return *this; |
| } |
| |
| duplicates_iterator operator++(int) |
| { |
| duplicates_iterator tmp(*this); |
| ++(*this); |
| return tmp; |
| } |
| |
| Node* get_node()const{return node;} |
| |
| private: |
| void sync() |
| { |
| if(node!=end&&pred(begin_chunk->value(),node->value()))advance(); |
| } |
| |
| void advance() |
| { |
| for(Node* node2=node;node!=end;node=node2){ |
| Node::increment(node2); |
| if(node2!=end&&!pred(node->value(),node2->value()))break; |
| } |
| begin_chunk=node; |
| } |
| |
| Node* node; |
| Node* begin_chunk; |
| Node* end; |
| Predicate pred; |
| }; |
| |
| template<typename Node,typename Predicate> |
| bool operator==( |
| const duplicates_iterator<Node,Predicate>& x, |
| const duplicates_iterator<Node,Predicate>& y) |
| { |
| return x.get_node()==y.get_node(); |
| } |
| |
| template<typename Node,typename Predicate> |
| bool operator!=( |
| const duplicates_iterator<Node,Predicate>& x, |
| const duplicates_iterator<Node,Predicate>& y) |
| { |
| return !(x==y); |
| } |
| |
| } /* namespace multi_index::detail */ |
| |
| } /* namespace multi_index */ |
| |
| } /* namespace boost */ |
| |
| #endif |