[ 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)