[ 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) |
html generated using doxygen and Python
|