Chris@16
|
1 // Copyright David Abrahams 2002.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
3 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 #ifndef CLASS_DWA200216_HPP
|
Chris@16
|
6 # define CLASS_DWA200216_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # include <boost/python/detail/prefix.hpp>
|
Chris@16
|
9
|
Chris@16
|
10 # include <boost/noncopyable.hpp>
|
Chris@16
|
11
|
Chris@16
|
12 # include <boost/python/class_fwd.hpp>
|
Chris@16
|
13 # include <boost/python/object/class.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 # include <boost/python/object.hpp>
|
Chris@16
|
16 # include <boost/python/type_id.hpp>
|
Chris@16
|
17 # include <boost/python/data_members.hpp>
|
Chris@16
|
18 # include <boost/python/make_function.hpp>
|
Chris@16
|
19 # include <boost/python/signature.hpp>
|
Chris@16
|
20 # include <boost/python/init.hpp>
|
Chris@16
|
21 # include <boost/python/args_fwd.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 # include <boost/python/object/class_metadata.hpp>
|
Chris@16
|
24 # include <boost/python/object/pickle_support.hpp>
|
Chris@16
|
25 # include <boost/python/object/add_to_namespace.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 # include <boost/python/detail/overloads_fwd.hpp>
|
Chris@16
|
28 # include <boost/python/detail/operator_id.hpp>
|
Chris@16
|
29 # include <boost/python/detail/def_helper.hpp>
|
Chris@16
|
30 # include <boost/python/detail/force_instantiate.hpp>
|
Chris@16
|
31 # include <boost/python/detail/unwrap_type_id.hpp>
|
Chris@16
|
32 # include <boost/python/detail/unwrap_wrapper.hpp>
|
Chris@16
|
33
|
Chris@16
|
34 # include <boost/type_traits/is_same.hpp>
|
Chris@16
|
35 # include <boost/type_traits/is_member_function_pointer.hpp>
|
Chris@16
|
36 # include <boost/type_traits/is_polymorphic.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 # include <boost/mpl/size.hpp>
|
Chris@16
|
39 # include <boost/mpl/for_each.hpp>
|
Chris@16
|
40 # include <boost/mpl/bool.hpp>
|
Chris@16
|
41 # include <boost/mpl/not.hpp>
|
Chris@16
|
42
|
Chris@16
|
43 # include <boost/detail/workaround.hpp>
|
Chris@16
|
44
|
Chris@16
|
45 # if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) \
|
Chris@16
|
46 /* pro9 reintroduced the bug */ \
|
Chris@16
|
47 || (BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
|
Chris@16
|
48 && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) \
|
Chris@16
|
49 || BOOST_WORKAROUND(__GNUC__, < 3)
|
Chris@16
|
50
|
Chris@16
|
51 # define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
|
Chris@16
|
52
|
Chris@16
|
53 # endif
|
Chris@16
|
54
|
Chris@16
|
55 # ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
|
Chris@16
|
56 # include <boost/mpl/and.hpp>
|
Chris@16
|
57 # include <boost/type_traits/is_member_pointer.hpp>
|
Chris@16
|
58 # endif
|
Chris@16
|
59
|
Chris@16
|
60 namespace boost { namespace python {
|
Chris@16
|
61
|
Chris@16
|
62 template <class DerivedVisitor> class def_visitor;
|
Chris@16
|
63
|
Chris@16
|
64 enum no_init_t { no_init };
|
Chris@16
|
65
|
Chris@16
|
66 namespace detail
|
Chris@16
|
67 {
|
Chris@16
|
68 // This function object is used with mpl::for_each to write the id
|
Chris@16
|
69 // of the type a pointer to which is passed as its 2nd compile-time
|
Chris@16
|
70 // argument. into the iterator pointed to by its runtime argument
|
Chris@16
|
71 struct write_type_id
|
Chris@16
|
72 {
|
Chris@16
|
73 write_type_id(type_info**p) : p(p) {}
|
Chris@16
|
74
|
Chris@16
|
75 // Here's the runtime behavior
|
Chris@16
|
76 template <class T>
|
Chris@16
|
77 void operator()(T*) const
|
Chris@16
|
78 {
|
Chris@16
|
79 *(*p)++ = type_id<T>();
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 type_info** p;
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85 template <class T>
|
Chris@16
|
86 struct is_data_member_pointer
|
Chris@16
|
87 : mpl::and_<
|
Chris@16
|
88 is_member_pointer<T>
|
Chris@16
|
89 , mpl::not_<is_member_function_pointer<T> >
|
Chris@16
|
90 >
|
Chris@16
|
91 {};
|
Chris@16
|
92
|
Chris@16
|
93 # ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
|
Chris@16
|
94 # define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , detail::is_data_member_pointer<D>()
|
Chris@16
|
95 # define BOOST_PYTHON_YES_DATA_MEMBER , mpl::true_
|
Chris@16
|
96 # define BOOST_PYTHON_NO_DATA_MEMBER , mpl::false_
|
Chris@16
|
97 # elif defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
Chris@16
|
98 # define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , 0
|
Chris@16
|
99 # define BOOST_PYTHON_YES_DATA_MEMBER , int
|
Chris@16
|
100 # define BOOST_PYTHON_NO_DATA_MEMBER , ...
|
Chris@16
|
101 # else
|
Chris@16
|
102 # define BOOST_PYTHON_DATA_MEMBER_HELPER(D)
|
Chris@16
|
103 # define BOOST_PYTHON_YES_DATA_MEMBER
|
Chris@16
|
104 # define BOOST_PYTHON_NO_DATA_MEMBER
|
Chris@16
|
105 # endif
|
Chris@16
|
106
|
Chris@16
|
107 namespace error
|
Chris@16
|
108 {
|
Chris@16
|
109 //
|
Chris@16
|
110 // A meta-assertion mechanism which prints nice error messages and
|
Chris@16
|
111 // backtraces on lots of compilers. Usage:
|
Chris@16
|
112 //
|
Chris@16
|
113 // assertion<C>::failed
|
Chris@16
|
114 //
|
Chris@16
|
115 // where C is an MPL metafunction class
|
Chris@16
|
116 //
|
Chris@16
|
117
|
Chris@16
|
118 template <class C> struct assertion_failed { };
|
Chris@16
|
119 template <class C> struct assertion_ok { typedef C failed; };
|
Chris@16
|
120
|
Chris@16
|
121 template <class C>
|
Chris@16
|
122 struct assertion
|
Chris@16
|
123 : mpl::if_<C, assertion_ok<C>, assertion_failed<C> >::type
|
Chris@16
|
124 {};
|
Chris@16
|
125
|
Chris@16
|
126 //
|
Chris@16
|
127 // Checks for validity of arguments used to define virtual
|
Chris@16
|
128 // functions with default implementations.
|
Chris@16
|
129 //
|
Chris@16
|
130
|
Chris@16
|
131 template <class Default>
|
Chris@16
|
132 void not_a_derived_class_member(Default) {}
|
Chris@16
|
133
|
Chris@16
|
134 template <class T, class Fn>
|
Chris@16
|
135 struct virtual_function_default
|
Chris@16
|
136 {
|
Chris@16
|
137 template <class Default>
|
Chris@16
|
138 static void
|
Chris@16
|
139 must_be_derived_class_member(Default const&)
|
Chris@16
|
140 {
|
Chris@16
|
141 // https://svn.boost.org/trac/boost/ticket/5803
|
Chris@16
|
142 //typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
|
Chris@16
|
143 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
Chris@16
|
144 typedef typename assertion<is_polymorphic<T> >::failed test1;
|
Chris@16
|
145 # endif
|
Chris@16
|
146 typedef typename assertion<is_member_function_pointer<Fn> >::failed test2;
|
Chris@16
|
147 not_a_derived_class_member<Default>(Fn());
|
Chris@16
|
148 }
|
Chris@16
|
149 };
|
Chris@16
|
150 }
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 // This is the primary mechanism through which users will expose
|
Chris@16
|
154 // C++ classes to Python.
|
Chris@16
|
155 template <
|
Chris@16
|
156 class W // class being wrapped
|
Chris@16
|
157 , class X1 // = detail::not_specified
|
Chris@16
|
158 , class X2 // = detail::not_specified
|
Chris@16
|
159 , class X3 // = detail::not_specified
|
Chris@16
|
160 >
|
Chris@16
|
161 class class_ : public objects::class_base
|
Chris@16
|
162 {
|
Chris@16
|
163 public: // types
|
Chris@16
|
164 typedef objects::class_base base;
|
Chris@16
|
165 typedef class_<W,X1,X2,X3> self;
|
Chris@16
|
166 typedef typename objects::class_metadata<W,X1,X2,X3> metadata;
|
Chris@16
|
167 typedef W wrapped_type;
|
Chris@16
|
168
|
Chris@16
|
169 private: // types
|
Chris@16
|
170
|
Chris@16
|
171 // A helper class which will contain an array of id objects to be
|
Chris@16
|
172 // passed to the base class constructor
|
Chris@16
|
173 struct id_vector
|
Chris@16
|
174 {
|
Chris@16
|
175 typedef typename metadata::bases bases;
|
Chris@16
|
176
|
Chris@16
|
177 id_vector()
|
Chris@16
|
178 {
|
Chris@16
|
179 // Stick the derived class id into the first element of the array
|
Chris@16
|
180 ids[0] = detail::unwrap_type_id((W*)0, (W*)0);
|
Chris@16
|
181
|
Chris@16
|
182 // Write the rest of the elements into succeeding positions.
|
Chris@16
|
183 type_info* p = ids + 1;
|
Chris@16
|
184 mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer<mpl::_>*)0);
|
Chris@16
|
185 }
|
Chris@16
|
186
|
Chris@16
|
187 BOOST_STATIC_CONSTANT(
|
Chris@16
|
188 std::size_t, size = mpl::size<bases>::value + 1);
|
Chris@16
|
189 type_info ids[size];
|
Chris@16
|
190 };
|
Chris@16
|
191 friend struct id_vector;
|
Chris@16
|
192
|
Chris@16
|
193 public: // constructors
|
Chris@16
|
194
|
Chris@16
|
195 // Construct with the class name, with or without docstring, and default __init__() function
|
Chris@16
|
196 class_(char const* name, char const* doc = 0);
|
Chris@16
|
197
|
Chris@16
|
198 // Construct with class name, no docstring, and an uncallable __init__ function
|
Chris@16
|
199 class_(char const* name, no_init_t);
|
Chris@16
|
200
|
Chris@16
|
201 // Construct with class name, docstring, and an uncallable __init__ function
|
Chris@16
|
202 class_(char const* name, char const* doc, no_init_t);
|
Chris@16
|
203
|
Chris@16
|
204 // Construct with class name and init<> function
|
Chris@16
|
205 template <class DerivedT>
|
Chris@16
|
206 inline class_(char const* name, init_base<DerivedT> const& i)
|
Chris@16
|
207 : base(name, id_vector::size, id_vector().ids)
|
Chris@16
|
208 {
|
Chris@16
|
209 this->initialize(i);
|
Chris@16
|
210 }
|
Chris@16
|
211
|
Chris@16
|
212 // Construct with class name, docstring and init<> function
|
Chris@16
|
213 template <class DerivedT>
|
Chris@16
|
214 inline class_(char const* name, char const* doc, init_base<DerivedT> const& i)
|
Chris@16
|
215 : base(name, id_vector::size, id_vector().ids, doc)
|
Chris@16
|
216 {
|
Chris@16
|
217 this->initialize(i);
|
Chris@16
|
218 }
|
Chris@16
|
219
|
Chris@16
|
220 public: // member functions
|
Chris@16
|
221
|
Chris@16
|
222 // Generic visitation
|
Chris@16
|
223 template <class Derived>
|
Chris@16
|
224 self& def(def_visitor<Derived> const& visitor)
|
Chris@16
|
225 {
|
Chris@16
|
226 visitor.visit(*this);
|
Chris@16
|
227 return *this;
|
Chris@16
|
228 }
|
Chris@16
|
229
|
Chris@16
|
230 // Wrap a member function or a non-member function which can take
|
Chris@16
|
231 // a T, T cv&, or T cv* as its first parameter, a callable
|
Chris@16
|
232 // python object, or a generic visitor.
|
Chris@16
|
233 template <class F>
|
Chris@16
|
234 self& def(char const* name, F f)
|
Chris@16
|
235 {
|
Chris@16
|
236 this->def_impl(
|
Chris@16
|
237 detail::unwrap_wrapper((W*)0)
|
Chris@16
|
238 , name, f, detail::def_helper<char const*>(0), &f);
|
Chris@16
|
239 return *this;
|
Chris@16
|
240 }
|
Chris@16
|
241
|
Chris@16
|
242 template <class A1, class A2>
|
Chris@16
|
243 self& def(char const* name, A1 a1, A2 const& a2)
|
Chris@16
|
244 {
|
Chris@16
|
245 this->def_maybe_overloads(name, a1, a2, &a2);
|
Chris@16
|
246 return *this;
|
Chris@16
|
247 }
|
Chris@16
|
248
|
Chris@16
|
249 template <class Fn, class A1, class A2>
|
Chris@16
|
250 self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2)
|
Chris@16
|
251 {
|
Chris@16
|
252 // The arguments are definitely:
|
Chris@16
|
253 // def(name, function, policy, doc_string)
|
Chris@16
|
254 // def(name, function, doc_string, policy)
|
Chris@16
|
255
|
Chris@16
|
256 this->def_impl(
|
Chris@16
|
257 detail::unwrap_wrapper((W*)0)
|
Chris@16
|
258 , name, fn
|
Chris@16
|
259 , detail::def_helper<A1,A2>(a1,a2)
|
Chris@16
|
260 , &fn);
|
Chris@16
|
261
|
Chris@16
|
262 return *this;
|
Chris@16
|
263 }
|
Chris@16
|
264
|
Chris@16
|
265 template <class Fn, class A1, class A2, class A3>
|
Chris@16
|
266 self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
|
Chris@16
|
267 {
|
Chris@16
|
268 this->def_impl(
|
Chris@16
|
269 detail::unwrap_wrapper((W*)0)
|
Chris@16
|
270 , name, fn
|
Chris@16
|
271 , detail::def_helper<A1,A2,A3>(a1,a2,a3)
|
Chris@16
|
272 , &fn);
|
Chris@16
|
273
|
Chris@16
|
274 return *this;
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 //
|
Chris@16
|
278 // Data member access
|
Chris@16
|
279 //
|
Chris@16
|
280 template <class D>
|
Chris@16
|
281 self& def_readonly(char const* name, D const& d, char const* doc=0)
|
Chris@16
|
282 {
|
Chris@16
|
283 return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
|
Chris@16
|
284 }
|
Chris@16
|
285
|
Chris@16
|
286 template <class D>
|
Chris@16
|
287 self& def_readwrite(char const* name, D const& d, char const* doc=0)
|
Chris@16
|
288 {
|
Chris@16
|
289 return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
|
Chris@16
|
290 }
|
Chris@16
|
291
|
Chris@16
|
292 template <class D>
|
Chris@16
|
293 self& def_readonly(char const* name, D& d, char const* doc=0)
|
Chris@16
|
294 {
|
Chris@16
|
295 return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
|
Chris@16
|
296 }
|
Chris@16
|
297
|
Chris@16
|
298 template <class D>
|
Chris@16
|
299 self& def_readwrite(char const* name, D& d, char const* doc=0)
|
Chris@16
|
300 {
|
Chris@16
|
301 return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 // Property creation
|
Chris@16
|
305 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
Chris@16
|
306 template <class Get>
|
Chris@16
|
307 self& add_property(char const* name, Get fget, char const* docstr = 0)
|
Chris@16
|
308 {
|
Chris@16
|
309 base::add_property(name, this->make_getter(fget), docstr);
|
Chris@16
|
310 return *this;
|
Chris@16
|
311 }
|
Chris@16
|
312
|
Chris@16
|
313 template <class Get, class Set>
|
Chris@16
|
314 self& add_property(char const* name, Get fget, Set fset, char const* docstr = 0)
|
Chris@16
|
315 {
|
Chris@16
|
316 base::add_property(
|
Chris@16
|
317 name, this->make_getter(fget), this->make_setter(fset), docstr);
|
Chris@16
|
318 return *this;
|
Chris@16
|
319 }
|
Chris@16
|
320 # else
|
Chris@16
|
321 private:
|
Chris@16
|
322 template <class Get>
|
Chris@16
|
323 self& add_property_impl(char const* name, Get fget, char const* docstr, int)
|
Chris@16
|
324 {
|
Chris@16
|
325 base::add_property(name, this->make_getter(fget), docstr);
|
Chris@16
|
326 return *this;
|
Chris@16
|
327 }
|
Chris@16
|
328
|
Chris@16
|
329 template <class Get, class Set>
|
Chris@16
|
330 self& add_property_impl(char const* name, Get fget, Set fset, ...)
|
Chris@16
|
331 {
|
Chris@16
|
332 base::add_property(
|
Chris@16
|
333 name, this->make_getter(fget), this->make_setter(fset), 0);
|
Chris@16
|
334 return *this;
|
Chris@16
|
335 }
|
Chris@16
|
336
|
Chris@16
|
337 public:
|
Chris@16
|
338 template <class Get>
|
Chris@16
|
339 self& add_property(char const* name, Get fget)
|
Chris@16
|
340 {
|
Chris@16
|
341 base::add_property(name, this->make_getter(fget), 0);
|
Chris@16
|
342 return *this;
|
Chris@16
|
343 }
|
Chris@16
|
344
|
Chris@16
|
345 template <class Get, class DocStrOrSet>
|
Chris@16
|
346 self& add_property(char const* name, Get fget, DocStrOrSet docstr_or_set)
|
Chris@16
|
347 {
|
Chris@16
|
348 this->add_property_impl(name, this->make_getter(fget), docstr_or_set, 0);
|
Chris@16
|
349 return *this;
|
Chris@16
|
350 }
|
Chris@16
|
351
|
Chris@16
|
352 template <class Get, class Set>
|
Chris@16
|
353 self&
|
Chris@16
|
354 add_property(char const* name, Get fget, Set fset, char const* docstr)
|
Chris@16
|
355 {
|
Chris@16
|
356 base::add_property(
|
Chris@16
|
357 name, this->make_getter(fget), this->make_setter(fset), docstr);
|
Chris@16
|
358 return *this;
|
Chris@16
|
359 }
|
Chris@16
|
360 # endif
|
Chris@16
|
361
|
Chris@16
|
362 template <class Get>
|
Chris@16
|
363 self& add_static_property(char const* name, Get fget)
|
Chris@16
|
364 {
|
Chris@16
|
365 base::add_static_property(name, object(fget));
|
Chris@16
|
366 return *this;
|
Chris@16
|
367 }
|
Chris@16
|
368
|
Chris@16
|
369 template <class Get, class Set>
|
Chris@16
|
370 self& add_static_property(char const* name, Get fget, Set fset)
|
Chris@16
|
371 {
|
Chris@16
|
372 base::add_static_property(name, object(fget), object(fset));
|
Chris@16
|
373 return *this;
|
Chris@16
|
374 }
|
Chris@16
|
375
|
Chris@16
|
376 template <class U>
|
Chris@16
|
377 self& setattr(char const* name, U const& x)
|
Chris@16
|
378 {
|
Chris@16
|
379 this->base::setattr(name, object(x));
|
Chris@16
|
380 return *this;
|
Chris@16
|
381 }
|
Chris@16
|
382
|
Chris@16
|
383 // Pickle support
|
Chris@16
|
384 template <typename PickleSuiteType>
|
Chris@16
|
385 self& def_pickle(PickleSuiteType const& x)
|
Chris@16
|
386 {
|
Chris@16
|
387 error_messages::must_be_derived_from_pickle_suite(x);
|
Chris@16
|
388 detail::pickle_suite_finalize<PickleSuiteType>::register_(
|
Chris@16
|
389 *this,
|
Chris@16
|
390 &PickleSuiteType::getinitargs,
|
Chris@16
|
391 &PickleSuiteType::getstate,
|
Chris@16
|
392 &PickleSuiteType::setstate,
|
Chris@16
|
393 PickleSuiteType::getstate_manages_dict());
|
Chris@16
|
394 return *this;
|
Chris@16
|
395 }
|
Chris@16
|
396
|
Chris@16
|
397 self& enable_pickling()
|
Chris@16
|
398 {
|
Chris@16
|
399 this->base::enable_pickling_(false);
|
Chris@16
|
400 return *this;
|
Chris@16
|
401 }
|
Chris@16
|
402
|
Chris@16
|
403 self& staticmethod(char const* name)
|
Chris@16
|
404 {
|
Chris@16
|
405 this->make_method_static(name);
|
Chris@16
|
406 return *this;
|
Chris@16
|
407 }
|
Chris@16
|
408 private: // helper functions
|
Chris@16
|
409
|
Chris@16
|
410 // Builds a method for this class around the given [member]
|
Chris@16
|
411 // function pointer or object, appropriately adjusting the type of
|
Chris@16
|
412 // the first signature argument so that if f is a member of a
|
Chris@16
|
413 // (possibly not wrapped) base class of T, an lvalue argument of
|
Chris@16
|
414 // type T will be required.
|
Chris@16
|
415 //
|
Chris@16
|
416 // @group PropertyHelpers {
|
Chris@16
|
417 template <class F>
|
Chris@16
|
418 object make_getter(F f)
|
Chris@16
|
419 {
|
Chris@16
|
420 typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
|
Chris@16
|
421
|
Chris@16
|
422 return this->make_fn_impl(
|
Chris@16
|
423 detail::unwrap_wrapper((W*)0)
|
Chris@16
|
424 , f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
|
Chris@16
|
425 );
|
Chris@16
|
426 }
|
Chris@16
|
427
|
Chris@16
|
428 template <class F>
|
Chris@16
|
429 object make_setter(F f)
|
Chris@16
|
430 {
|
Chris@16
|
431 typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
|
Chris@16
|
432
|
Chris@16
|
433 return this->make_fn_impl(
|
Chris@16
|
434 detail::unwrap_wrapper((W*)0)
|
Chris@16
|
435 , f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
|
Chris@16
|
436 );
|
Chris@16
|
437 }
|
Chris@16
|
438
|
Chris@16
|
439 template <class T, class F>
|
Chris@16
|
440 object make_fn_impl(T*, F const& f, mpl::false_, void*, mpl::false_)
|
Chris@16
|
441 {
|
Chris@16
|
442 return python::make_function(f, default_call_policies(), detail::get_signature(f, (T*)0));
|
Chris@16
|
443 }
|
Chris@16
|
444
|
Chris@16
|
445 template <class T, class D, class B>
|
Chris@16
|
446 object make_fn_impl(T*, D B::*pm_, mpl::false_, char*, mpl::true_)
|
Chris@16
|
447 {
|
Chris@16
|
448 D T::*pm = pm_;
|
Chris@16
|
449 return python::make_getter(pm);
|
Chris@16
|
450 }
|
Chris@16
|
451
|
Chris@16
|
452 template <class T, class D, class B>
|
Chris@16
|
453 object make_fn_impl(T*, D B::*pm_, mpl::false_, int*, mpl::true_)
|
Chris@16
|
454 {
|
Chris@16
|
455 D T::*pm = pm_;
|
Chris@16
|
456 return python::make_setter(pm);
|
Chris@16
|
457 }
|
Chris@16
|
458
|
Chris@16
|
459 template <class T, class F>
|
Chris@16
|
460 object make_fn_impl(T*, F const& x, mpl::true_, void*, mpl::false_)
|
Chris@16
|
461 {
|
Chris@16
|
462 return x;
|
Chris@16
|
463 }
|
Chris@16
|
464 // }
|
Chris@16
|
465
|
Chris@16
|
466 template <class D, class B>
|
Chris@16
|
467 self& def_readonly_impl(
|
Chris@16
|
468 char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
|
Chris@16
|
469 {
|
Chris@16
|
470 return this->add_property(name, pm_, doc);
|
Chris@16
|
471 }
|
Chris@16
|
472
|
Chris@16
|
473 template <class D, class B>
|
Chris@16
|
474 self& def_readwrite_impl(
|
Chris@16
|
475 char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
|
Chris@16
|
476 {
|
Chris@16
|
477 return this->add_property(name, pm_, pm_, doc);
|
Chris@16
|
478 }
|
Chris@16
|
479
|
Chris@16
|
480 template <class D>
|
Chris@16
|
481 self& def_readonly_impl(
|
Chris@16
|
482 char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
|
Chris@16
|
483 {
|
Chris@16
|
484 return this->add_static_property(name, python::make_getter(d));
|
Chris@16
|
485 }
|
Chris@16
|
486
|
Chris@16
|
487 template <class D>
|
Chris@16
|
488 self& def_readwrite_impl(
|
Chris@16
|
489 char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
|
Chris@16
|
490 {
|
Chris@16
|
491 return this->add_static_property(name, python::make_getter(d), python::make_setter(d));
|
Chris@16
|
492 }
|
Chris@16
|
493
|
Chris@16
|
494 template <class DefVisitor>
|
Chris@16
|
495 inline void initialize(DefVisitor const& i)
|
Chris@16
|
496 {
|
Chris@16
|
497 metadata::register_(); // set up runtime metadata/conversions
|
Chris@16
|
498
|
Chris@16
|
499 typedef typename metadata::holder holder;
|
Chris@16
|
500 this->set_instance_size( objects::additional_instance_size<holder>::value );
|
Chris@16
|
501
|
Chris@16
|
502 this->def(i);
|
Chris@16
|
503 }
|
Chris@16
|
504
|
Chris@16
|
505 inline void initialize(no_init_t)
|
Chris@16
|
506 {
|
Chris@16
|
507 metadata::register_(); // set up runtime metadata/conversions
|
Chris@16
|
508 this->def_no_init();
|
Chris@16
|
509 }
|
Chris@16
|
510
|
Chris@16
|
511 //
|
Chris@16
|
512 // These two overloads discriminate between def() as applied to a
|
Chris@16
|
513 // generic visitor and everything else.
|
Chris@16
|
514 //
|
Chris@16
|
515 // @group def_impl {
|
Chris@16
|
516 template <class T, class Helper, class LeafVisitor, class Visitor>
|
Chris@16
|
517 inline void def_impl(
|
Chris@16
|
518 T*
|
Chris@16
|
519 , char const* name
|
Chris@16
|
520 , LeafVisitor
|
Chris@16
|
521 , Helper const& helper
|
Chris@16
|
522 , def_visitor<Visitor> const* v
|
Chris@16
|
523 )
|
Chris@16
|
524 {
|
Chris@16
|
525 v->visit(*this, name, helper);
|
Chris@16
|
526 }
|
Chris@16
|
527
|
Chris@16
|
528 template <class T, class Fn, class Helper>
|
Chris@16
|
529 inline void def_impl(
|
Chris@16
|
530 T*
|
Chris@16
|
531 , char const* name
|
Chris@16
|
532 , Fn fn
|
Chris@16
|
533 , Helper const& helper
|
Chris@16
|
534 , ...
|
Chris@16
|
535 )
|
Chris@16
|
536 {
|
Chris@16
|
537 objects::add_to_namespace(
|
Chris@16
|
538 *this
|
Chris@16
|
539 , name
|
Chris@16
|
540 , make_function(
|
Chris@16
|
541 fn
|
Chris@16
|
542 , helper.policies()
|
Chris@16
|
543 , helper.keywords()
|
Chris@16
|
544 , detail::get_signature(fn, (T*)0)
|
Chris@16
|
545 )
|
Chris@16
|
546 , helper.doc()
|
Chris@16
|
547 );
|
Chris@16
|
548
|
Chris@16
|
549 this->def_default(name, fn, helper, mpl::bool_<Helper::has_default_implementation>());
|
Chris@16
|
550 }
|
Chris@16
|
551 // }
|
Chris@16
|
552
|
Chris@16
|
553 //
|
Chris@16
|
554 // These two overloads handle the definition of default
|
Chris@16
|
555 // implementation overloads for virtual functions. The second one
|
Chris@16
|
556 // handles the case where no default implementation was specified.
|
Chris@16
|
557 //
|
Chris@16
|
558 // @group def_default {
|
Chris@16
|
559 template <class Fn, class Helper>
|
Chris@16
|
560 inline void def_default(
|
Chris@16
|
561 char const* name
|
Chris@16
|
562 , Fn
|
Chris@16
|
563 , Helper const& helper
|
Chris@16
|
564 , mpl::bool_<true>)
|
Chris@16
|
565 {
|
Chris@16
|
566 detail::error::virtual_function_default<W,Fn>::must_be_derived_class_member(
|
Chris@16
|
567 helper.default_implementation());
|
Chris@16
|
568
|
Chris@16
|
569 objects::add_to_namespace(
|
Chris@16
|
570 *this, name,
|
Chris@16
|
571 make_function(
|
Chris@16
|
572 helper.default_implementation(), helper.policies(), helper.keywords())
|
Chris@16
|
573 );
|
Chris@16
|
574 }
|
Chris@16
|
575
|
Chris@16
|
576 template <class Fn, class Helper>
|
Chris@16
|
577 inline void def_default(char const*, Fn, Helper const&, mpl::bool_<false>)
|
Chris@16
|
578 { }
|
Chris@16
|
579 // }
|
Chris@16
|
580
|
Chris@16
|
581 //
|
Chris@16
|
582 // These two overloads discriminate between def() as applied to
|
Chris@16
|
583 // regular functions and def() as applied to the result of
|
Chris@16
|
584 // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
|
Chris@16
|
585 // discriminate.
|
Chris@16
|
586 //
|
Chris@16
|
587 // @group def_maybe_overloads {
|
Chris@16
|
588 template <class OverloadsT, class SigT>
|
Chris@16
|
589 void def_maybe_overloads(
|
Chris@16
|
590 char const* name
|
Chris@16
|
591 , SigT sig
|
Chris@16
|
592 , OverloadsT const& overloads
|
Chris@16
|
593 , detail::overloads_base const*)
|
Chris@16
|
594
|
Chris@16
|
595 {
|
Chris@16
|
596 // convert sig to a type_list (see detail::get_signature in signature.hpp)
|
Chris@16
|
597 // before calling detail::define_with_defaults.
|
Chris@16
|
598 detail::define_with_defaults(
|
Chris@16
|
599 name, overloads, *this, detail::get_signature(sig));
|
Chris@16
|
600 }
|
Chris@16
|
601
|
Chris@16
|
602 template <class Fn, class A1>
|
Chris@16
|
603 void def_maybe_overloads(
|
Chris@16
|
604 char const* name
|
Chris@16
|
605 , Fn fn
|
Chris@16
|
606 , A1 const& a1
|
Chris@16
|
607 , ...)
|
Chris@16
|
608 {
|
Chris@16
|
609 this->def_impl(
|
Chris@16
|
610 detail::unwrap_wrapper((W*)0)
|
Chris@16
|
611 , name
|
Chris@16
|
612 , fn
|
Chris@16
|
613 , detail::def_helper<A1>(a1)
|
Chris@16
|
614 , &fn
|
Chris@16
|
615 );
|
Chris@16
|
616
|
Chris@16
|
617 }
|
Chris@16
|
618 // }
|
Chris@16
|
619 };
|
Chris@16
|
620
|
Chris@16
|
621
|
Chris@16
|
622 //
|
Chris@16
|
623 // implementations
|
Chris@16
|
624 //
|
Chris@16
|
625
|
Chris@16
|
626 template <class W, class X1, class X2, class X3>
|
Chris@16
|
627 inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc)
|
Chris@16
|
628 : base(name, id_vector::size, id_vector().ids, doc)
|
Chris@16
|
629 {
|
Chris@16
|
630 this->initialize(init<>());
|
Chris@16
|
631 // select_holder::assert_default_constructible();
|
Chris@16
|
632 }
|
Chris@16
|
633
|
Chris@16
|
634 template <class W, class X1, class X2, class X3>
|
Chris@16
|
635 inline class_<W,X1,X2,X3>::class_(char const* name, no_init_t)
|
Chris@16
|
636 : base(name, id_vector::size, id_vector().ids)
|
Chris@16
|
637 {
|
Chris@16
|
638 this->initialize(no_init);
|
Chris@16
|
639 }
|
Chris@16
|
640
|
Chris@16
|
641 template <class W, class X1, class X2, class X3>
|
Chris@16
|
642 inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
|
Chris@16
|
643 : base(name, id_vector::size, id_vector().ids, doc)
|
Chris@16
|
644 {
|
Chris@16
|
645 this->initialize(no_init);
|
Chris@16
|
646 }
|
Chris@16
|
647
|
Chris@16
|
648 }} // namespace boost::python
|
Chris@16
|
649
|
Chris@16
|
650 # undef BOOST_PYTHON_DATA_MEMBER_HELPER
|
Chris@16
|
651 # undef BOOST_PYTHON_YES_DATA_MEMBER
|
Chris@16
|
652 # undef BOOST_PYTHON_NO_DATA_MEMBER
|
Chris@16
|
653 # undef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
|
Chris@16
|
654
|
Chris@16
|
655 #endif // CLASS_DWA200216_HPP
|