]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/gil/include/boost/gil/extension/dynamic_image/apply_operation_base.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / gil / include / boost / gil / extension / dynamic_image / apply_operation_base.hpp
CommitLineData
7c673cae
FG
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
34namespace boost { namespace gil {
35
36/*
37GENERATE_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
121namespace detail {
122template <std::size_t N> struct apply_operation_fwd_fn {};
123
124// Create specializations of apply_operation_fn for each N 0..100
125GIL_GENERATE_APPLY_FWD_OPS(99)
126} // namespace detail
127
128// unary application
129template <typename Types, typename Bits, typename Op>
130typename 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
135template <typename Types, typename Bits, typename Op>
136typename 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
140namespace 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
170template <typename Types1, typename Types2, typename Bits1, typename Bits2, typename Op>
171static 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