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_ACCESSORFUNCTORS_HXX
25 #define INCLUDED_BASEBMP_ACCESSORFUNCTORS_HXX
26 
27 #include <osl/diagnose.h>
28 #include <basebmp/metafunctions.hxx>
29 
30 #include <functional>
31 
32 namespace basebmp
33 {
34 
35 // Some common accessor functors
36 // ------------------------------------------------------------
37 
38 
39 /// combine two values via XOR
40 template< typename T > struct XorFunctor : public std::binary_function<T,T,T>
41 {
operator ()basebmp::XorFunctor42     T operator()( T v1, T v2 ) const { return v1 ^ v2; }
43 };
44 
45 //-----------------------------------------------------------------------------
46 
47 /// Base class, passing on the arg types
48 template< typename T, typename M > struct MaskFunctorBase :
49         public TernaryFunctorBase<T,M,T,T> {};
50 
51 
52 /** Let a mask flag decide between two values
53 
54     @tpl polarity
55     Mask polarity. When true, a false in the mask denotes
56     transparency, i.e. the original value will display. And vice
57     versa.
58  */
59 template< typename T,
60           typename M,
61           bool     polarity > struct GenericOutputMaskFunctor : public MaskFunctorBase<T,M>
62 {
63     /// Ternary mask operation - selects v1 for !m == polarity, v2 otherwise
operator ()basebmp::GenericOutputMaskFunctor64     T operator()( T v1, M m, T v2 ) const
65     {
66         return !m == polarity ? v1 : v2;
67     }
68 };
69 
70 /** Let a mask bit decide between two values (specialization for
71     integer mask types)
72  */
73 template< typename T,
74           typename M,
75           bool     polarity > struct IntegerOutputMaskFunctor;
76 template< typename T,
77           typename M > struct IntegerOutputMaskFunctor<T,M,true> : public MaskFunctorBase<T,M>
78 {
79     /** Mask v with state of m
80 
81         @return v2, if m != 0, v1 otherwise.
82      */
operator ()basebmp::IntegerOutputMaskFunctor83     T operator()( T v1, M m, T v2 ) const
84     {
85         typedef typename make_unsigned<T>::type unsigned_T;
86 
87         // mask will be 0, iff m == 0, and 1 otherwise
88         const T mask( unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) );
89         return v1*(M)(1-mask) + v2*mask;
90     }
91 };
92 template< typename T,
93           typename M > struct IntegerOutputMaskFunctor<T,M,false> : public MaskFunctorBase<T,M>
94 {
95     /** Mask v with state of m
96 
97         @return v2, if m != 0, v1 otherwise.
98      */
operator ()basebmp::IntegerOutputMaskFunctor99     T operator()( T v1, M m, T v2 ) const
100     {
101         typedef typename make_unsigned<T>::type unsigned_T;
102 
103         // mask will be 0, iff m == 0, and 1 otherwise
104         const T mask( unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) );
105         return v1*mask + v2*(M)(1-mask);
106     }
107 };
108 
109 /** Let a mask bit decide between two values (specialization for
110     binary-valued mask types)
111  */
112 template< typename T, typename M, bool polarity > struct FastIntegerOutputMaskFunctor;
113 template< typename T, typename M > struct FastIntegerOutputMaskFunctor<T,M,true> :
114    public MaskFunctorBase<T,M>
115 {
116     /// Specialization, only valid if mask can only attain 0 or 1
operator ()basebmp::FastIntegerOutputMaskFunctor117     T operator()( T v1, M m, T v2 ) const
118     {
119         OSL_ASSERT(m<=1);
120 
121         return v1*(M)(1-m) + v2*m;
122     }
123 };
124 template< typename T, typename M > struct FastIntegerOutputMaskFunctor<T,M,false> :
125    public MaskFunctorBase<T,M>
126 {
127     /// Specialization, only valid if mask can only attain 0 or 1
operator ()basebmp::FastIntegerOutputMaskFunctor128     T operator()( T v1, M m, T v2 ) const
129     {
130         OSL_ASSERT(m<=1);
131 
132         return v1*m + v2*(M)(1-m);
133     }
134 };
135 
136 //-----------------------------------------------------------------------------
137 
138 /** Split a pair value from a JoinImageAccessorAdapter into its
139     individual values, and pass it on to a ternary functor
140 
141     This wrapper is an adaptable binary functor, and can thus be used
142     with a BinarySetterFunctionAccessorAdapter. Useful e.g. for
143     out-of-image alpha channel, or a masked image.
144 
145     @tpl Functor
146     An adaptable ternary functor (as can e.g. be passed to the
147     TernarySetterFunctionAccessorAdapter)
148  */
149 template< typename Functor > struct BinaryFunctorSplittingWrapper :
150         public std::binary_function<typename Functor::first_argument_type,
151                                     std::pair<typename Functor::third_argument_type,
152                                               typename Functor::second_argument_type>,
153                                     typename Functor::result_type>
154 {
155 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
156 // making all members public, if no member template friends
157 private:
158     template<class A> friend struct BinaryFunctorSplittingWrapper;
159 #endif
160     Functor maFunctor;
161 
162 public:
BinaryFunctorSplittingWrapperbasebmp::BinaryFunctorSplittingWrapper163     BinaryFunctorSplittingWrapper() : maFunctor() {}
164 
165     template< class A > explicit
BinaryFunctorSplittingWrapperbasebmp::BinaryFunctorSplittingWrapper166     BinaryFunctorSplittingWrapper(
167         BinaryFunctorSplittingWrapper<A> const& src ) : maFunctor(src.maFunctor) {}
168 
169     template< class F > explicit
BinaryFunctorSplittingWrapperbasebmp::BinaryFunctorSplittingWrapper170     BinaryFunctorSplittingWrapper( F const& func ) : maFunctor(func) {}
171 
operator ()basebmp::BinaryFunctorSplittingWrapper172     typename Functor::result_type operator()(
173         typename Functor::first_argument_type                      v1,
174         std::pair< typename Functor::third_argument_type,
175                    typename Functor::second_argument_type > const& v2 ) const
176     {
177         return maFunctor( v1, v2.second, v2.first );
178     }
179 };
180 
181 } // namespace basebmp
182 
183 #endif /* INCLUDED_BASEBMP_ACCESSORFUNCTORS_HXX */
184