]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/python/include/boost/python/numpy/invoke_matching.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / python / include / boost / python / numpy / invoke_matching.hpp
CommitLineData
7c673cae
FG
1// Copyright Jim Bosch 2010-2012.
2// Copyright Stefan Seefeld 2016.
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef boost_python_numpy_invoke_matching_hpp_
8#define boost_python_numpy_invoke_matching_hpp_
9
10/**
11 * @brief Template invocation based on dtype matching.
12 */
13
14#include <boost/python/numpy/dtype.hpp>
15#include <boost/python/numpy/ndarray.hpp>
16#include <boost/mpl/integral_c.hpp>
17
18namespace boost { namespace python { namespace numpy {
19namespace detail
20{
21
22struct add_pointer_meta
23{
24 template <typename T>
25 struct apply
26 {
27 typedef typename boost::add_pointer<T>::type type;
28 };
29
30};
31
32struct dtype_template_match_found {};
33struct nd_template_match_found {};
34
35template <typename Function>
36struct dtype_template_invoker
37{
38
39 template <typename T>
40 void operator()(T *) const
41 {
42 if (dtype::get_builtin<T>() == m_dtype)
43 {
44 m_func.Function::template apply<T>();
45 throw dtype_template_match_found();
46 }
47 }
48
49 dtype_template_invoker(dtype const & dtype_, Function func)
50 : m_dtype(dtype_), m_func(func) {}
51
52private:
53 dtype const & m_dtype;
54 Function m_func;
55};
56
57template <typename Function>
58struct dtype_template_invoker< boost::reference_wrapper<Function> >
59{
60
61 template <typename T>
62 void operator()(T *) const
63 {
64 if (dtype::get_builtin<T>() == m_dtype)
65 {
66 m_func.Function::template apply<T>();
67 throw dtype_template_match_found();
68 }
69 }
70
71 dtype_template_invoker(dtype const & dtype_, Function & func)
72 : m_dtype(dtype_), m_func(func) {}
73
74private:
75 dtype const & m_dtype;
76 Function & m_func;
77};
78
79template <typename Function>
80struct nd_template_invoker
81{
82 template <int N>
83 void operator()(boost::mpl::integral_c<int,N> *) const
84 {
85 if (m_nd == N)
86 {
87 m_func.Function::template apply<N>();
88 throw nd_template_match_found();
89 }
90 }
91
92 nd_template_invoker(int nd, Function func) : m_nd(nd), m_func(func) {}
93
94private:
95 int m_nd;
96 Function m_func;
97};
98
99template <typename Function>
100struct nd_template_invoker< boost::reference_wrapper<Function> >
101{
102 template <int N>
103 void operator()(boost::mpl::integral_c<int,N> *) const
104 {
105 if (m_nd == N)
106 {
107 m_func.Function::template apply<N>();
108 throw nd_template_match_found();
109 }
110 }
111
112 nd_template_invoker(int nd, Function & func) : m_nd(nd), m_func(func) {}
113
114private:
115 int m_nd;
116 Function & m_func;
117};
118
119} // namespace boost::python::numpy::detail
120
121template <typename Sequence, typename Function>
122void invoke_matching_nd(int nd, Function f)
123{
124 detail::nd_template_invoker<Function> invoker(nd, f);
125 try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
126 catch (detail::nd_template_match_found &) { return;}
127 PyErr_SetString(PyExc_TypeError, "number of dimensions not found in template list.");
128 python::throw_error_already_set();
129}
130
131template <typename Sequence, typename Function>
132void invoke_matching_dtype(dtype const & dtype_, Function f)
133{
134 detail::dtype_template_invoker<Function> invoker(dtype_, f);
135 try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
136 catch (detail::dtype_template_match_found &) { return;}
137 PyErr_SetString(PyExc_TypeError, "dtype not found in template list.");
138 python::throw_error_already_set();
139}
140
141namespace detail
142{
143
144template <typename T, typename Function>
145struct array_template_invoker_wrapper_2
146{
147 template <int N>
148 void apply() const { m_func.Function::template apply<T,N>();}
149 array_template_invoker_wrapper_2(Function & func) : m_func(func) {}
150
151private:
152 Function & m_func;
153};
154
155template <typename DimSequence, typename Function>
156struct array_template_invoker_wrapper_1
157{
158 template <typename T>
159 void apply() const { invoke_matching_nd<DimSequence>(m_nd, array_template_invoker_wrapper_2<T,Function>(m_func));}
160 array_template_invoker_wrapper_1(int nd, Function & func) : m_nd(nd), m_func(func) {}
161
162private:
163 int m_nd;
164 Function & m_func;
165};
166
167template <typename DimSequence, typename Function>
168struct array_template_invoker_wrapper_1< DimSequence, boost::reference_wrapper<Function> >
169 : public array_template_invoker_wrapper_1< DimSequence, Function >
170{
171 array_template_invoker_wrapper_1(int nd, Function & func)
172 : array_template_invoker_wrapper_1< DimSequence, Function >(nd, func) {}
173};
174
175} // namespace boost::python::numpy::detail
176
177template <typename TypeSequence, typename DimSequence, typename Function>
178void invoke_matching_array(ndarray const & array_, Function f)
179{
180 detail::array_template_invoker_wrapper_1<DimSequence,Function> wrapper(array_.get_nd(), f);
181 invoke_matching_dtype<TypeSequence>(array_.get_dtype(), wrapper);
182}
183
184}}} // namespace boost::python::numpy
185
186#endif