#ifndef cycle_iterator_H #define cycle_iterator_H #include #include namespace boost { //! This is a cycle iterator that does keep track of wraparound. template class cycle_iterator : public boost::iterator_adaptor, BaseIterator > { public: typedef typename boost::iterator_adaptor, BaseIterator > super_t; typedef typename super_t::difference_type difference_type; typedef typename super_t::value_type value_type; typedef typename super_t::reference reference; explicit cycle_iterator() {} explicit cycle_iterator (BaseIterator const& _b, BaseIterator const& _e, offset_t offset=0) : base(_b), size (_e-_b) { SetPos (offset); } template cycle_iterator (cycle_iterator const& other) : base (other.base), size (other.size), position (other.position), wrap (other.wrap) {} private: friend class boost::iterator_core_access; void increment () { ++position; if (position >= size) { ++wrap; position -= size; } } void decrement () { --position; if (position < 0) { --wrap; position += size; } } void SetPos (offset_t newpos) { position = newpos % size; wrap = newpos / size; if (position < 0) { --wrap; position += size; } } void advance (difference_type n) { offset_t newpos = realposition() + n; SetPos (newpos); } difference_type distance_to (cycle_iterator const& y) const { if (size == 0) return 0; else { offset_t pos1 = realposition(); offset_t pos2 = y.realposition(); return -(pos1 - pos2); } } bool equal (cycle_iterator const& y) const { return distance_to (y) == 0; } reference dereference() { return *(base + position); } const reference dereference() const { return *(base + position); } offset_t PositiveMod (offset_t x) const { offset_t y = x % size; if (y < 0) y += size; return y; } public: reference operator[] (difference_type n) { return *(base + PositiveMod (position + n)); } const reference operator[] (difference_type n) const { return *(base +PositiveMod (position + n)); } offset_t offset() const { return position; } offset_t realposition () const { return position + wrap * size; } // private: BaseIterator base; offset_t size; offset_t position; offset_t wrap; }; template cycle_iterator make_cycle_iterator(BaseIterator b, BaseIterator e, offset_t offset=0) { return cycle_iterator (b, e, offset); } template cycle_iterator make_cycle_iterator(BaseIterator b, BaseIterator e, int offset=0) { return cycle_iterator (b, e, offset); } } //namespace boost #endif