1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX 25 #define INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX 26 27 #include <vigra/numerictraits.hxx> 28 29 namespace basebmp 30 { 31 32 /** Interpose given accessor's set and get methods with two unary 33 functors. 34 35 @tpl WrappedAccessor 36 Wrapped type must provide the usual get and set accessor methods, 37 with the usual signatures (see StandardAccessor for a conforming 38 example). 39 40 @tpl GetterFunctor 41 An Adaptable Unary Function (i.e. providing result_type and 42 argument_type typedefs) 43 44 @tpl SetterFunctor 45 An Adaptable Unary Function (i.e. providing result_type and 46 argument_type typedefs) 47 */ 48 template< class WrappedAccessor, 49 typename GetterFunctor, 50 typename SetterFunctor > class UnaryFunctionAccessorAdapter 51 { 52 public: 53 typedef typename GetterFunctor::result_type value_type; 54 typedef typename SetterFunctor::argument_type argument_type; 55 56 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 57 // making all members public, if no member template friends 58 private: 59 template<class A, typename G, typename S> friend class UnaryFunctionAccessorAdapter; 60 #endif 61 62 // we don't derive from wrapped type, to avoid ambiguities 63 // regarding templatized getter/setter methods. 64 WrappedAccessor maAccessor; 65 GetterFunctor maGetterFunctor; 66 SetterFunctor maSetterFunctor; 67 68 public: UnaryFunctionAccessorAdapter()69 UnaryFunctionAccessorAdapter() : 70 maAccessor(), 71 maGetterFunctor(), 72 maSetterFunctor() 73 {} 74 75 template< class A > explicit UnaryFunctionAccessorAdapter(UnaryFunctionAccessorAdapter<A,GetterFunctor,SetterFunctor> const & rSrc)76 UnaryFunctionAccessorAdapter( UnaryFunctionAccessorAdapter< A, 77 GetterFunctor, 78 SetterFunctor > const& rSrc ) : 79 maAccessor( rSrc.maAccessor ), 80 maGetterFunctor( rSrc.maGetterFunctor ), 81 maSetterFunctor( rSrc.maSetterFunctor ) 82 {} 83 UnaryFunctionAccessorAdapter(T const & accessor)84 template< class T > explicit UnaryFunctionAccessorAdapter( T const& accessor ) : 85 maAccessor( accessor ), 86 maGetterFunctor(), 87 maSetterFunctor() 88 {} 89 UnaryFunctionAccessorAdapter(T accessor,GetterFunctor getterFunctor,SetterFunctor setterFunctor)90 template< class T > UnaryFunctionAccessorAdapter( T accessor, 91 GetterFunctor getterFunctor, 92 SetterFunctor setterFunctor) : 93 maAccessor( accessor ), 94 maGetterFunctor( getterFunctor ), 95 maSetterFunctor( setterFunctor ) 96 {} 97 98 // ------------------------------------------------------- 99 getWrappedAccessor() const100 WrappedAccessor const& getWrappedAccessor() const { return maAccessor; } getWrappedAccessor()101 WrappedAccessor& getWrappedAccessor() { return maAccessor; } 102 103 // ------------------------------------------------------- 104 getter(typename GetterFunctor::argument_type v) const105 value_type getter(typename GetterFunctor::argument_type v) const 106 { 107 return maGetterFunctor(v); 108 } setter(argument_type v) const109 typename SetterFunctor::result_type setter(argument_type v) const 110 { 111 return maSetterFunctor(v); 112 } 113 114 // ------------------------------------------------------- 115 116 template< class Iterator > operator ()(Iterator const & i) const117 value_type operator()(Iterator const& i) const 118 { 119 return maGetterFunctor( maAccessor(i) ); 120 } 121 122 template< class Iterator, class Difference > operator ()(Iterator const & i,Difference const & diff) const123 value_type operator()(Iterator const& i, Difference const& diff) const 124 { 125 return maGetterFunctor( maAccessor(i,diff) ); 126 } 127 128 // ------------------------------------------------------- 129 130 template< typename V, class Iterator > set(V const & value,Iterator const & i) const131 void set(V const& value, Iterator const& i) const 132 { 133 maAccessor.set( 134 maSetterFunctor( 135 vigra::detail::RequiresExplicitCast<argument_type>::cast(value) ), 136 i ); 137 } 138 139 template< typename V, class Iterator, class Difference > set(V const & value,Iterator const & i,Difference const & diff) const140 void set(V const& value, Iterator const& i, Difference const& diff) const 141 { 142 maAccessor.set( 143 maSetterFunctor( 144 vigra::detail::RequiresExplicitCast<argument_type>::cast(value) ), 145 i, 146 diff ); 147 } 148 149 }; 150 151 //----------------------------------------------------------------------------- 152 153 /** Interpose given accessor's set methods with a binary function, 154 taking both old and new value. 155 156 The wrappee's getter methods kept as-is. 157 158 @tpl WrappedAccessor 159 Wrapped type must provide the usual get and set accessor methods, 160 with the usual signatures (see StandardAccessor for a conforming 161 example). Furthermore, must provide a nested typedef value_type. 162 163 @tpl SetterFunctor 164 An adaptable binary function (i.e. providing nested typedefs for 165 result_type and first and second argument type) 166 */ 167 template< class WrappedAccessor, 168 typename SetterFunctor > class BinarySetterFunctionAccessorAdapter 169 { 170 public: 171 typedef typename WrappedAccessor::value_type value_type; 172 typedef typename SetterFunctor::second_argument_type argument_type; 173 174 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 175 // making all members public, if no member template friends 176 private: 177 template<class A, typename S> friend class BinarySetterFunctionAccessorAdapter; 178 #endif 179 180 WrappedAccessor maAccessor; 181 SetterFunctor maFunctor; 182 183 public: BinarySetterFunctionAccessorAdapter()184 BinarySetterFunctionAccessorAdapter() : 185 maAccessor(), 186 maFunctor() 187 {} 188 189 template< class A > explicit BinarySetterFunctionAccessorAdapter(BinarySetterFunctionAccessorAdapter<A,SetterFunctor> const & rSrc)190 BinarySetterFunctionAccessorAdapter( 191 BinarySetterFunctionAccessorAdapter< A, 192 SetterFunctor > const& rSrc ) : 193 maAccessor( rSrc.maAccessor ), 194 maFunctor( rSrc.maFunctor ) 195 {} 196 BinarySetterFunctionAccessorAdapter(T const & accessor)197 template< class T > explicit BinarySetterFunctionAccessorAdapter( T const& accessor ) : 198 maAccessor( accessor ), 199 maFunctor() 200 {} 201 BinarySetterFunctionAccessorAdapter(T accessor,SetterFunctor functor)202 template< class T > BinarySetterFunctionAccessorAdapter( T accessor, 203 SetterFunctor functor ) : 204 maAccessor( accessor ), 205 maFunctor( functor ) 206 {} 207 208 // ------------------------------------------------------- 209 getWrappedAccessor() const210 WrappedAccessor const& getWrappedAccessor() const { return maAccessor; } getWrappedAccessor()211 WrappedAccessor& getWrappedAccessor() { return maAccessor; } 212 213 // ------------------------------------------------------- 214 setter(typename SetterFunctor::first_argument_type v1,argument_type v2) const215 typename SetterFunctor::result_type setter( 216 typename SetterFunctor::first_argument_type v1, 217 argument_type v2 ) const 218 { 219 return maSetterFunctor(v1,v2); 220 } 221 222 // ------------------------------------------------------- 223 224 template< class Iterator > operator ()(Iterator const & i) const225 value_type operator()(Iterator const& i) const 226 { 227 return maAccessor(i); 228 } 229 230 template< class Iterator, class Difference > operator ()(Iterator const & i,Difference const & diff) const231 value_type operator()(Iterator const& i, Difference const& diff) const 232 { 233 return maAccessor(i,diff); 234 } 235 236 // ------------------------------------------------------- 237 238 template< typename V, class Iterator > set(V const & value,Iterator const & i) const239 void set(V const& value, Iterator const& i) const 240 { 241 maAccessor.set( 242 maFunctor(maAccessor(i), 243 vigra::detail::RequiresExplicitCast<argument_type>::cast(value)), 244 i ); 245 } 246 247 template< typename V, class Iterator, class Difference > set(V const & value,Iterator const & i,Difference const & diff) const248 void set(V const& value, Iterator const& i, Difference const& diff) const 249 { 250 maAccessor.set( 251 maFunctor(maAccessor(i,diff), 252 vigra::detail::RequiresExplicitCast<argument_type>::cast(value)), 253 i, 254 diff ); 255 } 256 257 }; 258 259 //----------------------------------------------------------------------------- 260 261 /** Write through a CompositeIterator's first wrapped iterator, by 262 piping the first wrapped iterator value, the second iterator 263 value, and the specified new value through a ternary function. 264 265 Passed iterator must fulfill the CompositeIterator concept. Note 266 that the getter/setter methods are not templatized regarding the 267 iterator type, to make the mask calculation optimization below 268 safe (see the maskedAccessor template metafunction below) 269 270 @tpl WrappedAccessor1 271 Wrapped type must provide the usual get and set accessor methods, 272 with the usual signatures (see StandardAccessor for a conforming 273 example). Furthermore, the type must provide a nested typedef 274 value_type (the selection of WrappedAccessor1 as the provider for 275 that typedef is rather arbitrary. Could have been 276 WrappedAccessor2, too. So sue me) 277 278 @tpl Functor 279 An adaptable ternary function (i.e. providing nested typedefs for 280 result_type and first, second and third argument type) 281 */ 282 template< class WrappedAccessor1, 283 class WrappedAccessor2, 284 typename Functor > class TernarySetterFunctionAccessorAdapter 285 { 286 public: 287 typedef typename WrappedAccessor1::value_type value_type; 288 typedef typename Functor::third_argument_type argument_type; 289 290 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 291 // making all members public, if no member template friends 292 private: 293 template<class A1, class A2, typename F> friend class TernarySetterFunctionAccessorAdapter; 294 #endif 295 296 WrappedAccessor1 ma1stAccessor; 297 WrappedAccessor2 ma2ndAccessor; 298 Functor maFunctor; 299 300 public: TernarySetterFunctionAccessorAdapter()301 TernarySetterFunctionAccessorAdapter() : 302 ma1stAccessor(), 303 ma2ndAccessor(), 304 maFunctor() 305 {} 306 TernarySetterFunctionAccessorAdapter(T const & accessor)307 template< class T > explicit TernarySetterFunctionAccessorAdapter( T const& accessor ) : 308 ma1stAccessor( accessor ), 309 ma2ndAccessor(), 310 maFunctor() 311 {} 312 313 template< class A1, class A2 > explicit TernarySetterFunctionAccessorAdapter(TernarySetterFunctionAccessorAdapter<A1,A2,Functor> const & rSrc)314 TernarySetterFunctionAccessorAdapter( 315 TernarySetterFunctionAccessorAdapter< A1, 316 A2, 317 Functor > const& rSrc ) : 318 ma1stAccessor( rSrc.ma1stAccessor ), 319 ma2ndAccessor( rSrc.ma2ndAccessor ), 320 maFunctor( rSrc.maFunctor ) 321 {} 322 323 template< class T1, class T2 > TernarySetterFunctionAccessorAdapter(T1 accessor1,T2 accessor2)324 TernarySetterFunctionAccessorAdapter( T1 accessor1, 325 T2 accessor2 ) : 326 ma1stAccessor( accessor1 ), 327 ma2ndAccessor( accessor2 ), 328 maFunctor() 329 {} 330 331 template< class T1, class T2 > TernarySetterFunctionAccessorAdapter(T1 accessor1,T2 accessor2,Functor func)332 TernarySetterFunctionAccessorAdapter( T1 accessor1, 333 T2 accessor2, 334 Functor func ) : 335 ma1stAccessor( accessor1 ), 336 ma2ndAccessor( accessor2 ), 337 maFunctor( func ) 338 {} 339 340 // ------------------------------------------------------- 341 get1stWrappedAccessor() const342 WrappedAccessor1 const& get1stWrappedAccessor() const { return ma1stAccessor; } get1stWrappedAccessor()343 WrappedAccessor1& get1stWrappedAccessor() { return ma1stAccessor; } 344 get2ndWrappedAccessor() const345 WrappedAccessor2 const& get2ndWrappedAccessor() const { return ma2ndAccessor; } get2ndWrappedAccessor()346 WrappedAccessor2& get2ndWrappedAccessor() { return ma2ndAccessor; } 347 348 // ------------------------------------------------------- 349 setter(typename Functor::first_argument_type v1,typename Functor::second_argument_type v2,argument_type v3) const350 typename Functor::result_type setter( 351 typename Functor::first_argument_type v1, 352 typename Functor::second_argument_type v2, 353 argument_type v3 ) const 354 { 355 return maSetterFunctor(v1,v2,v3); 356 } 357 358 // ------------------------------------------------------- 359 360 template< class Iterator > operator ()(Iterator const & i) const361 value_type operator()(Iterator const& i) const 362 { 363 return ma1stAccessor(i.first()); 364 } 365 366 template< class Iterator, class Difference > operator ()(Iterator const & i,Difference const & diff) const367 value_type operator()(Iterator const& i, Difference const& diff) const 368 { 369 return ma1stAccessor(i.second(),diff); 370 } 371 372 // ------------------------------------------------------- 373 374 template< typename V, class Iterator > set(V const & value,Iterator const & i) const375 void set(V const& value, Iterator const& i) const 376 { 377 ma1stAccessor.set( 378 maFunctor(ma1stAccessor(i.first()), 379 ma2ndAccessor(i.second()), 380 vigra::detail::RequiresExplicitCast<argument_type>::cast(value)), 381 i.first() ); 382 } 383 384 template< typename V, class Iterator, class Difference > set(V const & value,Iterator const & i,Difference const & diff) const385 void set(V const& value, Iterator const& i, Difference const& diff) const 386 { 387 ma1stAccessor.set( 388 maFunctor(ma1stAccessor(i.first(), diff), 389 ma2ndAccessor(i.second(),diff), 390 vigra::detail::RequiresExplicitCast<argument_type>::cast(value)), 391 i.first(), 392 diff ); 393 } 394 395 }; 396 397 //----------------------------------------------------------------------------- 398 399 /** Access two distinct images simultaneously 400 401 Passed iterator must fulfill the CompositeIterator concept 402 (i.e. wrap the two image's iterators into one 403 CompositeIterator). The getter and setter methods expect and 404 return a pair of values, with types equal to the two accessors 405 value types 406 407 @tpl WrappedAccessor1 408 Wrapped type must provide the usual get and set accessor methods, 409 with the usual signatures (see StandardAccessor for a conforming 410 example). Furthermore, the type must provide a nested typedef 411 value_type. 412 413 @tpl WrappedAccessor2 414 Wrapped type must provide the usual get and set accessor methods, 415 with the usual signatures (see StandardAccessor for a conforming 416 example). Furthermore, the type must provide a nested typedef 417 value_type. 418 */ 419 template< class WrappedAccessor1, 420 class WrappedAccessor2 > class JoinImageAccessorAdapter 421 { 422 public: 423 // TODO(F3): Need numeric traits and a few free functions to 424 // actually calculate with a pair (semantic: apply every operation 425 // individually to the contained types) 426 typedef std::pair<typename WrappedAccessor1::value_type, 427 typename WrappedAccessor2::value_type> value_type; 428 429 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 430 // making all members public, if no member template friends 431 private: 432 template<class A1, class A2> friend class JoinImageAccessorAdapter; 433 #endif 434 435 WrappedAccessor1 ma1stAccessor; 436 WrappedAccessor2 ma2ndAccessor; 437 438 public: JoinImageAccessorAdapter()439 JoinImageAccessorAdapter() : 440 ma1stAccessor(), 441 ma2ndAccessor() 442 {} 443 JoinImageAccessorAdapter(T const & accessor)444 template< class T > explicit JoinImageAccessorAdapter( T const& accessor ) : 445 ma1stAccessor( accessor ), 446 ma2ndAccessor() 447 {} 448 449 template< class A1, class A2 > explicit JoinImageAccessorAdapter(JoinImageAccessorAdapter<A1,A2> const & rSrc)450 JoinImageAccessorAdapter( 451 JoinImageAccessorAdapter< A1, 452 A2 > const& rSrc ) : 453 ma1stAccessor( rSrc.ma1stAccessor ), 454 ma2ndAccessor( rSrc.ma2ndAccessor ) 455 {} 456 457 template< class T1, class T2 > JoinImageAccessorAdapter(T1 accessor1,T2 accessor2)458 JoinImageAccessorAdapter( T1 accessor1, 459 T2 accessor2 ) : 460 ma1stAccessor( accessor1 ), 461 ma2ndAccessor( accessor2 ) 462 {} 463 464 // ------------------------------------------------------- 465 get1stWrappedAccessor() const466 WrappedAccessor1 const& get1stWrappedAccessor() const { return ma1stAccessor; } get1stWrappedAccessor()467 WrappedAccessor1& get1stWrappedAccessor() { return ma1stAccessor; } 468 get2ndWrappedAccessor() const469 WrappedAccessor2 const& get2ndWrappedAccessor() const { return ma2ndAccessor; } get2ndWrappedAccessor()470 WrappedAccessor2& get2ndWrappedAccessor() { return ma2ndAccessor; } 471 472 // ------------------------------------------------------- 473 474 template< class Iterator > operator ()(Iterator const & i) const475 value_type operator()(Iterator const& i) const 476 { 477 return std::make_pair(ma1stAccessor(i.first()), 478 ma2ndAccessor(i.second())); 479 } 480 481 template< class Iterator, class Difference > operator ()(Iterator const & i,Difference const & diff) const482 value_type operator()(Iterator const& i, Difference const& diff) const 483 { 484 return std::make_pair(ma1stAccessor(i.first(),diff), 485 ma2ndAccessor(i.second(),diff)); 486 } 487 488 // ------------------------------------------------------- 489 490 template< typename V, class Iterator > set(V const & value,Iterator const & i) const491 void set(V const& value, Iterator const& i) const 492 { 493 ma1stAccessor.set( 494 vigra::detail::RequiresExplicitCast<typename WrappedAccessor1::value_type>::cast( 495 value.first), 496 i.first() ); 497 ma2ndAccessor.set( 498 vigra::detail::RequiresExplicitCast<typename WrappedAccessor2::value_type>::cast( 499 value.second), 500 i.second() ); 501 } 502 503 template< typename V, class Iterator, class Difference > set(V const & value,Iterator const & i,Difference const & diff) const504 void set(V const& value, Iterator const& i, Difference const& diff) const 505 { 506 ma1stAccessor.set( 507 vigra::detail::RequiresExplicitCast<typename WrappedAccessor1::value_type>::cast( 508 value.first), 509 i.first(), 510 diff ); 511 ma2ndAccessor.set( 512 vigra::detail::RequiresExplicitCast<typename WrappedAccessor2::value_type>::cast( 513 value.second), 514 i.second(), 515 diff ); 516 } 517 518 }; 519 520 } // namespace basebmp 521 522 #endif /* INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX */ 523