[ 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.5.0, Dec 07 2006 ) */ 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 /* koethe@informatik.uni-hamburg.de or */ 00012 /* vigra@kogs1.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 (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|