1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX 29 #define INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX 30 31 #include <sal/types.h> 32 #include <osl/diagnose.h> 33 34 #include <basebmp/nonstandarditerator.hxx> 35 #include <vigra/tuple.hxx> 36 #include <vigra/iteratortraits.hxx> 37 38 39 namespace basebmp 40 { 41 42 namespace detail 43 { 44 template< typename T1, typename T2 > class ArithmeticProxy 45 { 46 public: 47 ArithmeticProxy(T1& val1, T2& val2) : 48 mpVal1( &val1 ), 49 mpVal2( &val2 ) 50 {} 51 52 void operator++() { ++(*mpVal1); ++(*mpVal2); } 53 void operator++(int) { (*mpVal1)++; (*mpVal2)++; } 54 void operator--() { --(*mpVal1); --(*mpVal2); } 55 void operator--(int) { (*mpVal1)--; (*mpVal2)--; } 56 void operator+=(int d) {*mpVal1+=d; *mpVal2+=d; } 57 void operator-=(int d) {*mpVal1-=d; *mpVal2-=d; } 58 59 bool operator==(ArithmeticProxy const & rhs) const 60 { return *mpVal1==*rhs.mpVal1 && *mpVal2==*rhs.mpVal2; } 61 62 bool operator!=(ArithmeticProxy const & rhs) const 63 { return *mpVal1!=*rhs.mpVal1 || *mpVal2!=*rhs.mpVal2; } 64 65 bool operator<(ArithmeticProxy const & rhs) const 66 { return *mpVal1<*rhs.mpVal1 && *mpVal2<*rhs.mpVal2; } 67 68 bool operator<=(ArithmeticProxy const & rhs) const 69 { return *mpVal1<=*rhs.mpVal1 && *mpVal2<=*rhs.mpVal2; } 70 71 bool operator>(ArithmeticProxy const & rhs) const 72 { return *mpVal1>*rhs.mpVal1 && *mpVal2>*rhs.mpVal2; } 73 74 bool operator>=(ArithmeticProxy const & rhs) const 75 { return *mpVal1>=*rhs.mpVal1 && *mpVal2>=*rhs.mpVal2; } 76 77 int operator-(ArithmeticProxy const & rhs) const 78 { return *mpVal1 - *rhs.mpVal1; } 79 80 private: 81 T1* mpVal1; 82 T2* mpVal2; 83 }; 84 85 template< typename Iterator1, 86 typename Iterator2, 87 typename ValueType, 88 typename DifferenceType, 89 typename IteratorCategory, 90 class Derived > 91 class CompositeIteratorBase : public NonStandardIterator 92 { 93 public: 94 typedef Iterator1 iterator1_type; 95 typedef Iterator2 iterator2_type; 96 typedef ValueType value_type; 97 typedef DifferenceType difference_type; 98 typedef IteratorCategory iterator_category; 99 100 protected: 101 iterator1_type maIter1; 102 iterator2_type maIter2; 103 104 private: 105 bool equal(CompositeIteratorBase const & rhs) const 106 { 107 return (maIter1 == rhs.maIter1) && (maIter2 == rhs.maIter2); 108 } 109 110 public: 111 CompositeIteratorBase() : 112 maIter1(), 113 maIter2() 114 {} 115 116 CompositeIteratorBase( const iterator1_type& rIter1, const iterator2_type& rIter2 ) : 117 maIter1( rIter1 ), 118 maIter2( rIter2 ) 119 {} 120 121 bool operator==(Derived const & rhs) const 122 { 123 return equal(rhs); 124 } 125 126 bool operator!=(Derived const & rhs) const 127 { 128 return !equal(rhs); 129 } 130 131 difference_type operator-(Derived const & rhs) const 132 { 133 OSL_ASSERT( maIter1 - rhs.maIter1 == maIter2 - rhs.maIter2 ); 134 return maIter1 - rhs.maIter1; 135 } 136 137 Derived & operator+=(difference_type const & s) 138 { 139 maIter1 += s; 140 maIter2 += s; 141 return static_cast<Derived&>(*this); 142 } 143 144 Derived & operator-=(difference_type const & s) 145 { 146 maIter1 -= s; 147 maIter2 -= s; 148 return static_cast<Derived&>(*this); 149 } 150 151 Derived operator+(difference_type const & s) const 152 { 153 Derived ret(static_cast<Derived const&>(*this)); 154 ret += s; 155 return ret; 156 } 157 158 Derived operator-(difference_type const & s) const 159 { 160 Derived ret(static_cast<Derived const&>(*this)); 161 ret -= s; 162 return ret; 163 } 164 165 Derived& operator++() 166 { 167 ++maIter1; 168 ++maIter2; 169 return static_cast<Derived&>(*this); 170 } 171 172 Derived& operator--() 173 { 174 --maIter1; 175 --maIter2; 176 return static_cast<Derived&>(*this); 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 Derived operator--(int) 188 { 189 Derived ret(static_cast<Derived const&>(*this)); 190 --maIter1; 191 --maIter2; 192 return ret; 193 } 194 195 value_type get() const 196 { 197 return value_type(maIter1.get(), 198 maIter2.get()); 199 } 200 201 value_type get(difference_type const & d) const 202 { 203 return value_type(maIter1.get(d), 204 maIter2.get(d)); 205 } 206 207 void set( value_type v ) const 208 { 209 maIter1.set(v); 210 maIter2.set(v); 211 } 212 213 void set( value_type v, difference_type const & d ) const 214 { 215 maIter1.set(v,d); 216 maIter2.set(v,d); 217 } 218 219 const iterator1_type& first() const { return maIter1; } 220 iterator1_type& first() { return maIter1; } 221 222 const iterator2_type& second() const { return maIter2; } 223 iterator2_type& second() { return maIter2; } 224 }; 225 } 226 227 /** Provide the composition of two 1D image iterators 228 229 Use this template to compose two iterators into one (e.g. image 230 and mask). Operations are transitive, e.g. operator== only returns 231 true, if both wrapped iterator operator== have yielded true. 232 233 Note that both iterators must have compatible difference types. To 234 avoid funny effects, iterator ranges given by a CompositeIterator 235 should consist of wrapped iterators of similar range 236 */ 237 template< typename Iterator1, 238 typename Iterator2, 239 typename ValueType, 240 typename DifferenceType, 241 typename IteratorCategory > 242 class CompositeIterator1D : 243 public detail::CompositeIteratorBase< Iterator1, 244 Iterator2, 245 ValueType, 246 DifferenceType, 247 IteratorCategory, 248 CompositeIterator1D<Iterator1, 249 Iterator2, 250 ValueType, 251 DifferenceType, 252 IteratorCategory> > 253 { 254 typedef detail::CompositeIteratorBase< Iterator1, 255 Iterator2, 256 ValueType, 257 DifferenceType, 258 IteratorCategory, 259 CompositeIterator1D<Iterator1, 260 Iterator2, 261 ValueType, 262 DifferenceType, 263 IteratorCategory> > base_type; 264 public: 265 CompositeIterator1D() : 266 base_type() 267 {} 268 269 CompositeIterator1D( const Iterator1& rIter1, 270 const Iterator2& rIter2 ) : 271 base_type( rIter1, rIter2 ) 272 {} 273 }; 274 275 /** Provide the composition of two 2D image iterators 276 277 Use this template to compose two iterators into one (e.g. image 278 and mask). Operations are transitive, e.g. operator== only returns 279 true, if both wrapped iterator operator== have yielded true. 280 281 Note that both iterators must have compatible difference types. To 282 avoid funny effects, iterator ranges given by a CompositeIterator 283 should consist of wrapped iterators of similar range 284 */ 285 template< typename Iterator1, typename Iterator2 > class CompositeIterator2D : 286 public detail::CompositeIteratorBase< Iterator1, 287 Iterator2, 288 std::pair< 289 typename vigra::IteratorTraits<Iterator1>::value_type, 290 typename vigra::IteratorTraits<Iterator2>::value_type >, 291 typename vigra::IteratorTraits<Iterator1>::difference_type, 292 typename vigra::IteratorTraits<Iterator1>::iterator_category, 293 CompositeIterator2D<Iterator1, Iterator2> > 294 { 295 typedef detail::CompositeIteratorBase< Iterator1, 296 Iterator2, 297 std::pair< 298 typename vigra::IteratorTraits<Iterator1>::value_type, 299 typename vigra::IteratorTraits<Iterator2>::value_type >, 300 typename vigra::IteratorTraits<Iterator1>::difference_type, 301 typename vigra::IteratorTraits<Iterator1>::iterator_category, 302 CompositeIterator2D<Iterator1, Iterator2> > base_type; 303 public: 304 typedef CompositeIterator1D< typename Iterator1::row_iterator, 305 typename Iterator2::row_iterator, 306 typename base_type::value_type, 307 int, 308 typename base_type::iterator_category > row_iterator; 309 typedef CompositeIterator1D< typename Iterator1::column_iterator, 310 typename Iterator2::column_iterator, 311 typename base_type::value_type, 312 int, 313 typename base_type::iterator_category > column_iterator; 314 315 typedef detail::ArithmeticProxy< typename Iterator1::MoveX, 316 typename Iterator2::MoveX > MoveX; 317 typedef detail::ArithmeticProxy< typename Iterator1::MoveY, 318 typename Iterator2::MoveY > MoveY; 319 320 MoveX x; 321 MoveY y; 322 323 CompositeIterator2D() : 324 base_type(), 325 x(this->maIter1.x,this->maIter2.x), 326 y(this->maIter1.y,this->maIter2.y) 327 {} 328 329 CompositeIterator2D( const Iterator1& rIter1, const Iterator2& rIter2 ) : 330 base_type( rIter1, rIter2 ), 331 x(this->maIter1.x,this->maIter2.x), 332 y(this->maIter1.y,this->maIter2.y) 333 {} 334 335 CompositeIterator2D( const CompositeIterator2D& rOld ) : 336 base_type(rOld), 337 x(this->maIter1.x,this->maIter2.x), 338 y(this->maIter1.y,this->maIter2.y) 339 {} 340 341 CompositeIterator2D& operator=( const CompositeIterator2D& rNew ) 342 { 343 this->maIter1 = rNew.maIter1; 344 this->maIter2 = rNew.maIter2; 345 346 x = MoveX(this->maIter1.x, 347 this->maIter2.x); 348 y = MoveY(this->maIter1.y, 349 this->maIter2.y); 350 } 351 352 row_iterator rowIterator() const 353 { 354 return row_iterator(this->maIter1.rowIterator(), 355 this->maIter2.rowIterator()); 356 } 357 358 column_iterator columnIterator() const 359 { 360 return column_iterator(this->maIter1.columnIterator(), 361 this->maIter2.columnIterator()); 362 } 363 }; 364 365 } // namespace basebmp 366 367 #endif /* INCLUDED_BASEBMP_COMPOSITEITERATOR_HXX */ 368