[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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) |
html generated using doxygen and Python
|