[ 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 adpaters 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> <<a href="iteratoradapter_8hxx-source.html">vigra/iteratoradapter.hxx</a>><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.7.0 (Thu Aug 25 2011)