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