Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // Copyright David Abrahams 2002, Joel de Guzman, 2002.
|
Chris@16
|
4 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
5 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
9 #if !defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef DEFAULTS_DEF_JDG20020811_HPP
|
Chris@16
|
12 #define DEFAULTS_DEF_JDG20020811_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/python/detail/defaults_gen.hpp>
|
Chris@16
|
15 #include <boost/type_traits.hpp>
|
Chris@16
|
16 #include <boost/mpl/front.hpp>
|
Chris@16
|
17 #include <boost/mpl/size.hpp>
|
Chris@16
|
18 #include <boost/static_assert.hpp>
|
Chris@16
|
19 #include <boost/preprocessor/iterate.hpp>
|
Chris@16
|
20 #include <boost/python/class_fwd.hpp>
|
Chris@16
|
21 #include <boost/python/scope.hpp>
|
Chris@16
|
22 #include <boost/preprocessor/debug/line.hpp>
|
Chris@16
|
23 #include <boost/python/detail/scope.hpp>
|
Chris@16
|
24 #include <boost/python/detail/make_keyword_range_fn.hpp>
|
Chris@16
|
25 #include <boost/python/object/add_to_namespace.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
28 namespace boost { namespace python {
|
Chris@16
|
29
|
Chris@16
|
30 struct module;
|
Chris@16
|
31
|
Chris@16
|
32 namespace objects
|
Chris@16
|
33 {
|
Chris@16
|
34 struct class_base;
|
Chris@16
|
35 }
|
Chris@16
|
36
|
Chris@16
|
37 namespace detail
|
Chris@16
|
38 {
|
Chris@16
|
39 // Called as::
|
Chris@16
|
40 //
|
Chris@16
|
41 // name_space_def(ns, "func", func, kw, policies, docstring, &ns)
|
Chris@16
|
42 //
|
Chris@16
|
43 // Dispatch to properly add f to namespace ns.
|
Chris@16
|
44 //
|
Chris@16
|
45 // @group define_stub_function helpers {
|
Chris@16
|
46 template <class Func, class CallPolicies, class NameSpaceT>
|
Chris@16
|
47 static void name_space_def(
|
Chris@16
|
48 NameSpaceT& name_space
|
Chris@16
|
49 , char const* name
|
Chris@16
|
50 , Func f
|
Chris@16
|
51 , keyword_range const& kw
|
Chris@16
|
52 , CallPolicies const& policies
|
Chris@16
|
53 , char const* doc
|
Chris@16
|
54 , objects::class_base*
|
Chris@16
|
55 )
|
Chris@16
|
56 {
|
Chris@16
|
57 typedef typename NameSpaceT::wrapped_type wrapped_type;
|
Chris@16
|
58
|
Chris@16
|
59 objects::add_to_namespace(
|
Chris@16
|
60 name_space, name,
|
Chris@16
|
61 detail::make_keyword_range_function(
|
Chris@16
|
62 f, policies, kw, get_signature(f, (wrapped_type*)0))
|
Chris@16
|
63 , doc
|
Chris@16
|
64 );
|
Chris@16
|
65 }
|
Chris@16
|
66
|
Chris@16
|
67 template <class Func, class CallPolicies>
|
Chris@16
|
68 static void name_space_def(
|
Chris@16
|
69 object& name_space
|
Chris@16
|
70 , char const* name
|
Chris@16
|
71 , Func f
|
Chris@16
|
72 , keyword_range const& kw
|
Chris@16
|
73 , CallPolicies const& policies
|
Chris@16
|
74 , char const* doc
|
Chris@16
|
75 , ...
|
Chris@16
|
76 )
|
Chris@16
|
77 {
|
Chris@16
|
78 scope within(name_space);
|
Chris@16
|
79
|
Chris@16
|
80 detail::scope_setattr_doc(
|
Chris@16
|
81 name
|
Chris@16
|
82 , detail::make_keyword_range_function(f, policies, kw)
|
Chris@16
|
83 , doc);
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 // For backward compatibility -- is this obsolete?
|
Chris@16
|
87 template <class Func, class CallPolicies, class NameSpaceT>
|
Chris@16
|
88 static void name_space_def(
|
Chris@16
|
89 NameSpaceT& name_space
|
Chris@16
|
90 , char const* name
|
Chris@16
|
91 , Func f
|
Chris@16
|
92 , keyword_range const& kw // ignored
|
Chris@16
|
93 , CallPolicies const& policies
|
Chris@16
|
94 , char const* doc
|
Chris@16
|
95 , module*
|
Chris@16
|
96 )
|
Chris@16
|
97 {
|
Chris@16
|
98 name_space.def(name, f, policies, doc);
|
Chris@16
|
99 }
|
Chris@16
|
100 // }
|
Chris@16
|
101
|
Chris@16
|
102
|
Chris@16
|
103 // Expansions of ::
|
Chris@16
|
104 //
|
Chris@16
|
105 // template <typename OverloadsT, typename NameSpaceT>
|
Chris@16
|
106 // inline void
|
Chris@16
|
107 // define_stub_function(
|
Chris@16
|
108 // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_<N>)
|
Chris@16
|
109 // {
|
Chris@16
|
110 // name_space.def(name, &OverloadsT::func_N);
|
Chris@16
|
111 // }
|
Chris@16
|
112 //
|
Chris@16
|
113 // where N runs from 0 to BOOST_PYTHON_MAX_ARITY.
|
Chris@16
|
114 //
|
Chris@16
|
115 // The set of overloaded functions (define_stub_function) expects:
|
Chris@16
|
116 //
|
Chris@16
|
117 // 1. char const* name: function name that will be visible to python
|
Chris@16
|
118 // 2. OverloadsT: a function overloads struct (see defaults_gen.hpp)
|
Chris@16
|
119 // 3. NameSpaceT& name_space: a python::class_ or python::module instance
|
Chris@16
|
120 // 4. int_t<N>: the Nth overloaded function (OverloadsT::func_N)
|
Chris@16
|
121 // (see defaults_gen.hpp)
|
Chris@16
|
122 // 5. char const* name: doc string
|
Chris@16
|
123 //
|
Chris@16
|
124 // @group define_stub_function<N> {
|
Chris@16
|
125 template <int N>
|
Chris@16
|
126 struct define_stub_function {};
|
Chris@16
|
127
|
Chris@16
|
128 #define BOOST_PP_ITERATION_PARAMS_1 \
|
Chris@16
|
129 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>))
|
Chris@16
|
130
|
Chris@16
|
131 #include BOOST_PP_ITERATE()
|
Chris@16
|
132
|
Chris@16
|
133 // }
|
Chris@16
|
134
|
Chris@16
|
135 // This helper template struct does the actual recursive
|
Chris@16
|
136 // definition. There's a generic version
|
Chris@16
|
137 // define_with_defaults_helper<N> and a terminal case
|
Chris@16
|
138 // define_with_defaults_helper<0>. The struct and its
|
Chris@16
|
139 // specialization has a sole static member function def that
|
Chris@16
|
140 // expects:
|
Chris@16
|
141 //
|
Chris@16
|
142 // 1. char const* name: function name that will be
|
Chris@16
|
143 // visible to python
|
Chris@16
|
144 //
|
Chris@16
|
145 // 2. OverloadsT: a function overloads struct
|
Chris@16
|
146 // (see defaults_gen.hpp)
|
Chris@16
|
147 //
|
Chris@16
|
148 // 3. NameSpaceT& name_space: a python::class_ or
|
Chris@16
|
149 // python::module instance
|
Chris@16
|
150 //
|
Chris@16
|
151 // 4. char const* name: doc string
|
Chris@16
|
152 //
|
Chris@16
|
153 // The def static member function calls a corresponding
|
Chris@16
|
154 // define_stub_function<N>. The general case recursively calls
|
Chris@16
|
155 // define_with_defaults_helper<N-1>::def until it reaches the
|
Chris@16
|
156 // terminal case case define_with_defaults_helper<0>.
|
Chris@16
|
157 template <int N>
|
Chris@16
|
158 struct define_with_defaults_helper {
|
Chris@16
|
159
|
Chris@16
|
160 template <class StubsT, class CallPolicies, class NameSpaceT>
|
Chris@16
|
161 static void
|
Chris@16
|
162 def(
|
Chris@16
|
163 char const* name,
|
Chris@16
|
164 StubsT stubs,
|
Chris@16
|
165 keyword_range kw,
|
Chris@16
|
166 CallPolicies const& policies,
|
Chris@16
|
167 NameSpaceT& name_space,
|
Chris@16
|
168 char const* doc)
|
Chris@16
|
169 {
|
Chris@16
|
170 // define the NTH stub function of stubs
|
Chris@16
|
171 define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
|
Chris@16
|
172
|
Chris@16
|
173 if (kw.second > kw.first)
|
Chris@16
|
174 --kw.second;
|
Chris@16
|
175
|
Chris@16
|
176 // call the next define_with_defaults_helper
|
Chris@16
|
177 define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc);
|
Chris@16
|
178 }
|
Chris@16
|
179 };
|
Chris@16
|
180
|
Chris@16
|
181 template <>
|
Chris@16
|
182 struct define_with_defaults_helper<0> {
|
Chris@16
|
183
|
Chris@16
|
184 template <class StubsT, class CallPolicies, class NameSpaceT>
|
Chris@16
|
185 static void
|
Chris@16
|
186 def(
|
Chris@16
|
187 char const* name,
|
Chris@16
|
188 StubsT stubs,
|
Chris@16
|
189 keyword_range const& kw,
|
Chris@16
|
190 CallPolicies const& policies,
|
Chris@16
|
191 NameSpaceT& name_space,
|
Chris@16
|
192 char const* doc)
|
Chris@16
|
193 {
|
Chris@16
|
194 // define the Oth stub function of stubs
|
Chris@16
|
195 define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc);
|
Chris@16
|
196 // return
|
Chris@16
|
197 }
|
Chris@16
|
198 };
|
Chris@16
|
199
|
Chris@16
|
200 // define_with_defaults
|
Chris@16
|
201 //
|
Chris@16
|
202 // 1. char const* name: function name that will be
|
Chris@16
|
203 // visible to python
|
Chris@16
|
204 //
|
Chris@16
|
205 // 2. OverloadsT: a function overloads struct
|
Chris@16
|
206 // (see defaults_gen.hpp)
|
Chris@16
|
207 //
|
Chris@16
|
208 // 3. CallPolicies& policies: Call policies
|
Chris@16
|
209 // 4. NameSpaceT& name_space: a python::class_ or
|
Chris@16
|
210 // python::module instance
|
Chris@16
|
211 //
|
Chris@16
|
212 // 5. SigT sig: Function signature typelist
|
Chris@16
|
213 // (see defaults_gen.hpp)
|
Chris@16
|
214 //
|
Chris@16
|
215 // 6. char const* name: doc string
|
Chris@16
|
216 //
|
Chris@16
|
217 // This is the main entry point. This function recursively
|
Chris@16
|
218 // defines all stub functions of StubT (see defaults_gen.hpp) in
|
Chris@16
|
219 // NameSpaceT name_space which can be either a python::class_ or
|
Chris@16
|
220 // a python::module. The sig argument is a typelist that
|
Chris@16
|
221 // specifies the return type, the class (for member functions,
|
Chris@16
|
222 // and the arguments. Here are some SigT examples:
|
Chris@16
|
223 //
|
Chris@16
|
224 // int foo(int) mpl::vector<int, int>
|
Chris@16
|
225 // void bar(int, int) mpl::vector<void, int, int>
|
Chris@16
|
226 // void C::foo(int) mpl::vector<void, C, int>
|
Chris@16
|
227 //
|
Chris@16
|
228 template <class OverloadsT, class NameSpaceT, class SigT>
|
Chris@16
|
229 inline void
|
Chris@16
|
230 define_with_defaults(
|
Chris@16
|
231 char const* name,
|
Chris@16
|
232 OverloadsT const& overloads,
|
Chris@16
|
233 NameSpaceT& name_space,
|
Chris@16
|
234 SigT const&)
|
Chris@16
|
235 {
|
Chris@16
|
236 typedef typename mpl::front<SigT>::type return_type;
|
Chris@16
|
237 typedef typename OverloadsT::void_return_type void_return_type;
|
Chris@16
|
238 typedef typename OverloadsT::non_void_return_type non_void_return_type;
|
Chris@16
|
239
|
Chris@16
|
240 typedef typename mpl::if_c<
|
Chris@16
|
241 boost::is_same<void, return_type>::value
|
Chris@16
|
242 , void_return_type
|
Chris@16
|
243 , non_void_return_type
|
Chris@16
|
244 >::type stubs_type;
|
Chris@16
|
245
|
Chris@16
|
246 BOOST_STATIC_ASSERT(
|
Chris@16
|
247 (stubs_type::max_args) <= mpl::size<SigT>::value);
|
Chris@16
|
248
|
Chris@16
|
249 typedef typename stubs_type::template gen<SigT> gen_type;
|
Chris@16
|
250 define_with_defaults_helper<stubs_type::n_funcs-1>::def(
|
Chris@16
|
251 name
|
Chris@16
|
252 , gen_type()
|
Chris@16
|
253 , overloads.keywords()
|
Chris@16
|
254 , overloads.call_policies()
|
Chris@16
|
255 , name_space
|
Chris@16
|
256 , overloads.doc_string());
|
Chris@16
|
257 }
|
Chris@16
|
258
|
Chris@16
|
259 } // namespace detail
|
Chris@16
|
260
|
Chris@16
|
261 }} // namespace boost::python
|
Chris@16
|
262
|
Chris@16
|
263 #endif // DEFAULTS_DEF_JDG20020811_HPP
|
Chris@16
|
264
|
Chris@16
|
265 #else // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
266 // PP vertical iteration code
|
Chris@16
|
267
|
Chris@16
|
268
|
Chris@16
|
269 template <>
|
Chris@16
|
270 struct define_stub_function<BOOST_PP_ITERATION()> {
|
Chris@16
|
271 template <class StubsT, class CallPolicies, class NameSpaceT>
|
Chris@16
|
272 static void define(
|
Chris@16
|
273 char const* name
|
Chris@16
|
274 , StubsT const&
|
Chris@16
|
275 , keyword_range const& kw
|
Chris@16
|
276 , CallPolicies const& policies
|
Chris@16
|
277 , NameSpaceT& name_space
|
Chris@16
|
278 , char const* doc)
|
Chris@16
|
279 {
|
Chris@16
|
280 detail::name_space_def(
|
Chris@16
|
281 name_space
|
Chris@16
|
282 , name
|
Chris@16
|
283 , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION())
|
Chris@16
|
284 , kw
|
Chris@16
|
285 , policies
|
Chris@16
|
286 , doc
|
Chris@16
|
287 , &name_space);
|
Chris@16
|
288 }
|
Chris@16
|
289 };
|
Chris@16
|
290
|
Chris@16
|
291 #endif // !defined(BOOST_PP_IS_ITERATING)
|