00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef GIL_APPLY_OPERATION_BASE_HPP
00014 #define GIL_APPLY_OPERATION_BASE_HPP
00015
00016 #include "../../gil_config.hpp"
00017 #include "../../utilities.hpp"
00018 #include <boost/mpl/begin.hpp>
00019 #include <boost/mpl/next.hpp>
00020 #include <boost/mpl/deref.hpp>
00021 #include <boost/mpl/size.hpp>
00022 #include <boost/preprocessor/repeat.hpp>
00023
00033
00034 namespace boost { namespace gil {
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
00064
00065
00066
00067
00068 #define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next<T##N>::type
00069 #define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits));
00070 #define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits));
00071
00072 #define GIL_APPLY_FWD_OP(z, N, text) \
00073 template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> { \
00074 template <typename Types, typename Bits, typename UnaryOp> \
00075 typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { \
00076 typedef typename mpl::begin<Types>::type \
00077 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
00078 T##N; \
00079 switch (index) { \
00080 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \
00081 } \
00082 throw; \
00083 } \
00084 template <typename Types, typename Bits, typename UnaryOp> \
00085 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \
00086 typedef typename mpl::begin<Types>::type \
00087 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
00088 T##N; \
00089 switch (index) { \
00090 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \
00091 } \
00092 throw; \
00093 } \
00094 };
00095
00096 #define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY)
00097
00098 namespace detail {
00099 template <std::size_t N> struct apply_operation_fwd_fn {};
00100
00101
00102 GIL_GENERATE_APPLY_FWD_OPS(99)
00103 };
00104
00105
00106 template <typename Types, typename Bits, typename Op>
00107 typename Op::result_type GIL_FORCEINLINE apply_operation_basec(const Bits& bits, std::size_t index, Op op) {
00108 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template applyc<Types>(bits,index,op);
00109 }
00110
00111
00112 template <typename Types, typename Bits, typename Op>
00113 typename Op::result_type GIL_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) {
00114 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template apply<Types>(bits,index,op);
00115 }
00116
00117 namespace detail {
00118 template <typename T2, typename Op>
00119 struct reduce_bind1 {
00120 const T2& _t2;
00121 mutable Op& _op;
00122
00123 typedef typename Op::result_type result_type;
00124
00125 reduce_bind1(const T2& t2, Op& op) : _t2(t2), _op(op) {}
00126
00127 template <typename T1> GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); }
00128 };
00129
00130 template <typename Types1, typename Bits1, typename Op>
00131 struct reduce_bind2 {
00132 const Bits1& _bits1;
00133 std::size_t _index1;
00134 mutable Op& _op;
00135
00136 typedef typename Op::result_type result_type;
00137
00138 reduce_bind2(const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {}
00139
00140 template <typename T2> GIL_FORCEINLINE result_type operator()(const T2& t2) {
00141 return apply_operation_basec<Types1>(_bits1, _index1, reduce_bind1<T2,Op>(t2, _op));
00142 }
00143 };
00144 }
00145
00146
00147 template <typename Types1, typename Types2, typename Bits1, typename Bits2, typename Op>
00148 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) {
00149 return apply_operation_basec<Types2>(bits2,index2,detail::reduce_bind2<Types1,Bits1,Op>(bits1,index1,op));
00150 }
00151
00152 #undef GIL_FWD_TYPEDEFS
00153 #undef GIL_FWD_CASE
00154 #undef GIL_FWD_CONST_CASE
00155 #undef GIL_APPLY_FWD_OP
00156 #undef GIL_GENERATE_APPLY_FWD_OPS
00157 #undef BHS
00158
00159 } }
00160
00161
00162 #endif