vigra - vigra/iteratoradapter.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

iteratoradapter.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36
37 #ifndef VIGRA_ITERATORADAPTER_HXX
38 #define VIGRA_ITERATORADAPTER_HXX
39
40 namespace vigra {
41
42 /********************************************************/
43 /* */
44 /* IteratorAdaptor */
45 /* */
46 /********************************************************/
47
48 /** \brief Quickly create 1-dimensional iterator adapters.
49
50 This class supports the easy creation of 1D iterator adapters out
51 of existing iterators. To use it, you must first implement a policy class
52 that defines the iterator's behavior. The policy is used to
53 instantiate the IteratorAdapter template, which thus automatically
54 obtains all required functions of an STL-compatible iterator.
55 General information on how this works can be found on the
56 <a href="http://www.boost.org/libs/utility/iterator_adaptors.htm">Boost Iterator Adaptor</a>
57 page, although there are some differences in the details of the
58 boost and VIGRA implementations.
59 Here is an example policy class that just exports the behaviour
60 of the underlying iterator:
61
62 \code
63 template <class Iterator>
64 class TrivialIteratorAdaptorPolicy
65 {
66 public:
67 // the underlying iterator
68 typedef Iterator BaseType;
69
70 // the adaptor's value type
71 typedef typename Iterator::value_type value_type;
72
73 // the adaptor's difference type (result of 'iter1 - iter2',
74 // argument of 'iter[n]')
75 typedef typename Iterator::difference_type difference_type;
76
77 // the adaptor's reference type (result of '*iter')
78 typedef typename Iterator::reference reference;
79
80 // the adaptor's index_reference type (result of 'iter[n]')
81 typedef typename Iterator::index_reference index_reference;
82
83 // the adaptor's pointer type (result of 'iter.operator->()')
84 typedef typename Iterator::pointer pointer;
85
86 // the adaptor's iterator category
87 typedef typename Iterator::iterator_category iterator_category;
88
89 // do some additional initialization in the adaptor's constructor
90 static void initialize(BaseType & d) {}
91
92 // called by '*iter', 'iter->'
93 static reference dereference(BaseType const & d)
94 { return *d; }
95
96 // called by 'iter[n]'
97 static index_reference dereference(BaseType d, difference_type n)
98 { return d[n]; }
99
100 // called by 'iter1 == iter2', 'iter1 != iter2'
101 static bool equal(BaseType const & d1, BaseType const & d2)
102 { return d1 == d2; }
103
104 // called by 'iter1 < iter2', 'iter1 <= iter2', 'iter1 > iter2', 'iter1 >= iter2'
105 static bool less(BaseType const & d1, BaseType const & d2)
106 { return d1 < d2; }
107
108 // called by 'iter1 - iter2'
109 static difference_type difference(BaseType const & d1, BaseType const & d2)
110 { return d1 - d2; }
111
112 // called by '++iter', 'iter++'
113 static void increment(BaseType & d)
114 { ++d; }
115
116 // called by '--iter', 'iter--'
117 static void decrement(BaseType & d)
118 { --d; }
119
120 // called by 'iter += n', 'iter -= n'
121 static void advance(BaseType & d, difference_type n)
122 { d += n; }
123 };
124 \endcode
125
126 This policy class is used like this:
127
128 \code
129 SomeIterator iter = ...;
130
131 vigra::IteratorAdaptor<vigra::TrivialIteratorAdaptorPolicy<SomeIterator> > iter_adaptor(iter);
132 \endcode
133
134 By changing the definition of the policy members, a wide range of
135 adaptor behaviors can be achieved. If the base iterator isn't a
136 random access iterator, just drop the functions that cannot be implemented.
137 This simply means that some adaptor functions may not be called,
138 as one would expect from an iterator that doesn't support random access.
139 Note also that the <TT>BaseType</TT> needs not be an iterator -
140 it can be any type that contains the information necessary for the
141 adaptor to do it's work.
142
143 <b>\#include</b> <vigra/iteratoradapter.hxx><br>
144 Namespace: vigra
145
146 */
147 template <class Policy>
148 class IteratorAdaptor
149 {
150 public:
151
152 typedef typename Policy::BaseType BaseType;
153 typedef typename Policy::value_type value_type;
154 typedef typename Policy::difference_type difference_type;
155 typedef typename Policy::reference reference;
156 typedef typename Policy::index_reference index_reference;
157 typedef typename Policy::pointer pointer;
158 typedef typename Policy::iterator_category iterator_category;
159
160 IteratorAdaptor()
161 : adaptee_()
162 {}
163
164 /** Construct from an instance of the policy class' BaseType
165 Note that the functions of the adaptor implement the
166 interface of an random access iterator as defined in the
167 C++ standard, so there is no need for explicit documentation.
168 */
169 explicit IteratorAdaptor(BaseType const & o)
170 : adaptee_(o)
171 {
172 Policy::initialize(adaptee_);
173 }
174
175 IteratorAdaptor(IteratorAdaptor const & o)
176 : adaptee_(o.adaptee_)
177 {}
178
179 IteratorAdaptor & operator=(BaseType const & o)
180 {
181 if(this != &o)
182 {
183 adaptee_ = o;
184 Policy::initialize(adaptee_);
185 }
186 return *this;
187 }
188
189 IteratorAdaptor & operator=(IteratorAdaptor const & o)
190 {
191 if(this != &o)
192 adaptee_ = o.adaptee_;
193 return *this;
194 }
195
196 IteratorAdaptor & operator+=(difference_type d)
197 {
198 Policy::advance(adaptee_, d);
199 return *this;
200 }
201
202 IteratorAdaptor operator+(difference_type d) const
203 {
204 return IteratorAdaptor(*this) += d;
205 }
206
207 IteratorAdaptor & operator-=(difference_type d)
208 {
209 Policy::advance(adaptee_, -d);
210 return *this;
211 }
212
213 IteratorAdaptor operator-(difference_type d) const
214 {
215 return IteratorAdaptor(*this) -= d;
216 }
217
218 IteratorAdaptor & operator++()
219 {
220 Policy::increment(adaptee_);
221 return *this;
222 }
223
224 IteratorAdaptor operator++(int)
225 {
226 IteratorAdaptor res(*this);
227 Policy::increment(adaptee_);
228 return res;
229 }
230
231 IteratorAdaptor & operator--()
232 {
233 Policy::decrement(adaptee_);
234 return *this;
235 }
236
237 IteratorAdaptor operator--(int)
238 {
239 IteratorAdaptor res(*this);
240 Policy::decrement(adaptee_);
241 return res;
242 }
243
244 bool operator==(IteratorAdaptor const & o) const
245 {
246 return Policy::equal(adaptee_, o.adaptee_);
247 }
248
249 bool operator!=(IteratorAdaptor const & o) const
250 {
251 return !Policy::equal(adaptee_, o.adaptee_);
252 }
253
254 bool operator<(IteratorAdaptor const & o) const
255 {
256 return Policy::less(adaptee_, o.adaptee_);
257 }
258
259 bool operator<=(IteratorAdaptor const & o) const
260 {
261 return !Policy::less(o.adaptee_, adaptee_);
262 }
263
264 bool operator>(IteratorAdaptor const & o) const
265 {
266 return Policy::less(o.adaptee_, adaptee_);
267 }
268
269 bool operator>=(IteratorAdaptor const & o) const
270 {
271 return !Policy::less(adaptee_, o.adaptee_);
272 }
273
274 difference_type operator-(IteratorAdaptor const & o) const
275 {
276 return Policy::difference(adaptee_, o.adaptee_);
277 }
278
279 reference operator*() const
280 {
281 return Policy::dereference(adaptee_);
282 }
283
284 index_reference operator[](difference_type d) const
285 {
286 return Policy::dereference(adaptee_, d);
287 }
288
289 pointer operator->() const
290 {
291 return &Policy::dereference(adaptee_);
292 }
293
294 protected:
295
296 BaseType adaptee_;
297 };
298
299 } // namespace vigra
300
301
302 #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.10.0 (Mon Nov 18 2013)