[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]

details vigra/iteratoradapter.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    ( Version 1.3.3, Aug 18 2005 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022 
00023 
00024 #ifndef VIGRA_ITERATORADAPTER_HXX
00025 #define VIGRA_ITERATORADAPTER_HXX
00026 
00027 namespace vigra {
00028 
00029 /********************************************************/
00030 /*                                                      */
00031 /*                    IteratorAdaptor                   */
00032 /*                                                      */
00033 /********************************************************/
00034 
00035 /*! \brief Quckly create 1-dimensional iterator adapters.
00036 
00037     This class supports the easy creation of 1D iterator adpaters out
00038     of existing iterators. To use it, you must first implement a policy class
00039     that defines the iterator's behavior. The policy is used to
00040     instantiate the IteratorAdapter template, which thus automatically
00041     obtains all required functions of an STL-compatible iterator.
00042     General information on how this works can be found on the
00043     <a href="http://www.boost.org/libs/utility/iterator_adaptors.htm">Boost Iterator Adaptor</a>
00044     page, although there are some differences in the details of the
00045     boost and VIGRA implementations.
00046     Here is an example policy class that just exports the behaviour
00047     of the underlying iterator:
00048 
00049     \code
00050     template <class Iterator>
00051     class TrivialIteratorAdaptorPolicy
00052     {
00053       public:
00054         // the underlying iterator
00055         typedef Iterator                               BaseType;
00056 
00057         // the adaptor's value type
00058         typedef typename Iterator::value_type          value_type;
00059 
00060         // the adaptor's difference type (result of 'iter1 - iter2',
00061         //                                argument of 'iter[n]')
00062         typedef typename Iterator::difference_type     difference_type;
00063 
00064         // the adaptor's reference type (result of '*iter')
00065         typedef typename Iterator::reference           reference;
00066 
00067         // the adaptor's index_reference type (result of 'iter[n]')
00068         typedef typename Iterator::index_reference     index_reference;
00069 
00070         // the adaptor's pointer type (result of 'iter.operator->()')
00071         typedef typename Iterator::pointer             pointer;
00072 
00073         // the adaptor's iterator category
00074         typedef typename Iterator::iterator_category   iterator_category;
00075 
00076         // do some additional initialization in the adaptor's constructor
00077         static void initialize(BaseType & d) {}
00078 
00079         // called by '*iter', 'iter->'
00080         static reference dereference(BaseType const & d)
00081             { return *d; }
00082 
00083         // called by 'iter[n]'
00084         static index_reference dereference(BaseType d, difference_type n)
00085             { return d[n]; }
00086 
00087         // called by 'iter1 == iter2', 'iter1 != iter2'
00088         static bool equal(BaseType const & d1, BaseType const & d2)
00089             { return d1 == d2; }
00090 
00091         // called by 'iter1 < iter2', 'iter1 <= iter2', 'iter1 > iter2', 'iter1 >= iter2'
00092         static bool less(BaseType const & d1, BaseType const & d2)
00093             { return d1 < d2; }
00094 
00095         // called by 'iter1 - iter2'
00096         static difference_type difference(BaseType const & d1, BaseType const & d2)
00097             { return d1 - d2; }
00098 
00099         // called by '++iter', 'iter++'
00100         static void increment(BaseType & d)
00101             { ++d; }
00102 
00103         // called by '--iter', 'iter--'
00104         static void decrement(BaseType & d)
00105             { --d; }
00106 
00107         // called by 'iter += n', 'iter -= n'
00108         static void advance(BaseType & d, difference_type n)
00109             { d += n; }
00110     };
00111     \endcode
00112 
00113     This policy class is used like this:
00114 
00115     \code
00116     SomeIterator iter = ...;
00117 
00118     vigra::IteratorAdaptor<vigra::TrivialIteratorAdaptorPolicy<SomeIterator> > iter_adaptor(iter);
00119     \endcode
00120 
00121     By changing the definition of the policy members, a wide range of
00122     adaptor behaviors can be achieved. If the base iterator isn't a
00123     random access iterator, just drop the functions that cannot be implemented.
00124     This simply means that some adaptor functions may not be called,
00125     as one would expect from an iterator that doesn't support random access.
00126     Note also that the <TT>BaseType</TT> needs not be an iterator -
00127     it can be any type that contains the information necessary for the
00128     adaptor to do it's work.
00129 
00130     <b>\#include</b> "<a href="iteratoradapter_8hxx-source.html">vigra/iteratoradapter.hxx</a>"<br>
00131     Namespace: vigra
00132 
00133 */
00134 template <class Policy>
00135 class IteratorAdaptor
00136 {
00137   public:
00138 
00139     typedef typename Policy::BaseType BaseType;
00140     typedef typename Policy::value_type        value_type;
00141     typedef typename Policy::difference_type   difference_type;
00142     typedef typename Policy::reference         reference;
00143     typedef typename Policy::index_reference   index_reference;
00144     typedef typename Policy::pointer           pointer;
00145     typedef typename Policy::iterator_category iterator_category;
00146 
00147     IteratorAdaptor()
00148     : adaptee_()
00149     {}
00150 
00151         /** Construct from an instance of the policy class' BaseType
00152             Note that the functions of the adaptor implement the
00153             interface of an random access iterator as defined in the
00154             C++ standard, so there is no need for explicit documentation.
00155         */
00156     explicit IteratorAdaptor(BaseType const & o)
00157     : adaptee_(o)
00158     {
00159         Policy::initialize(adaptee_);
00160     }
00161 
00162     IteratorAdaptor(IteratorAdaptor const & o)
00163     : adaptee_(o.adaptee_)
00164     {}
00165 
00166     IteratorAdaptor & operator=(BaseType const & o)
00167     {
00168         if(this != &o)
00169         {
00170             adaptee_ = o;
00171             Policy::initialize(adaptee_);
00172         }
00173         return *this;
00174     }
00175 
00176     IteratorAdaptor & operator=(IteratorAdaptor const & o)
00177     {
00178         if(this != &o)
00179             adaptee_ = o.adaptee_;
00180         return *this;
00181     }
00182 
00183     IteratorAdaptor & operator+=(difference_type d)
00184     {
00185         Policy::advance(adaptee_, d);
00186         return *this;
00187     }
00188 
00189     IteratorAdaptor operator+(difference_type d) const
00190     {
00191         return IteratorAdaptor(*this) += d;
00192     }
00193 
00194     IteratorAdaptor & operator-=(difference_type d)
00195     {
00196         Policy::advance(adaptee_, -d);
00197         return *this;
00198     }
00199 
00200     IteratorAdaptor operator-(difference_type d) const
00201     {
00202         return IteratorAdaptor(*this) -= d;
00203     }
00204 
00205     IteratorAdaptor & operator++()
00206     {
00207         Policy::increment(adaptee_);
00208         return *this;
00209     }
00210 
00211     IteratorAdaptor operator++(int)
00212     {
00213         IteratorAdaptor res(*this);
00214         Policy::increment(adaptee_);
00215         return res;
00216     }
00217 
00218     IteratorAdaptor & operator--()
00219     {
00220         Policy::decrement(adaptee_);
00221         return *this;
00222     }
00223 
00224     IteratorAdaptor operator--(int)
00225     {
00226         IteratorAdaptor res(*this);
00227         Policy::decrement(adaptee_);
00228         return res;
00229     }
00230 
00231     bool operator==(IteratorAdaptor const & o) const
00232     {
00233         return Policy::equal(adaptee_, o.adaptee_);
00234     }
00235 
00236     bool operator!=(IteratorAdaptor const & o) const
00237     {
00238         return !Policy::equal(adaptee_, o.adaptee_);
00239     }
00240 
00241     bool operator<(IteratorAdaptor const & o) const
00242     {
00243         return Policy::less(adaptee_, o.adaptee_);
00244     }
00245 
00246     bool operator<=(IteratorAdaptor const & o) const
00247     {
00248         return !Policy::less(o.adaptee_, adaptee_);
00249     }
00250 
00251     bool operator>(IteratorAdaptor const & o) const
00252     {
00253         return Policy::less(o.adaptee_, adaptee_);
00254     }
00255 
00256     bool operator>=(IteratorAdaptor const & o) const
00257     {
00258         return !Policy::less(adaptee_, o.adaptee_);
00259     }
00260 
00261     difference_type operator-(IteratorAdaptor const & o) const
00262     {
00263         return Policy::difference(adaptee_, o.adaptee_);
00264     }
00265 
00266     reference operator*() const
00267     {
00268         return Policy::dereference(adaptee_);
00269     }
00270 
00271     index_reference operator[](difference_type d) const
00272     {
00273         return Policy::dereference(adaptee_, d);
00274     }
00275 
00276     pointer operator->() const
00277     {
00278         return &Policy::dereference(adaptee_);
00279     }
00280 
00281   protected:
00282 
00283     BaseType adaptee_;
00284 };
00285 
00286 } // namespace vigra
00287 
00288 
00289 #endif /* VIGRA_ITERATORADAPTER_HXX */

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)