[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | 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.6.0, Aug 13 2008 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@informatik.uni-hamburg.de                               */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037
    00038
    00039 #ifndef VIGRA_ITERATORADAPTER_HXX
    00040 #define VIGRA_ITERATORADAPTER_HXX
    00041
    00042 namespace vigra {
    00043
    00044 /********************************************************/
    00045 /*                                                      */
    00046 /*                    IteratorAdaptor                   */
    00047 /*                                                      */
    00048 /********************************************************/
    00049
    00050 /*! \brief Quickly create 1-dimensional iterator adapters.
    00051
    00052     This class supports the easy creation of 1D iterator adpaters out
    00053     of existing iterators. To use it, you must first implement a policy class
    00054     that defines the iterator's behavior. The policy is used to
    00055     instantiate the IteratorAdapter template, which thus automatically
    00056     obtains all required functions of an STL-compatible iterator.
    00057     General information on how this works can be found on the
    00058     <a href="http://www.boost.org/libs/utility/iterator_adaptors.htm">Boost Iterator Adaptor</a>
    00059     page, although there are some differences in the details of the
    00060     boost and VIGRA implementations.
    00061     Here is an example policy class that just exports the behaviour
    00062     of the underlying iterator:
    00063
    00064     \code
    00065     template <class Iterator>
    00066     class TrivialIteratorAdaptorPolicy
    00067     {
    00068       public:
    00069         // the underlying iterator
    00070         typedef Iterator                               BaseType;
    00071
    00072         // the adaptor's value type
    00073         typedef typename Iterator::value_type          value_type;
    00074
    00075         // the adaptor's difference type (result of 'iter1 - iter2',
    00076         //                                argument of 'iter[n]')
    00077         typedef typename Iterator::difference_type     difference_type;
    00078
    00079         // the adaptor's reference type (result of '*iter')
    00080         typedef typename Iterator::reference           reference;
    00081
    00082         // the adaptor's index_reference type (result of 'iter[n]')
    00083         typedef typename Iterator::index_reference     index_reference;
    00084
    00085         // the adaptor's pointer type (result of 'iter.operator->()')
    00086         typedef typename Iterator::pointer             pointer;
    00087
    00088         // the adaptor's iterator category
    00089         typedef typename Iterator::iterator_category   iterator_category;
    00090
    00091         // do some additional initialization in the adaptor's constructor
    00092         static void initialize(BaseType & d) {}
    00093
    00094         // called by '*iter', 'iter->'
    00095         static reference dereference(BaseType const & d)
    00096             { return *d; }
    00097
    00098         // called by 'iter[n]'
    00099         static index_reference dereference(BaseType d, difference_type n)
    00100             { return d[n]; }
    00101
    00102         // called by 'iter1 == iter2', 'iter1 != iter2'
    00103         static bool equal(BaseType const & d1, BaseType const & d2)
    00104             { return d1 == d2; }
    00105
    00106         // called by 'iter1 < iter2', 'iter1 <= iter2', 'iter1 > iter2', 'iter1 >= iter2'
    00107         static bool less(BaseType const & d1, BaseType const & d2)
    00108             { return d1 < d2; }
    00109
    00110         // called by 'iter1 - iter2'
    00111         static difference_type difference(BaseType const & d1, BaseType const & d2)
    00112             { return d1 - d2; }
    00113
    00114         // called by '++iter', 'iter++'
    00115         static void increment(BaseType & d)
    00116             { ++d; }
    00117
    00118         // called by '--iter', 'iter--'
    00119         static void decrement(BaseType & d)
    00120             { --d; }
    00121
    00122         // called by 'iter += n', 'iter -= n'
    00123         static void advance(BaseType & d, difference_type n)
    00124             { d += n; }
    00125     };
    00126     \endcode
    00127
    00128     This policy class is used like this:
    00129
    00130     \code
    00131     SomeIterator iter = ...;
    00132
    00133     vigra::IteratorAdaptor<vigra::TrivialIteratorAdaptorPolicy<SomeIterator> > iter_adaptor(iter);
    00134     \endcode
    00135
    00136     By changing the definition of the policy members, a wide range of
    00137     adaptor behaviors can be achieved. If the base iterator isn't a
    00138     random access iterator, just drop the functions that cannot be implemented.
    00139     This simply means that some adaptor functions may not be called,
    00140     as one would expect from an iterator that doesn't support random access.
    00141     Note also that the <TT>BaseType</TT> needs not be an iterator -
    00142     it can be any type that contains the information necessary for the
    00143     adaptor to do it's work.
    00144
    00145     <b>\#include</b> <<a href="iteratoradapter_8hxx-source.html">vigra/iteratoradapter.hxx</a>><br>
    00146     Namespace: vigra
    00147
    00148 */
    00149 template <class Policy>
    00150 class IteratorAdaptor
    00151 {
    00152   public:
    00153
    00154     typedef typename Policy::BaseType BaseType;
    00155     typedef typename Policy::value_type        value_type;
    00156     typedef typename Policy::difference_type   difference_type;
    00157     typedef typename Policy::reference         reference;
    00158     typedef typename Policy::index_reference   index_reference;
    00159     typedef typename Policy::pointer           pointer;
    00160     typedef typename Policy::iterator_category iterator_category;
    00161
    00162     IteratorAdaptor()
    00163     : adaptee_()
    00164     {}
    00165
    00166         /** Construct from an instance of the policy class' BaseType
    00167             Note that the functions of the adaptor implement the
    00168             interface of an random access iterator as defined in the
    00169             C++ standard, so there is no need for explicit documentation.
    00170         */
    00171     explicit IteratorAdaptor(BaseType const & o)
    00172     : adaptee_(o)
    00173     {
    00174         Policy::initialize(adaptee_);
    00175     }
    00176
    00177     IteratorAdaptor(IteratorAdaptor const & o)
    00178     : adaptee_(o.adaptee_)
    00179     {}
    00180
    00181     IteratorAdaptor & operator=(BaseType const & o)
    00182     {
    00183         if(this != &o)
    00184         {
    00185             adaptee_ = o;
    00186             Policy::initialize(adaptee_);
    00187         }
    00188         return *this;
    00189     }
    00190
    00191     IteratorAdaptor & operator=(IteratorAdaptor const & o)
    00192     {
    00193         if(this != &o)
    00194             adaptee_ = o.adaptee_;
    00195         return *this;
    00196     }
    00197
    00198     IteratorAdaptor & operator+=(difference_type d)
    00199     {
    00200         Policy::advance(adaptee_, d);
    00201         return *this;
    00202     }
    00203
    00204     IteratorAdaptor operator+(difference_type d) const
    00205     {
    00206         return IteratorAdaptor(*this) += d;
    00207     }
    00208
    00209     IteratorAdaptor & operator-=(difference_type d)
    00210     {
    00211         Policy::advance(adaptee_, -d);
    00212         return *this;
    00213     }
    00214
    00215     IteratorAdaptor operator-(difference_type d) const
    00216     {
    00217         return IteratorAdaptor(*this) -= d;
    00218     }
    00219
    00220     IteratorAdaptor & operator++()
    00221     {
    00222         Policy::increment(adaptee_);
    00223         return *this;
    00224     }
    00225
    00226     IteratorAdaptor operator++(int)
    00227     {
    00228         IteratorAdaptor res(*this);
    00229         Policy::increment(adaptee_);
    00230         return res;
    00231     }
    00232
    00233     IteratorAdaptor & operator--()
    00234     {
    00235         Policy::decrement(adaptee_);
    00236         return *this;
    00237     }
    00238
    00239     IteratorAdaptor operator--(int)
    00240     {
    00241         IteratorAdaptor res(*this);
    00242         Policy::decrement(adaptee_);
    00243         return res;
    00244     }
    00245
    00246     bool operator==(IteratorAdaptor const & o) const
    00247     {
    00248         return Policy::equal(adaptee_, o.adaptee_);
    00249     }
    00250
    00251     bool operator!=(IteratorAdaptor const & o) const
    00252     {
    00253         return !Policy::equal(adaptee_, o.adaptee_);
    00254     }
    00255
    00256     bool operator<(IteratorAdaptor const & o) const
    00257     {
    00258         return Policy::less(adaptee_, o.adaptee_);
    00259     }
    00260
    00261     bool operator<=(IteratorAdaptor const & o) const
    00262     {
    00263         return !Policy::less(o.adaptee_, adaptee_);
    00264     }
    00265
    00266     bool operator>(IteratorAdaptor const & o) const
    00267     {
    00268         return Policy::less(o.adaptee_, adaptee_);
    00269     }
    00270
    00271     bool operator>=(IteratorAdaptor const & o) const
    00272     {
    00273         return !Policy::less(adaptee_, o.adaptee_);
    00274     }
    00275
    00276     difference_type operator-(IteratorAdaptor const & o) const
    00277     {
    00278         return Policy::difference(adaptee_, o.adaptee_);
    00279     }
    00280
    00281     reference operator*() const
    00282     {
    00283         return Policy::dereference(adaptee_);
    00284     }
    00285
    00286     index_reference operator[](difference_type d) const
    00287     {
    00288         return Policy::dereference(adaptee_, d);
    00289     }
    00290
    00291     pointer operator->() const
    00292     {
    00293         return &Policy::dereference(adaptee_);
    00294     }
    00295
    00296   protected:
    00297
    00298     BaseType adaptee_;
    00299 };
    00300
    00301 } // namespace vigra
    00302
    00303
    00304 #endif /* VIGRA_ITERATORADAPTER_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)