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

| vigra/iteratoradapter.hxx |
--- | --- | ---

    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.2, Jan 27 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.2 (27 Jan 2005)