Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
21 : #define INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
22 :
23 : #include <sal/types.h>
24 : #include <osl/diagnose.h>
25 :
26 : #include <basebmp/nonstandarditerator.hxx>
27 : #include <vigra/tuple.hxx>
28 : #include <vigra/iteratortraits.hxx>
29 :
30 :
31 : namespace basebmp
32 : {
33 :
34 : namespace detail
35 : {
36 : template< typename T1, typename T2 > class ArithmeticProxy
37 : {
38 : public:
39 0 : ArithmeticProxy(T1& val1, T2& val2) :
40 : mpVal1( &val1 ),
41 0 : mpVal2( &val2 )
42 0 : {}
43 :
44 0 : void operator++() { ++(*mpVal1); ++(*mpVal2); }
45 : void operator++(int) { (*mpVal1)++; (*mpVal2)++; }
46 : void operator--() { --(*mpVal1); --(*mpVal2); }
47 : void operator--(int) { (*mpVal1)--; (*mpVal2)--; }
48 0 : void operator+=(int d) {*mpVal1+=d; *mpVal2+=d; }
49 : void operator-=(int d) {*mpVal1-=d; *mpVal2-=d; }
50 :
51 : bool operator==(ArithmeticProxy const & rhs) const
52 : { return *mpVal1==*rhs.mpVal1 && *mpVal2==*rhs.mpVal2; }
53 :
54 : bool operator!=(ArithmeticProxy const & rhs) const
55 : { return *mpVal1!=*rhs.mpVal1 || *mpVal2!=*rhs.mpVal2; }
56 :
57 0 : bool operator<(ArithmeticProxy const & rhs) const
58 0 : { return *mpVal1<*rhs.mpVal1 && *mpVal2<*rhs.mpVal2; }
59 :
60 : bool operator<=(ArithmeticProxy const & rhs) const
61 : { return *mpVal1<=*rhs.mpVal1 && *mpVal2<=*rhs.mpVal2; }
62 :
63 : bool operator>(ArithmeticProxy const & rhs) const
64 : { return *mpVal1>*rhs.mpVal1 && *mpVal2>*rhs.mpVal2; }
65 :
66 : bool operator>=(ArithmeticProxy const & rhs) const
67 : { return *mpVal1>=*rhs.mpVal1 && *mpVal2>=*rhs.mpVal2; }
68 :
69 0 : int operator-(ArithmeticProxy const & rhs) const
70 0 : { return *mpVal1 - *rhs.mpVal1; }
71 :
72 : private:
73 : T1* mpVal1;
74 : T2* mpVal2;
75 : };
76 :
77 : template< typename Iterator1,
78 : typename Iterator2,
79 : typename ValueType,
80 : typename DifferenceType,
81 : typename IteratorCategory,
82 : class Derived >
83 0 : class CompositeIteratorBase : public NonStandardIterator
84 : {
85 : public:
86 : typedef Iterator1 iterator1_type;
87 : typedef Iterator2 iterator2_type;
88 : typedef ValueType value_type;
89 : typedef DifferenceType difference_type;
90 : typedef IteratorCategory iterator_category;
91 :
92 : protected:
93 : iterator1_type maIter1;
94 : iterator2_type maIter2;
95 :
96 : private:
97 0 : bool equal(CompositeIteratorBase const & rhs) const
98 : {
99 0 : return (maIter1 == rhs.maIter1) && (maIter2 == rhs.maIter2);
100 : }
101 :
102 : public:
103 : CompositeIteratorBase() :
104 : maIter1(),
105 : maIter2()
106 : {}
107 :
108 0 : CompositeIteratorBase( const iterator1_type& rIter1, const iterator2_type& rIter2 ) :
109 : maIter1( rIter1 ),
110 0 : maIter2( rIter2 )
111 0 : {}
112 :
113 0 : bool operator==(Derived const & rhs) const
114 : {
115 0 : return equal(rhs);
116 : }
117 :
118 0 : bool operator!=(Derived const & rhs) const
119 : {
120 0 : return !equal(rhs);
121 : }
122 :
123 0 : difference_type operator-(Derived const & rhs) const
124 : {
125 : OSL_ASSERT( maIter1 - rhs.maIter1 == maIter2 - rhs.maIter2 );
126 0 : return maIter1 - rhs.maIter1;
127 : }
128 :
129 0 : Derived & operator+=(difference_type const & s)
130 : {
131 0 : maIter1 += s;
132 0 : maIter2 += s;
133 0 : return static_cast<Derived&>(*this);
134 : }
135 :
136 : Derived & operator-=(difference_type const & s)
137 : {
138 : maIter1 -= s;
139 : maIter2 -= s;
140 : return static_cast<Derived&>(*this);
141 : }
142 :
143 0 : Derived operator+(difference_type const & s) const
144 : {
145 0 : Derived ret(static_cast<Derived const&>(*this));
146 0 : ret += s;
147 0 : return ret;
148 : }
149 :
150 : Derived operator-(difference_type const & s) const
151 : {
152 : Derived ret(static_cast<Derived const&>(*this));
153 : ret -= s;
154 : return ret;
155 : }
156 :
157 0 : Derived& operator++()
158 : {
159 0 : ++maIter1;
160 0 : ++maIter2;
161 0 : return static_cast<Derived&>(*this);
162 : }
163 :
164 : Derived& operator--()
165 : {
166 : --maIter1;
167 : --maIter2;
168 : return static_cast<Derived&>(*this);
169 : }
170 :
171 0 : Derived operator++(int)
172 : {
173 0 : Derived ret(static_cast<Derived const&>(*this));
174 0 : ++maIter1;
175 0 : ++maIter2;
176 0 : return ret;
177 : }
178 :
179 : Derived operator--(int)
180 : {
181 : Derived ret(static_cast<Derived const&>(*this));
182 : --maIter1;
183 : --maIter2;
184 : return ret;
185 : }
186 :
187 : value_type get() const
188 : {
189 : return value_type(maIter1.get(),
190 : maIter2.get());
191 : }
192 :
193 : value_type get(difference_type const & d) const
194 : {
195 : return value_type(maIter1.get(d),
196 : maIter2.get(d));
197 : }
198 :
199 : void set( value_type v ) const
200 : {
201 : maIter1.set(v);
202 : maIter2.set(v);
203 : }
204 :
205 : void set( value_type v, difference_type const & d ) const
206 : {
207 : maIter1.set(v,d);
208 : maIter2.set(v,d);
209 : }
210 :
211 0 : const iterator1_type& first() const { return maIter1; }
212 : iterator1_type& first() { return maIter1; }
213 :
214 0 : const iterator2_type& second() const { return maIter2; }
215 : iterator2_type& second() { return maIter2; }
216 : };
217 : }
218 :
219 : /** Provide the composition of two 1D image iterators
220 :
221 : Use this template to compose two iterators into one (e.g. image
222 : and mask). Operations are transitive, e.g. operator== only returns
223 : true, if both wrapped iterator operator== have yielded true.
224 :
225 : Note that both iterators must have compatible difference types. To
226 : avoid funny effects, iterator ranges given by a CompositeIterator
227 : should consist of wrapped iterators of similar range
228 : */
229 : template< typename Iterator1,
230 : typename Iterator2,
231 : typename ValueType,
232 : typename DifferenceType,
233 : typename IteratorCategory >
234 0 : class CompositeIterator1D :
235 : public detail::CompositeIteratorBase< Iterator1,
236 : Iterator2,
237 : ValueType,
238 : DifferenceType,
239 : IteratorCategory,
240 : CompositeIterator1D<Iterator1,
241 : Iterator2,
242 : ValueType,
243 : DifferenceType,
244 : IteratorCategory> >
245 : {
246 : typedef detail::CompositeIteratorBase< Iterator1,
247 : Iterator2,
248 : ValueType,
249 : DifferenceType,
250 : IteratorCategory,
251 : CompositeIterator1D<Iterator1,
252 : Iterator2,
253 : ValueType,
254 : DifferenceType,
255 : IteratorCategory> > base_type;
256 : public:
257 : CompositeIterator1D() :
258 : base_type()
259 : {}
260 :
261 0 : CompositeIterator1D( const Iterator1& rIter1,
262 : const Iterator2& rIter2 ) :
263 0 : base_type( rIter1, rIter2 )
264 0 : {}
265 : };
266 :
267 : /** Provide the composition of two 2D image iterators
268 :
269 : Use this template to compose two iterators into one (e.g. image
270 : and mask). Operations are transitive, e.g. operator== only returns
271 : true, if both wrapped iterator operator== have yielded true.
272 :
273 : Note that both iterators must have compatible difference types. To
274 : avoid funny effects, iterator ranges given by a CompositeIterator
275 : should consist of wrapped iterators of similar range
276 : */
277 : template< typename Iterator1, typename Iterator2 > class CompositeIterator2D :
278 : public detail::CompositeIteratorBase< Iterator1,
279 : Iterator2,
280 : std::pair<
281 : typename vigra::IteratorTraits<Iterator1>::value_type,
282 : typename vigra::IteratorTraits<Iterator2>::value_type >,
283 : typename vigra::IteratorTraits<Iterator1>::difference_type,
284 : typename vigra::IteratorTraits<Iterator1>::iterator_category,
285 : CompositeIterator2D<Iterator1, Iterator2> >
286 : {
287 : typedef detail::CompositeIteratorBase< Iterator1,
288 : Iterator2,
289 : std::pair<
290 : typename vigra::IteratorTraits<Iterator1>::value_type,
291 : typename vigra::IteratorTraits<Iterator2>::value_type >,
292 : typename vigra::IteratorTraits<Iterator1>::difference_type,
293 : typename vigra::IteratorTraits<Iterator1>::iterator_category,
294 : CompositeIterator2D<Iterator1, Iterator2> > base_type;
295 : public:
296 : typedef CompositeIterator1D< typename Iterator1::row_iterator,
297 : typename Iterator2::row_iterator,
298 : typename base_type::value_type,
299 : int,
300 : typename base_type::iterator_category > row_iterator;
301 : typedef CompositeIterator1D< typename Iterator1::column_iterator,
302 : typename Iterator2::column_iterator,
303 : typename base_type::value_type,
304 : int,
305 : typename base_type::iterator_category > column_iterator;
306 :
307 : typedef detail::ArithmeticProxy< typename Iterator1::MoveX,
308 : typename Iterator2::MoveX > MoveX;
309 : typedef detail::ArithmeticProxy< typename Iterator1::MoveY,
310 : typename Iterator2::MoveY > MoveY;
311 :
312 : MoveX x;
313 : MoveY y;
314 :
315 : CompositeIterator2D() :
316 : base_type(),
317 : x(this->maIter1.x,this->maIter2.x),
318 : y(this->maIter1.y,this->maIter2.y)
319 : {}
320 :
321 0 : CompositeIterator2D( const Iterator1& rIter1, const Iterator2& rIter2 ) :
322 : base_type( rIter1, rIter2 ),
323 : x(this->maIter1.x,this->maIter2.x),
324 0 : y(this->maIter1.y,this->maIter2.y)
325 0 : {}
326 :
327 0 : CompositeIterator2D( const CompositeIterator2D& rOld ) :
328 : base_type(rOld),
329 : x(this->maIter1.x,this->maIter2.x),
330 0 : y(this->maIter1.y,this->maIter2.y)
331 0 : {}
332 :
333 : CompositeIterator2D& operator=( const CompositeIterator2D& rNew )
334 : {
335 : this->maIter1 = rNew.maIter1;
336 : this->maIter2 = rNew.maIter2;
337 :
338 : x = MoveX(this->maIter1.x,
339 : this->maIter2.x);
340 : y = MoveY(this->maIter1.y,
341 : this->maIter2.y);
342 : }
343 :
344 0 : row_iterator rowIterator() const
345 : {
346 : return row_iterator(this->maIter1.rowIterator(),
347 0 : this->maIter2.rowIterator());
348 : }
349 :
350 0 : column_iterator columnIterator() const
351 : {
352 : return column_iterator(this->maIter1.columnIterator(),
353 0 : this->maIter2.columnIterator());
354 : }
355 : };
356 :
357 : } // namespace basebmp
358 :
359 : #endif /* INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX */
360 :
361 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|