1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
21 #define INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX
23 #include <sal/types.h>
24 #include <osl/diagnose.h>
26 #include <basebmp/nonstandarditerator.hxx>
27 #include <vigra/tuple.hxx>
28 #include <vigra/iteratortraits.hxx>
36 template< typename T1
, typename T2
> class ArithmeticProxy
39 ArithmeticProxy(T1
& val1
, T2
& val2
) :
44 void operator++() { ++(*mpVal1
); ++(*mpVal2
); }
45 void operator++(int) { (*mpVal1
)++; (*mpVal2
)++; }
46 void operator--() { --(*mpVal1
); --(*mpVal2
); }
47 void operator--(int) { (*mpVal1
)--; (*mpVal2
)--; }
48 void operator+=(int d
) {*mpVal1
+=d
; *mpVal2
+=d
; }
49 void operator-=(int d
) {*mpVal1
-=d
; *mpVal2
-=d
; }
51 bool operator==(ArithmeticProxy
const & rhs
) const
52 { return *mpVal1
==*rhs
.mpVal1
&& *mpVal2
==*rhs
.mpVal2
; }
54 bool operator!=(ArithmeticProxy
const & rhs
) const
55 { return *mpVal1
!=*rhs
.mpVal1
|| *mpVal2
!=*rhs
.mpVal2
; }
57 bool operator<(ArithmeticProxy
const & rhs
) const
58 { return *mpVal1
<*rhs
.mpVal1
&& *mpVal2
<*rhs
.mpVal2
; }
60 bool operator<=(ArithmeticProxy
const & rhs
) const
61 { return *mpVal1
<=*rhs
.mpVal1
&& *mpVal2
<=*rhs
.mpVal2
; }
63 bool operator>(ArithmeticProxy
const & rhs
) const
64 { return *mpVal1
>*rhs
.mpVal1
&& *mpVal2
>*rhs
.mpVal2
; }
66 bool operator>=(ArithmeticProxy
const & rhs
) const
67 { return *mpVal1
>=*rhs
.mpVal1
&& *mpVal2
>=*rhs
.mpVal2
; }
69 int operator-(ArithmeticProxy
const & rhs
) const
70 { return *mpVal1
- *rhs
.mpVal1
; }
77 template< typename Iterator1
,
80 typename DifferenceType
,
81 typename IteratorCategory
,
83 class CompositeIteratorBase
: public NonStandardIterator
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
;
93 iterator1_type maIter1
;
94 iterator2_type maIter2
;
97 bool equal(CompositeIteratorBase
const & rhs
) const
99 return (maIter1
== rhs
.maIter1
) && (maIter2
== rhs
.maIter2
);
103 CompositeIteratorBase() :
108 CompositeIteratorBase( const iterator1_type
& rIter1
, const iterator2_type
& rIter2
) :
113 bool operator==(Derived
const & rhs
) const
118 bool operator!=(Derived
const & rhs
) const
123 difference_type
operator-(Derived
const & rhs
) const
125 OSL_ASSERT( maIter1
- rhs
.maIter1
== maIter2
- rhs
.maIter2
);
126 return maIter1
- rhs
.maIter1
;
129 Derived
& operator+=(difference_type
const & s
)
133 return static_cast<Derived
&>(*this);
136 Derived
& operator-=(difference_type
const & s
)
140 return static_cast<Derived
&>(*this);
143 Derived
operator+(difference_type
const & s
) const
145 Derived
ret(static_cast<Derived
const&>(*this));
150 Derived
operator-(difference_type
const & s
) const
152 Derived
ret(static_cast<Derived
const&>(*this));
157 Derived
& operator++()
161 return static_cast<Derived
&>(*this);
164 Derived
& operator--()
168 return static_cast<Derived
&>(*this);
171 Derived
operator++(int)
173 Derived
ret(static_cast<Derived
const&>(*this));
179 Derived
operator--(int)
181 Derived
ret(static_cast<Derived
const&>(*this));
187 value_type
get() const
189 return value_type(maIter1
.get(),
193 value_type
get(difference_type
const & d
) const
195 return value_type(maIter1
.get(d
),
199 void set( value_type v
) const
205 void set( value_type v
, difference_type
const & d
) const
211 const iterator1_type
& first() const { return maIter1
; }
212 iterator1_type
& first() { return maIter1
; }
214 const iterator2_type
& second() const { return maIter2
; }
215 iterator2_type
& second() { return maIter2
; }
219 /** Provide the composition of two 1D image iterators
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.
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
229 template< typename Iterator1
,
232 typename DifferenceType
,
233 typename IteratorCategory
>
234 class CompositeIterator1D
:
235 public detail::CompositeIteratorBase
< Iterator1
,
240 CompositeIterator1D
<Iterator1
,
246 typedef detail::CompositeIteratorBase
< Iterator1
,
251 CompositeIterator1D
<Iterator1
,
255 IteratorCategory
> > base_type
;
257 CompositeIterator1D() :
261 CompositeIterator1D( const Iterator1
& rIter1
,
262 const Iterator2
& rIter2
) :
263 base_type( rIter1
, rIter2
)
267 /** Provide the composition of two 2D image iterators
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.
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
277 template< typename Iterator1
, typename Iterator2
> class CompositeIterator2D
:
278 public detail::CompositeIteratorBase
< Iterator1
,
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
> >
287 typedef detail::CompositeIteratorBase
< Iterator1
,
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
;
296 typedef CompositeIterator1D
< typename
Iterator1::row_iterator
,
297 typename
Iterator2::row_iterator
,
298 typename
base_type::value_type
,
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
,
305 typename
base_type::iterator_category
> column_iterator
;
307 typedef detail::ArithmeticProxy
< typename
Iterator1::MoveX
,
308 typename
Iterator2::MoveX
> MoveX
;
309 typedef detail::ArithmeticProxy
< typename
Iterator1::MoveY
,
310 typename
Iterator2::MoveY
> MoveY
;
315 CompositeIterator2D() :
317 x(this->maIter1
.x
,this->maIter2
.x
),
318 y(this->maIter1
.y
,this->maIter2
.y
)
321 CompositeIterator2D( const Iterator1
& rIter1
, const Iterator2
& rIter2
) :
322 base_type( rIter1
, rIter2
),
323 x(this->maIter1
.x
,this->maIter2
.x
),
324 y(this->maIter1
.y
,this->maIter2
.y
)
327 CompositeIterator2D( const CompositeIterator2D
& rOld
) :
329 x(this->maIter1
.x
,this->maIter2
.x
),
330 y(this->maIter1
.y
,this->maIter2
.y
)
333 CompositeIterator2D
& operator=( const CompositeIterator2D
& rNew
)
335 this->maIter1
= rNew
.maIter1
;
336 this->maIter2
= rNew
.maIter2
;
338 x
= MoveX(this->maIter1
.x
,
340 y
= MoveY(this->maIter1
.y
,
344 row_iterator
rowIterator() const
346 return row_iterator(this->maIter1
.rowIterator(),
347 this->maIter2
.rowIterator());
350 column_iterator
columnIterator() const
352 return column_iterator(this->maIter1
.columnIterator(),
353 this->maIter2
.columnIterator());
357 } // namespace basebmp
359 #endif /* INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX */
361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */