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