8 #ifndef BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_APPLY_OPERATION_BASE_HPP
9 #define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_APPLY_OPERATION_BASE_HPP
11 #include <boost/gil/utilities.hpp>
13 #include <boost/config.hpp>
14 #include <boost/mpl/begin.hpp>
15 #include <boost/mpl/next.hpp>
16 #include <boost/mpl/deref.hpp>
17 #include <boost/mpl/size.hpp>
18 #include <boost/preprocessor/repeat.hpp>
20 namespace boost {
namespace gil {
58 #define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next<T##N>::type
59 #define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits));
60 #define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits));
62 #define GIL_FWD_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits), info);
63 #define GIL_FWD_CONST_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits), info);
65 #define GIL_APPLY_FWD_OP(z, N, text) \
66 template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> { \
67 template <typename Types, typename Bits, typename UnaryOp> \
68 typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { \
69 typedef typename mpl::begin<Types>::type \
70 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
73 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \
77 template <typename Types, typename Bits, typename UnaryOp> \
78 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \
79 typedef typename mpl::begin<Types>::type \
80 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
83 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \
87 template <typename Types, typename Info, typename Bits, typename UnaryOp> \
88 typename UnaryOp::result_type apply(Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
89 typedef typename mpl::begin<Types>::type \
90 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
93 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE_WITH_INFO, BOOST_PP_EMPTY) \
97 template <typename Types, typename Bits, typename Info, typename UnaryOp> \
98 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
99 typedef typename mpl::begin<Types>::type \
100 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
103 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE_WITH_INFO,BOOST_PP_EMPTY) \
109 #define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY)
112 template <std::
size_t N>
struct apply_operation_fwd_fn {};
115 GIL_GENERATE_APPLY_FWD_OPS(99)
119 template <
typename Types,
typename Bits,
typename Op>
120 typename Op::result_type BOOST_FORCEINLINE apply_operation_basec(
const Bits& bits, std::size_t index, Op op) {
121 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().
template applyc<Types>(bits,index,op);
125 template <
typename Types,
typename Bits,
typename Op>
126 typename Op::result_type BOOST_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) {
127 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().
template apply<Types>(bits,index,op);
131 template <
typename T2,
typename Op>
132 struct reduce_bind1 {
136 typedef typename Op::result_type result_type;
138 reduce_bind1(
const T2& t2, Op& op) : _t2(t2), _op(op) {}
140 template <
typename T1> BOOST_FORCEINLINE result_type operator()(
const T1& t1) {
return _op(t1, _t2); }
143 template <
typename Types1,
typename Bits1,
typename Op>
144 struct reduce_bind2 {
149 typedef typename Op::result_type result_type;
151 reduce_bind2(
const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {}
153 template <
typename T2> BOOST_FORCEINLINE result_type operator()(
const T2& t2) {
154 return apply_operation_basec<Types1>(_bits1, _index1, reduce_bind1<T2,Op>(t2, _op));
160 template <
typename Types1,
typename Types2,
typename Bits1,
typename Bits2,
typename Op>
161 static typename Op::result_type BOOST_FORCEINLINE apply_operation_base(
const Bits1& bits1, std::size_t index1,
const Bits2& bits2, std::size_t index2, Op op) {
162 return apply_operation_basec<Types2>(bits2,index2,detail::reduce_bind2<Types1,Bits1,Op>(bits1,index1,op));
165 #undef GIL_FWD_TYPEDEFS
167 #undef GIL_FWD_CONST_CASE
168 #undef GIL_APPLY_FWD_OP
169 #undef GIL_GENERATE_APPLY_FWD_OPS