]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/gil/include/boost/gil/extension/dynamic_image/apply_operation_base.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / gil / include / boost / gil / extension / dynamic_image / apply_operation_base.hpp
1 /*
2 Copyright 2005-2007 Adobe Systems Incorporated
3
4 Use, modification and distribution are subject to the Boost Software License,
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7
8 See http://opensource.adobe.com/gil for most recent version including documentation.
9 */
10
11 /*************************************************************************************************/
12
13 #ifndef GIL_APPLY_OPERATION_BASE_HPP
14 #define GIL_APPLY_OPERATION_BASE_HPP
15
16 #include "../../gil_config.hpp"
17 #include "../../utilities.hpp"
18 #include <boost/mpl/begin.hpp>
19 #include <boost/mpl/next.hpp>
20 #include <boost/mpl/deref.hpp>
21 #include <boost/mpl/size.hpp>
22 #include <boost/preprocessor/repeat.hpp>
23
24 ////////////////////////////////////////////////////////////////////////////////////////
25 /// \file
26 /// \brief Given an object with run-time specified type (denoted as an array of Bits, dynamic index, and a static set of Types) and a generic operation,
27 /// casts the object to its appropriate type and applies the operation
28 /// \author Lubomir Bourdev and Hailin Jin \n
29 /// Adobe Systems Incorporated
30 /// \date 2005-2007 \n Last updated on November 6, 2007
31 ///
32 ////////////////////////////////////////////////////////////////////////////////////////
33
34 namespace boost { namespace gil {
35
36 /*
37 GENERATE_APPLY_FWD_OPS generates for every N functions that look like this (for N==2):
38
39 template <> struct apply_operation_fwd_fn<3> {
40 template <typename Types, typename Bits, typename UnaryOp>
41 typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const {
42 typedef typename mpl::begin<Types>::type T0;
43 typedef typename mpl::next<T0>::type T1;
44 typedef typename mpl::next<T1>::type T2;
45 switch (index) {
46 case 0: return op(reinterpret_cast<typename mpl::deref<T0>::type&>(bits));
47 case 1: return op(reinterpret_cast<typename mpl::deref<T1>::type&>(bits));
48 case 2: return op(reinterpret_cast<typename mpl::deref<T2>::type&>(bits));
49 }
50 throw;
51 }
52
53 template <typename Types, typename Bits, typename UnaryOp>
54 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const {
55 typedef typename mpl::begin<Types>::type T0;
56 typedef typename mpl::next<T0>::type T1;
57 typedef typename mpl::next<T1>::type T2;
58 switch (index) {
59 case 0: return op(reinterpret_cast<const typename mpl::deref<T0>::type&>(bits));
60 case 1: return op(reinterpret_cast<const typename mpl::deref<T1>::type&>(bits));
61 case 2: return op(reinterpret_cast<const typename mpl::deref<T2>::type&>(bits));
62 }
63 throw;
64 }
65 };
66 */
67
68 #define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next<T##N>::type
69 #define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits));
70 #define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits));
71
72 #define GIL_FWD_CASE_WITH_INFO(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits), info);
73 #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);
74
75 #define GIL_APPLY_FWD_OP(z, N, text) \
76 template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> { \
77 template <typename Types, typename Bits, typename UnaryOp> \
78 typename UnaryOp::result_type apply(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) \
81 T##N; \
82 switch (index) { \
83 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \
84 } \
85 throw; \
86 } \
87 template <typename Types, typename Bits, typename UnaryOp> \
88 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \
89 typedef typename mpl::begin<Types>::type \
90 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
91 T##N; \
92 switch (index) { \
93 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \
94 } \
95 throw; \
96 } \
97 template <typename Types, typename Info, typename Bits, typename UnaryOp> \
98 typename UnaryOp::result_type apply(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) \
101 T##N; \
102 switch (index) { \
103 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE_WITH_INFO, BOOST_PP_EMPTY) \
104 } \
105 throw; \
106 } \
107 template <typename Types, typename Bits, typename Info, typename UnaryOp> \
108 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, const Info& info, UnaryOp op) const { \
109 typedef typename mpl::begin<Types>::type \
110 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \
111 T##N; \
112 switch (index) { \
113 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE_WITH_INFO,BOOST_PP_EMPTY) \
114 } \
115 throw; \
116 } \
117 };
118
119 #define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY)
120
121 namespace detail {
122 template <std::size_t N> struct apply_operation_fwd_fn {};
123
124 // Create specializations of apply_operation_fn for each N 0..100
125 GIL_GENERATE_APPLY_FWD_OPS(99)
126 } // namespace detail
127
128 // unary application
129 template <typename Types, typename Bits, typename Op>
130 typename Op::result_type GIL_FORCEINLINE apply_operation_basec(const Bits& bits, std::size_t index, Op op) {
131 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template applyc<Types>(bits,index,op);
132 }
133
134 // unary application
135 template <typename Types, typename Bits, typename Op>
136 typename Op::result_type GIL_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) {
137 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template apply<Types>(bits,index,op);
138 }
139
140 namespace detail {
141 template <typename T2, typename Op>
142 struct reduce_bind1 {
143 const T2& _t2;
144 Op& _op;
145
146 typedef typename Op::result_type result_type;
147
148 reduce_bind1(const T2& t2, Op& op) : _t2(t2), _op(op) {}
149
150 template <typename T1> GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); }
151 };
152
153 template <typename Types1, typename Bits1, typename Op>
154 struct reduce_bind2 {
155 const Bits1& _bits1;
156 std::size_t _index1;
157 Op& _op;
158
159 typedef typename Op::result_type result_type;
160
161 reduce_bind2(const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {}
162
163 template <typename T2> GIL_FORCEINLINE result_type operator()(const T2& t2) {
164 return apply_operation_basec<Types1>(_bits1, _index1, reduce_bind1<T2,Op>(t2, _op));
165 }
166 };
167 } // namespace detail
168
169 // Binary application by applying on each dimension separately
170 template <typename Types1, typename Types2, typename Bits1, typename Bits2, typename Op>
171 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) {
172 return apply_operation_basec<Types2>(bits2,index2,detail::reduce_bind2<Types1,Bits1,Op>(bits1,index1,op));
173 }
174
175 #undef GIL_FWD_TYPEDEFS
176 #undef GIL_FWD_CASE
177 #undef GIL_FWD_CONST_CASE
178 #undef GIL_APPLY_FWD_OP
179 #undef GIL_GENERATE_APPLY_FWD_OPS
180 #undef BHS
181
182 } } // namespace boost::gil
183
184
185 #endif