Adobe Systems, Inc.

apply_operation.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2006 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef GIL_APPLY_OPERATION_HPP
00010 #define GIL_APPLY_OPERATION_HPP
00011 
00020 
00021 #include "apply_operation_base.hpp"
00022 #include "variant.hpp"
00023 
00024 //#define DO_REDUCE
00025 
00026 // Max number of cases in the cross-expension of binary operation for it to be reduced as unary
00027 #define BINARY_REDUCE_LIMIT 226
00028 
00029 #ifndef DO_REDUCE
00030 
00031 ADOBE_GIL_NAMESPACE_BEGIN
00032 
00033 template <typename TYPES, typename UNARY_OP> GIL_FORCEINLINE
00034 typename UNARY_OP::result_type apply_operation(variant<TYPES>& arg, UNARY_OP op) {
00035     return apply_operation_base<TYPES>(arg._bits, arg._index ,op);
00036 }
00037 
00038 template <typename TYPES, typename UNARY_OP> GIL_FORCEINLINE
00039 typename UNARY_OP::result_type apply_operation(const variant<TYPES>& arg, UNARY_OP op) {
00040     return apply_operation_basec<TYPES>(arg._bits, arg._index ,op);
00041 }
00042 
00043 template <typename TYPES1, typename TYPES2, typename BINARY_OP> GIL_FORCEINLINE
00044 typename BINARY_OP::result_type apply_operation(const variant<TYPES1>& arg1, const variant<TYPES2>& arg2, BINARY_OP op) {   
00045     return apply_operation_base<TYPES1,TYPES2>(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
00046 }
00047 
00048 ADOBE_GIL_NAMESPACE_END
00049 
00050 #else
00051 
00052 
00053 #include "type_vector.hpp"
00054 #include "dynamic_at_c.hpp"
00055 #include "reduce.hpp"
00056 #include <boost/mpl/insert.hpp>
00057 #include <boost/mpl/transform.hpp>
00058 
00059 
00060 ADOBE_GIL_NAMESPACE_BEGIN
00061 
00062 
00070 
00071 
00072 
00073 
00083 
00084 template <typename TYPES, typename OP>
00085 struct unary_reduce_impl {
00086     typedef typename boost::mpl::transform<TYPES, detail::reduce<OP, boost::mpl::_1> >::type reduced_t;
00087     typedef typename boost::mpl::copy<reduced_t, boost::mpl::inserter<boost::mpl::set<>, boost::mpl::insert<boost::mpl::_1,boost::mpl::_2> > >::type unique_t;
00088     static const bool is_single=boost::mpl::size<unique_t>::value==1;
00089 };
00090 
00091 template <typename TYPES, typename OP, bool SINGLE=unary_reduce_impl<TYPES,OP>::is_single>
00092 struct unary_reduce : public unary_reduce_impl<TYPES,OP> {
00093     typedef typename unary_reduce_impl<TYPES,OP>::reduced_t reduced_t;
00094     typedef typename unary_reduce_impl<TYPES,OP>::unique_t unique_t;
00095 
00096     static unsigned short inline map_index(std::size_t index) {
00097         typedef typename boost::mpl::mapping_vector<reduced_t, unique_t> indices_t;
00098         return gil::at_c<indices_t, unsigned short>(index);
00099     }
00100     template <typename BITS> GIL_FORCEINLINE static typename OP::result_type applyc(const BITS& bits, std::size_t index, OP op) {
00101         return apply_operation_basec<unique_t>(bits,map_index(index),op);
00102     }
00103 
00104     template <typename BITS> GIL_FORCEINLINE static typename OP::result_type apply(BITS& bits, std::size_t index, OP op) {
00105         return apply_operation_base<unique_t>(bits,map_index(index),op);
00106     }
00107 };
00108 
00109 template <typename TYPES, typename OP>
00110 struct unary_reduce<TYPES,OP,true> : public unary_reduce_impl<TYPES,OP> {
00111     typedef typename unary_reduce_impl<TYPES,OP>::unique_t unique_t;
00112     static unsigned short inline map_index(std::size_t index) { return 0; }
00113 
00114     template <typename BITS> GIL_FORCEINLINE static typename OP::result_type applyc(const BITS& bits, std::size_t index, OP op) {
00115         return op(reinterpret_cast<const typename boost::mpl::front<unique_t>::type&>(bits));
00116     }
00117 
00118     template <typename BITS> GIL_FORCEINLINE static typename OP::result_type apply(BITS& bits, std::size_t index, OP op) {
00119         return op(reinterpret_cast<typename       boost::mpl::front<unique_t>::type&>(bits));
00120     }
00121 };
00122 
00123 
00136 
00137 namespace detail {
00138     struct pair_generator {
00139         template <typename VEC2> struct apply {
00140             typedef std::pair<const typename boost::mpl::at_c<VEC2,0>::type*, const typename boost::mpl::at_c<VEC2,1>::type*> type;
00141         };
00142     };
00143 
00144     // When the types are not too large, applies reduce on their cross product
00145     template <typename UNARY_1, typename UNARY_2, typename OP, bool COMPLEX>
00146     struct binary_reduce_impl {
00147     //private:
00148         typedef typename boost::mpl::copy_to_vector<typename UNARY_1::unique_t>::type vec1_types;
00149         typedef typename boost::mpl::copy_to_vector<typename UNARY_2::unique_t>::type vec2_types;
00150 
00151         typedef boost::mpl::cross_vector<boost::mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;
00152         typedef unary_reduce<BIN_TYPES,OP> bin_reduced_t;
00153         
00154         static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
00155             unsigned short r1=UNARY_1::map_index(index1);
00156             unsigned short r2=UNARY_2::map_index(index2);
00157             return bin_reduced_t::map_index(r2*boost::mpl::size<vec1_types>::value + r1);
00158         }
00159     public:
00160         typedef typename bin_reduced_t::unique_t unique_t;
00161 
00162         template <typename BITS1, typename BITS2>
00163         static typename OP::result_type inline apply(const BITS1& bits1, std::size_t index1, const BITS2& bits2, std::size_t index2, OP op) {
00164             std::pair<const void*,const void*> pr(&bits1, &bits2);
00165             return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
00166         }
00167     };
00168 
00169     // When the types are large performs a double-dispatch. Binary reduction is not done.
00170     template <typename UNARY_1, typename UNARY_2, typename OP>
00171     struct binary_reduce_impl<UNARY_1,UNARY_2,OP,true> {
00172         template <typename BITS1, typename BITS2>
00173         static typename OP::result_type inline apply(const BITS1& bits1, std::size_t index1, const BITS2& bits2, std::size_t index2, OP op) {
00174             return apply_operation_base<UNARY_1::unique_t,UNARY_2::unique_t>(bits1, index1, bits2, index2, op);
00175         }
00176     };
00177 }
00178 
00179 
00180 template <typename TYPES1, typename TYPES2, typename OP>
00181 struct binary_reduce {
00182 //private:
00183     typedef unary_reduce<TYPES1,OP> unary1_t;
00184     typedef unary_reduce<TYPES2,OP> unary2_t;
00185 
00186     static const std::size_t CROSS_SIZE = boost::mpl::size<typename unary1_t::unique_t>::value * 
00187                                           boost::mpl::size<typename unary2_t::unique_t>::value;
00188 
00189     typedef detail::binary_reduce_impl<unary1_t,unary2_t,OP, (CROSS_SIZE>BINARY_REDUCE_LIMIT)> impl;
00190 public:
00191     template <typename BITS1, typename BITS2>
00192     static typename OP::result_type inline apply(const BITS1& bits1, std::size_t index1, const BITS2& bits2, std::size_t index2, OP op) {
00193         return impl::apply(bits1,index1,bits2,index2,op);
00194     }
00195 };
00196 
00197 template <typename TYPES, typename UNARY_OP>
00198 GIL_FORCEINLINE typename UNARY_OP::result_type apply_operation(variant<TYPES>& arg, UNARY_OP op) {
00199     return unary_reduce<TYPES,UNARY_OP>::template apply(arg._bits, arg._index ,op);
00200 }
00201 
00202 template <typename TYPES, typename UNARY_OP>
00203 GIL_FORCEINLINE typename UNARY_OP::result_type apply_operation(const variant<TYPES>& arg, UNARY_OP op) {
00204     return unary_reduce<TYPES,UNARY_OP>::template applyc(arg._bits, arg._index ,op);
00205 }
00206 
00207 template <typename TYPES1, typename TYPES2, typename BINARY_OP>
00208 GIL_FORCEINLINE typename BINARY_OP::result_type apply_operation(const variant<TYPES1>& arg1, const variant<TYPES2>& arg2, BINARY_OP op) {   
00209     return binary_reduce<TYPES1,TYPES2,BINARY_OP>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
00210 }
00211 
00212 
00213 ADOBE_GIL_NAMESPACE_END
00214 
00215 #endif
00216 
00217 #endif

Copyright © 2006 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google