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

vigra/iteratoradapter.hxx |

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