Adobe Systems, Inc.

apply_operation_base.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_BASE_HPP
00010 #define GIL_APPLY_OPERATION_BASE_HPP
00011 
00012 #include "../../core/gil_config.hpp"
00013 #include <boost/mpl/begin.hpp>
00014 #include <boost/mpl/next.hpp>
00015 #include <boost/mpl/deref.hpp>
00016 #include <boost/mpl/size.hpp>
00017 #include <boost/preprocessor/repeat.hpp> 
00018 
00028 
00029 ADOBE_GIL_NAMESPACE_BEGIN
00030 
00031 /*
00032 GENERATE_APPLY_FWD_OPS generates for every N functions that look like this (for N==2):
00033 
00034     template <> struct apply_operation_fwd_fn<3> {
00035         template <typename TYPES, typename BITS, typename UNARY_OP>
00036         typename UNARY_OP::result_type apply(BITS& bits, std::size_t index, UNARY_OP op) const {
00037             typedef typename boost::mpl::begin<TYPES>::type T0;
00038             typedef typename boost::mpl::next<T0>::type T1;
00039             typedef typename boost::mpl::next<T1>::type T2;
00040             switch (index) {
00041                 case 0: return op(reinterpret_cast<typename boost::mpl::deref<T0>::type&>(bits));
00042                 case 1: return op(reinterpret_cast<typename boost::mpl::deref<T1>::type&>(bits));
00043                 case 2: return op(reinterpret_cast<typename boost::mpl::deref<T2>::type&>(bits));
00044             }
00045             throw;
00046         }
00047 
00048         template <typename TYPES, typename BITS, typename UNARY_OP>
00049         typename UNARY_OP::result_type applyc(const BITS& bits, std::size_t index, UNARY_OP op) const {
00050             typedef typename boost::mpl::begin<TYPES>::type T0;
00051             typedef typename boost::mpl::next<T0>::type T1;
00052             typedef typename boost::mpl::next<T1>::type T2;
00053             switch (index) {
00054                 case 0: return op(reinterpret_cast<const typename boost::mpl::deref<T0>::type&>(bits));
00055                 case 1: return op(reinterpret_cast<const typename boost::mpl::deref<T1>::type&>(bits));
00056                 case 2: return op(reinterpret_cast<const typename boost::mpl::deref<T2>::type&>(bits));
00057             }
00058             throw;
00059         }
00060     };
00061 */
00062 
00063 #define FWD_TYPEDEFS(z, N, text)   T##N; typedef typename boost::mpl::next<T##N>::type 
00064 #define FWD_CASE(z, N, SUM)       case N: return op(reinterpret_cast<typename boost::mpl::deref<T##N>::type&>(bits));
00065 #define FWD_CONST_CASE(z, N, SUM) case N: return op(reinterpret_cast<const typename boost::mpl::deref<T##N>::type&>(bits));
00066 
00067 #define APPLY_FWD_OP(z, N, text)                                                                \
00068     template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> {                              \
00069         template <typename TYPES, typename BITS, typename UNARY_OP>                             \
00070         typename UNARY_OP::result_type apply(BITS& bits, std::size_t index, UNARY_OP op) const {\
00071             typedef typename boost::mpl::begin<TYPES>::type                                     \
00072             BOOST_PP_REPEAT(N, FWD_TYPEDEFS, BOOST_PP_EMPTY)                                    \
00073             T##N;                                                                               \
00074             switch (index) {                                                                    \
00075                 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), FWD_CASE, BOOST_PP_EMPTY)                    \
00076             }                                                                                   \
00077             throw;                                                                              \
00078         }                                                                                       \
00079         template <typename TYPES, typename BITS, typename UNARY_OP>                             \
00080         typename UNARY_OP::result_type applyc(const BITS& bits, std::size_t index, UNARY_OP op) const { \
00081             typedef typename boost::mpl::begin<TYPES>::type                                     \
00082             BOOST_PP_REPEAT(N, FWD_TYPEDEFS, BOOST_PP_EMPTY)                                    \
00083             T##N;                                                                               \
00084             switch (index) {                                                                    \
00085                 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), FWD_CONST_CASE,BOOST_PP_EMPTY)               \
00086             }                                                                                   \
00087             throw;                                                                              \
00088         }                                                                                       \
00089     };
00090 
00091 #define GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, APPLY_FWD_OP, BOOST_PP_EMPTY)
00092 
00093 namespace detail {
00094     template <std::size_t N> struct apply_operation_fwd_fn {};
00095 
00096     // Create specializations of apply_operation_fn for each N 0..100
00097     GENERATE_APPLY_FWD_OPS(99)
00098 };
00099 
00100 // unary application
00101 template <typename TYPES, typename BITS, typename OP> 
00102 typename OP::result_type GIL_FORCEINLINE apply_operation_basec(const BITS& bits, std::size_t index, OP op) {
00103     return detail::apply_operation_fwd_fn<boost::mpl::size<TYPES>::value>().template applyc<TYPES>(bits,index,op);
00104 }
00105 
00106 // unary application
00107 template <typename TYPES, typename BITS, typename OP> 
00108 typename OP::result_type GIL_FORCEINLINE apply_operation_base(      BITS& bits, std::size_t index, OP op) {
00109     return detail::apply_operation_fwd_fn<boost::mpl::size<TYPES>::value>().template apply<TYPES>(bits,index,op);
00110 }
00111 
00112 namespace detail {
00113     template <typename T2, typename OP>
00114     struct reduce_bind1 {
00115         const T2& _t2;
00116         mutable OP&  _op;
00117 
00118         typedef typename OP::result_type result_type;
00119 
00120         reduce_bind1(const T2& t2, OP& op) : _t2(t2), _op(op) {}
00121 
00122         template <typename T1> GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); }
00123     };
00124 
00125     template <typename TYPES1, typename BITS1, typename OP>
00126     struct reduce_bind2 {
00127         const BITS1& _bits1;
00128         std::size_t _index1;
00129         mutable OP&  _op;
00130 
00131         typedef typename OP::result_type result_type;
00132 
00133         reduce_bind2(const BITS1& bits1, std::size_t index1, OP& op) : _bits1(bits1), _index1(index1), _op(op) {}
00134 
00135         template <typename T2> GIL_FORCEINLINE result_type operator()(const T2& t2) { 
00136             return apply_operation_basec<TYPES1>(_bits1, _index1, reduce_bind1<T2,OP>(t2, _op));
00137         }
00138     };
00139 }
00140 
00141 // Binary application by applying on each dimension separately
00142 template <typename TYPES1, typename TYPES2, typename BITS1, typename BITS2, typename OP>
00143 static typename OP::result_type GIL_FORCEINLINE apply_operation_base(const BITS1& bits1, std::size_t index1, const BITS2& bits2, std::size_t index2, OP op) {
00144     return apply_operation_basec<TYPES2>(bits2,index2,detail::reduce_bind2<TYPES1,BITS1,OP>(bits1,index1,op));
00145 }
00146 
00147 ADOBE_GIL_NAMESPACE_END
00148 
00149 
00150 #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