[ 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#ifndef VIGRA_ITERATORADAPTER_HXX
36#define VIGRA_ITERATORADAPTER_HXX
37
38
39namespace vigra {
40
41/********************************************************/
42/* */
43/* IteratorAdaptor */
44/* */
45/********************************************************/
46
47/** \brief Quickly create 1-dimensional iterator adapters.
48
49 This class supports the easy creation of 1D iterator adapters out
50 of existing iterators. To use it, you must first implement a policy class
51 that defines the iterator's behavior. The policy is used to
52 instantiate the IteratorAdapter template, which thus automatically
53 obtains all required functions of an STL-compatible iterator.
54 General information on how this works can be found on the
55 <a href="http://www.boost.org/libs/utility/iterator_adaptors.htm">Boost Iterator Adaptor</a>
56 page, although there are some differences in the details of the
57 boost and VIGRA implementations.
58 Here is an example policy class that just exports the behaviour
59 of the underlying iterator:
60
61 \code
62 template <class Iterator>
63 class TrivialIteratorAdaptorPolicy
64 {
65 public:
66 // the underlying iterator
67 typedef Iterator BaseType;
68
69 // the adaptor's value type
70 typedef typename Iterator::value_type value_type;
71
72 // the adaptor's difference type (result of 'iter1 - iter2',
73 // argument of 'iter[n]')
74 typedef typename Iterator::difference_type difference_type;
75
76 // the adaptor's reference type (result of '*iter')
77 typedef typename Iterator::reference reference;
78
79 // the adaptor's index_reference type (result of 'iter[n]')
80 typedef typename Iterator::index_reference index_reference;
81
82 // the adaptor's pointer type (result of 'iter.operator->()')
83 typedef typename Iterator::pointer pointer;
84
85 // the adaptor's iterator category
86 typedef typename Iterator::iterator_category iterator_category;
87
88 // do some additional initialization in the adaptor's constructor
89 static void initialize(BaseType & d) {}
90
91 // called by '*iter', 'iter->'
92 static reference dereference(BaseType const & d)
93 { return *d; }
94
95 // called by 'iter[n]'
96 static index_reference dereference(BaseType d, difference_type n)
97 { return d[n]; }
98
99 // called by 'iter1 == iter2', 'iter1 != iter2'
100 static bool equal(BaseType const & d1, BaseType const & d2)
101 { return d1 == d2; }
102
103 // called by 'iter1 < iter2', 'iter1 <= iter2', 'iter1 > iter2', 'iter1 >= iter2'
104 static bool less(BaseType const & d1, BaseType const & d2)
105 { return d1 < d2; }
106
107 // called by 'iter1 - iter2'
108 static difference_type difference(BaseType const & d1, BaseType const & d2)
109 { return d1 - d2; }
110
111 // called by '++iter', 'iter++'
112 static void increment(BaseType & d)
113 { ++d; }
114
115 // called by '--iter', 'iter--'
116 static void decrement(BaseType & d)
117 { --d; }
118
119 // called by 'iter += n', 'iter -= n'
120 static void advance(BaseType & d, difference_type n)
121 { d += n; }
122 };
123 \endcode
124
125 This policy class is used like this:
126
127 \code
128 SomeIterator iter = ...;
129
130 vigra::IteratorAdaptor<vigra::TrivialIteratorAdaptorPolicy<SomeIterator> > iter_adaptor(iter);
131 \endcode
132
133 By changing the definition of the policy members, a wide range of
134 adaptor behaviors can be achieved. If the base iterator isn't a
135 random access iterator, just drop the functions that cannot be implemented.
136 This simply means that some adaptor functions may not be called,
137 as one would expect from an iterator that doesn't support random access.
138 Note also that the <TT>BaseType</TT> needs not be an iterator -
139 it can be any type that contains the information necessary for the
140 adaptor to do it's work.
141
142 <b>\#include</b> <vigra/iteratoradapter.hxx><br>
143 Namespace: vigra
144
145*/
146template <class Policy>
148{
149 public:
150
151 typedef typename Policy::BaseType BaseType;
152 typedef typename Policy::value_type value_type;
153 typedef typename Policy::difference_type difference_type;
154 typedef typename Policy::reference reference;
155 typedef typename Policy::index_reference index_reference;
156 typedef typename Policy::pointer pointer;
157 typedef typename Policy::iterator_category iterator_category;
158
160 : adaptee_()
161 {}
162
163 /** Construct from an instance of the policy class' BaseType
164 Note that the functions of the adaptor implement the
165 interface of an random access iterator as defined in the
166 C++ standard, so there is no need for explicit documentation.
167 */
168 explicit IteratorAdaptor(BaseType const & o)
169 : adaptee_(o)
170 {
171 Policy::initialize(adaptee_);
172 }
173
175 : adaptee_(o.adaptee_)
176 {}
177
178 IteratorAdaptor & operator=(BaseType const & o)
179 {
180 if(this != &o)
181 {
182 adaptee_ = o;
183 Policy::initialize(adaptee_);
184 }
185 return *this;
186 }
187
188 IteratorAdaptor & operator=(IteratorAdaptor const & o)
189 {
190 if(this != &o)
191 adaptee_ = o.adaptee_;
192 return *this;
193 }
194
195 IteratorAdaptor & operator+=(difference_type d)
196 {
197 Policy::advance(adaptee_, d);
198 return *this;
199 }
200
201 IteratorAdaptor operator+(difference_type d) const
202 {
203 return IteratorAdaptor(*this) += d;
204 }
205
206 IteratorAdaptor & operator-=(difference_type d)
207 {
208 Policy::advance(adaptee_, -d);
209 return *this;
210 }
211
212 IteratorAdaptor operator-(difference_type d) const
213 {
214 return IteratorAdaptor(*this) -= d;
215 }
216
217 IteratorAdaptor & operator++()
218 {
219 Policy::increment(adaptee_);
220 return *this;
221 }
222
223 IteratorAdaptor operator++(int)
224 {
225 IteratorAdaptor res(*this);
226 Policy::increment(adaptee_);
227 return res;
228 }
229
230 IteratorAdaptor & operator--()
231 {
232 Policy::decrement(adaptee_);
233 return *this;
234 }
235
236 IteratorAdaptor operator--(int)
237 {
238 IteratorAdaptor res(*this);
239 Policy::decrement(adaptee_);
240 return res;
241 }
242
243 bool operator==(IteratorAdaptor const & o) const
244 {
245 return Policy::equal(adaptee_, o.adaptee_);
246 }
247
248 bool operator!=(IteratorAdaptor const & o) const
249 {
250 return !Policy::equal(adaptee_, o.adaptee_);
251 }
252
253 bool operator<(IteratorAdaptor const & o) const
254 {
255 return Policy::less(adaptee_, o.adaptee_);
256 }
257
258 bool operator<=(IteratorAdaptor const & o) const
259 {
260 return !Policy::less(o.adaptee_, adaptee_);
261 }
262
263 bool operator>(IteratorAdaptor const & o) const
264 {
265 return Policy::less(o.adaptee_, adaptee_);
266 }
267
268 bool operator>=(IteratorAdaptor const & o) const
269 {
270 return !Policy::less(adaptee_, o.adaptee_);
271 }
272
273 difference_type operator-(IteratorAdaptor const & o) const
274 {
275 return Policy::difference(adaptee_, o.adaptee_);
276 }
277
278 reference operator*() const
279 {
280 return Policy::dereference(adaptee_);
281 }
282
283 index_reference operator[](difference_type d) const
284 {
285 return Policy::dereference(adaptee_, d);
286 }
287
288 pointer operator->() const
289 {
290 return &Policy::dereference(adaptee_);
291 }
292
293 protected:
294
295 BaseType adaptee_;
296};
297
298
299
300
301
302
303
304
305namespace detail_iterator_facade{
306
307
308
309
310}
311
312
313
314
315
316
317
318
319} // namespace vigra
320
321
322#endif /* VIGRA_ITERATORADAPTER_HXX */
Quickly create 1-dimensional iterator adapters.
Definition iteratoradapter.hxx:148
IteratorAdaptor(BaseType const &o)
Definition iteratoradapter.hxx:168

© 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.12.1