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