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