00001
00002
00003
00004
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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
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
00097 GENERATE_APPLY_FWD_OPS(99)
00098 };
00099
00100
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
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
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