Common/Util/Circulator.h

Go to the documentation of this file.
00001 //-------------------------------------------------------------------
00004 //  Copyright (c) 2004 Evan Sherbrooke
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License, or (at your option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019 //
00020 //-------------------------------------------------------------------
00021 
00022 #ifndef VOLUMILL_CIRCULATOR_H
00023 #define VOLUMILL_CIRCULATOR_H
00024 
00025 #pragma once
00026 
00027 #include <boost/iterator/iterator_facade.hpp>
00028 #include <boost/type_traits.hpp>
00029 
00030 namespace util
00031 {
00032 
00041 template<class Iterator>
00042 class Circulator : public boost::iterator_facade<
00043         Circulator<Iterator>,
00044         typename std::iterator_traits<Iterator>::value_type,
00045         boost::bidirectional_traversal_tag,
00046         typename std::iterator_traits<Iterator>::reference
00047 >
00048 {
00049 public:
00050         Circulator() {}
00051         explicit Circulator(Iterator begin, Iterator end, Iterator pos)
00052                 : m_begin (begin), m_end (end), m_pos (pos) {}
00053 
00054         Iterator getIterator() const { return m_pos; }
00055 
00056         // For compatibility with other circulator types
00057         bool isValid() const { return m_begin != m_end; }
00058 private:
00059         friend class boost::iterator_core_access;
00060         // should this compare ranges too? It seems inefficient and unnecessary
00061         bool equal(Circulator<Iterator> const& other) const
00062         {
00063                 return this->m_pos == other.m_pos;
00064         }
00065    void increment()
00066         {
00067                 ++m_pos;
00068                 if (m_pos == m_end)
00069                         m_pos = m_begin;
00070         }
00071         void decrement()
00072         {
00073                 if (m_pos == m_begin)
00074                         m_pos = m_end;
00075                 --m_pos;
00076         }
00077         typename std::iterator_traits<Iterator>::reference dereference() const
00078         {
00079                 return *m_pos;
00080         }
00081    Iterator m_begin, m_end, m_pos;
00082 };
00083 
00084 template<class Iterator>
00085 inline Circulator<Iterator> makeCirculator (Iterator begin, Iterator end, Iterator pos)
00086 {
00087         return Circulator<Iterator> (begin, end, pos);
00088 }
00089 
00092 template<class Circulator>
00093 class CirculatorToIterator : public boost::iterator_facade<
00094         CirculatorToIterator<Circulator>,
00095         typename std::iterator_traits<Circulator>::value_type,
00096         boost::bidirectional_traversal_tag,
00097         typename std::iterator_traits<Circulator>::reference
00098 >
00099 {
00100 public:
00101         CirculatorToIterator() {}
00102         explicit CirculatorToIterator(Circulator c, int winding = 0)
00103                 : m_circ (c), m_start (c), m_winding (winding) {}
00104 
00105         Circulator getCirculator() const { return m_circ; }
00106 private:
00107         friend class boost::iterator_core_access;
00108         bool equal(CirculatorToIterator<Circulator> const& other) const
00109         {
00110                 return this->m_circ == other.m_circ && this->m_winding == other.m_winding;
00111         }
00112    void increment()
00113         {
00114                 ++m_circ;
00115                 if (m_circ == m_start)
00116                         ++m_winding;
00117         }
00118         void decrement()
00119         {
00120                 if (m_circ == m_start)
00121                         --m_winding;
00122                 --m_circ;
00123         }
00124         typename std::iterator_traits<Circulator>::reference dereference() const
00125         {
00126                 return *m_circ;
00127         }
00128    Circulator m_circ, m_start;
00129         int m_winding;
00130 };
00131 
00132 template<class Circulator>
00133 inline CirculatorToIterator<Circulator> makeBeginIteratorFromCirculator (Circulator circ)
00134 {
00135         return CirculatorToIterator<Circulator> (circ);
00136 }
00137 
00138 template<class Circulator>
00139 inline CirculatorToIterator<Circulator> makeEndIteratorFromCirculator (Circulator circ)
00140 {
00141         return CirculatorToIterator<Circulator> (circ, circ.isValid() ? 1 : 0);
00142 }
00143 
00144 }
00145 #endif

Generated on Tue Jan 29 21:37:56 2008 for VoluMill Universal Client by  doxygen 1.4.6