Branch data 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 : 1230862 : ArithmeticProxy(T1& val1, T2& val2) :
40 : : mpVal1( &val1 ),
41 : 1230862 : mpVal2( &val2 )
42 : 1230862 : {}
43 : :
44 : 1768508 : void operator++() { ++(*mpVal1); ++(*mpVal2); }
45 : : void operator++(int) { (*mpVal1)++; (*mpVal2)++; }
46 : : void operator--() { --(*mpVal1); --(*mpVal2); }
47 : : void operator--(int) { (*mpVal1)--; (*mpVal2)--; }
48 : 10598 : 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 : 166007 : bool operator<(ArithmeticProxy const & rhs) const
58 [ + + ][ + - ]: 166007 : { 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 : 14655 : int operator-(ArithmeticProxy const & rhs) const
70 : 14655 : { 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 : 181332 : 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 : 218426548 : bool equal(CompositeIteratorBase const & rhs) const
98 : : {
99 [ + + ][ + - ]: 218426548 : return (maIter1 == rhs.maIter1) && (maIter2 == rhs.maIter2);
[ + + ][ + - ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ][ + - ]
[ # # ][ # # ]
[ + + ][ + - ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ][ + - ]
[ # # ][ # # ]
[ + + ][ + - ]
100 : : }
101 : :
102 : : public:
103 : : CompositeIteratorBase() :
104 : : maIter1(),
105 : : maIter2()
106 : : {}
107 : :
108 : 2174427 : CompositeIteratorBase( const iterator1_type& rIter1, const iterator2_type& rIter2 ) :
109 : : maIter1( rIter1 ),
110 : 2174427 : maIter2( rIter2 )
111 : 2174427 : {}
112 : :
113 : 0 : bool operator==(Derived const & rhs) const
114 : : {
115 : 0 : return equal(rhs);
116 : : }
117 : :
118 : 218426548 : bool operator!=(Derived const & rhs) const
119 : : {
120 : 218426548 : return !equal(rhs);
121 : : }
122 : :
123 : 140 : difference_type operator-(Derived const & rhs) const
124 : : {
125 : : OSL_ASSERT( maIter1 - rhs.maIter1 == maIter2 - rhs.maIter2 );
126 : 140 : return maIter1 - rhs.maIter1;
127 : : }
128 : :
129 : 4841630 : Derived & operator+=(difference_type const & s)
130 : : {
131 : 1490665 : maIter1 += s;
132 : 4841630 : maIter2 += s;
133 : 4841630 : 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 : 2932108 : Derived operator+(difference_type const & s) const
144 : : {
145 : 347508 : Derived ret(static_cast<Derived const&>(*this));
146 : 2932108 : ret += s;
147 : 2932108 : 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 : 32565020 : Derived& operator++()
158 : : {
159 : 25344262 : ++maIter1;
160 : 32565020 : ++maIter2;
161 : 32565020 : return static_cast<Derived&>(*this);
162 : : }
163 : :
164 : : Derived& operator--()
165 : : {
166 : : --maIter1;
167 : : --maIter2;
168 : : return static_cast<Derived&>(*this);
169 : : }
170 : :
171 : 191678017 : Derived operator++(int)
172 : : {
173 : 191678017 : Derived ret(static_cast<Derived const&>(*this));
174 : 1210 : ++maIter1;
175 : 191678017 : ++maIter2;
176 : 191678017 : 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 : 427643510 : const iterator1_type& first() const { return maIter1; }
212 : : iterator1_type& first() { return maIter1; }
213 : :
214 : 226361124 : 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 : 162810 : 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 : 1955197 : CompositeIterator1D( const Iterator1& rIter1,
262 : : const Iterator2& rIter2 ) :
263 : 1955197 : base_type( rIter1, rIter2 )
264 : 1955197 : {}
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 : 219230 : CompositeIterator2D( const Iterator1& rIter1, const Iterator2& rIter2 ) :
322 : : base_type( rIter1, rIter2 ),
323 : : x(this->maIter1.x,this->maIter2.x),
324 : 219230 : y(this->maIter1.y,this->maIter2.y)
325 : 219230 : {}
326 : :
327 : 396201 : CompositeIterator2D( const CompositeIterator2D& rOld ) :
328 : : base_type(rOld),
329 : : x(this->maIter1.x,this->maIter2.x),
330 : 396201 : y(this->maIter1.y,this->maIter2.y)
331 : 396201 : {}
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 : 1928846 : row_iterator rowIterator() const
345 : : {
346 : : return row_iterator(this->maIter1.rowIterator(),
347 [ + - ][ + - ]: 1928846 : this->maIter2.rowIterator());
[ # # ][ # # ]
[ + - ][ + - ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + - ][ + - ]
[ # # ][ # # ]
[ + - ][ + - ]
348 : : }
349 : :
350 : 26351 : column_iterator columnIterator() const
351 : : {
352 : : return column_iterator(this->maIter1.columnIterator(),
353 [ + - ][ + - ]: 26351 : 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: */
|