update credits
[LibreOffice.git] / include / basebmp / compositeiterator.hxx
blob4fb9c10f0bb4f48dc2a2b9149104fbeedda83b7e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
31 namespace basebmp
34 namespace detail
36 template< typename T1, typename T2 > class ArithmeticProxy
38 public:
39 ArithmeticProxy(T1& val1, T2& val2) :
40 mpVal1( &val1 ),
41 mpVal2( &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; }
72 private:
73 T1* mpVal1;
74 T2* mpVal2;
77 template< typename Iterator1,
78 typename Iterator2,
79 typename ValueType,
80 typename DifferenceType,
81 typename IteratorCategory,
82 class Derived >
83 class CompositeIteratorBase : public NonStandardIterator
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;
92 protected:
93 iterator1_type maIter1;
94 iterator2_type maIter2;
96 private:
97 bool equal(CompositeIteratorBase const & rhs) const
99 return (maIter1 == rhs.maIter1) && (maIter2 == rhs.maIter2);
102 public:
103 CompositeIteratorBase() :
104 maIter1(),
105 maIter2()
108 CompositeIteratorBase( const iterator1_type& rIter1, const iterator2_type& rIter2 ) :
109 maIter1( rIter1 ),
110 maIter2( rIter2 )
113 bool operator==(Derived const & rhs) const
115 return equal(rhs);
118 bool operator!=(Derived const & rhs) const
120 return !equal(rhs);
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)
131 maIter1 += s;
132 maIter2 += s;
133 return static_cast<Derived&>(*this);
136 Derived & operator-=(difference_type const & s)
138 maIter1 -= s;
139 maIter2 -= s;
140 return static_cast<Derived&>(*this);
143 Derived operator+(difference_type const & s) const
145 Derived ret(static_cast<Derived const&>(*this));
146 ret += s;
147 return ret;
150 Derived operator-(difference_type const & s) const
152 Derived ret(static_cast<Derived const&>(*this));
153 ret -= s;
154 return ret;
157 Derived& operator++()
159 ++maIter1;
160 ++maIter2;
161 return static_cast<Derived&>(*this);
164 Derived& operator--()
166 --maIter1;
167 --maIter2;
168 return static_cast<Derived&>(*this);
171 Derived operator++(int)
173 Derived ret(static_cast<Derived const&>(*this));
174 ++maIter1;
175 ++maIter2;
176 return ret;
179 Derived operator--(int)
181 Derived ret(static_cast<Derived const&>(*this));
182 --maIter1;
183 --maIter2;
184 return ret;
187 value_type get() const
189 return value_type(maIter1.get(),
190 maIter2.get());
193 value_type get(difference_type const & d) const
195 return value_type(maIter1.get(d),
196 maIter2.get(d));
199 void set( value_type v ) const
201 maIter1.set(v);
202 maIter2.set(v);
205 void set( value_type v, difference_type const & d ) const
207 maIter1.set(v,d);
208 maIter2.set(v,d);
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,
230 typename Iterator2,
231 typename ValueType,
232 typename DifferenceType,
233 typename IteratorCategory >
234 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> >
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()
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,
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> >
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;
307 typedef detail::ArithmeticProxy< typename Iterator1::MoveX,
308 typename Iterator2::MoveX > MoveX;
309 typedef detail::ArithmeticProxy< typename Iterator1::MoveY,
310 typename Iterator2::MoveY > MoveY;
312 MoveX x;
313 MoveY y;
315 CompositeIterator2D() :
316 base_type(),
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 ) :
328 base_type(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,
339 this->maIter2.x);
340 y = MoveY(this->maIter1.y,
341 this->maIter2.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: */