88
99# include < boost/python/detail/prefix.hpp>
1010
11+ # include < boost/python/handle.hpp>
12+
1113# include < boost/python/return_value_policy.hpp>
1214# include < boost/python/return_by_value.hpp>
1315# include < boost/python/return_internal_reference.hpp>
14- # include < boost/python/arg_from_python.hpp>
15-
16- # include < boost/python/object/function_object.hpp>
16+ # include < boost/python/make_function.hpp>
1717
1818# include < boost/python/converter/builtin_converters.hpp>
1919
2424# include < boost/type_traits/add_reference.hpp>
2525# include < boost/type_traits/is_member_pointer.hpp>
2626
27+ # if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
28+ # include < boost/type_traits/remove_cv.hpp>
29+ # endif
30+
2731# include < boost/mpl/apply_if.hpp>
2832# include < boost/mpl/if.hpp>
2933# include < boost/mpl/vector/vector10.hpp>
3034
31- # include < boost/bind.hpp>
32-
3335# include < boost/detail/workaround.hpp>
3436
3537namespace boost { namespace python {
@@ -43,97 +45,57 @@ namespace boost { namespace python {
4345
4446namespace detail
4547{
46- //
47- // Raw Getter and Setter function generators. These class templates
48- // generate static functions which can be bound together with
49- // policies and wrapped to generate the python callable objects
50- // mentioned above.
51- //
5248
53- //
54- // Generates get and set functions for access through
55- // pointers-to-data-members
56- //
57- template <class Data , class Class , class Policies >
49+ // A small function object which handles the getting and setting of
50+ // data members.
51+ template <class Data , class Class >
5852 struct member
5953 {
60- static PyObject* get (Data Class::*pm, PyObject* args_, PyObject*, Policies const & policies)
54+ private:
55+ typedef typename add_const<Data>::type data_const;
56+ typedef typename add_reference<data_const>::type data_cref;
57+
58+ public:
59+ member (Data Class::*which) : m_which(which) {}
60+
61+ Data& operator ()(Class& c) const
6162 {
62- arg_from_python<Class*> c0 (PyTuple_GET_ITEM (args_, 0 ));
63- if (!c0.convertible ()) return 0 ;
64-
65- // find the result converter
66- typedef typename Policies::result_converter result_converter;
67- typedef typename boost::add_reference<Data>::type source;
68- typename mpl::apply1<result_converter,source>::type cr;
69-
70- if (!policies.precall (args_)) return 0 ;
71-
72- PyObject* result = cr ( (c0 ())->*pm );
73-
74- return policies.postcall (args_, result);
63+ return c.*m_which;
7564 }
76-
77- static PyObject* set (Data Class::*pm, PyObject* args_, PyObject*, Policies const & policies)
78- {
79- // check that each of the arguments is convertible
80- arg_from_python<Class&> c0 (PyTuple_GET_ITEM (args_, 0 ));
81- if (!c0.convertible ()) return 0 ;
82-
83- typedef typename add_const<Data>::type target1;
84- typedef typename add_reference<target1>::type target;
85- arg_from_python<target> c1 (PyTuple_GET_ITEM (args_, 1 ));
86-
87- if (!c1.convertible ()) return 0 ;
8865
89- if (!policies.precall (args_)) return 0 ;
90-
91- (c0 ()).*pm = c1 ();
92-
93- return policies.postcall (args_, detail::none ());
66+ void operator ()(Class& c, data_cref d) const
67+ {
68+ c.*m_which = d;
9469 }
70+ private:
71+ Data Class::*m_which;
9572 };
9673
97- //
98- // Generates get and set functions for access through ordinary
99- // pointers. These are generally used to wrap static data members,
100- // but can also be used to expose namespace-scope data as class
101- // attributes.
102- //
103- template <class Data , class Policies >
74+ // A small function object which handles the getting and setting of
75+ // non-member objects.
76+ template <class Data >
10477 struct datum
10578 {
106- static PyObject* get (Data *p, PyObject* args_, PyObject*, Policies const & policies)
79+ private:
80+ typedef typename add_const<Data>::type data_const;
81+ typedef typename add_reference<data_const>::type data_cref;
82+
83+ public:
84+ datum (Data *which) : m_which(which) {}
85+
86+ Data& operator ()() const
10787 {
108- // find the result converter
109- typedef typename Policies::result_converter result_converter;
110- typedef typename boost::add_reference<Data>::type source;
111- typename mpl::apply1<result_converter,source>::type cr;
112-
113- if (!policies.precall (args_)) return 0 ;
114-
115- PyObject* result = cr ( *p );
116-
117- return policies.postcall (args_, result);
88+ return *m_which;
11889 }
119-
120- static PyObject* set (Data* p, PyObject* args_, PyObject*, Policies const & policies)
121- {
122- // check that each of the arguments is convertible
123- typedef typename add_const<Data>::type target1;
124- typedef typename add_reference<target1>::type target;
125- arg_from_python<target> c0 (PyTuple_GET_ITEM (args_, 0 ));
126-
127- if (!c0.convertible ()) return 0 ;
12890
129- if (!policies.precall (args_)) return 0 ;
130-
131- *p = c0 ();
132-
133- return policies.postcall (args_, detail::none ());
91+ void operator ()(data_cref d) const
92+ {
93+ *m_which = d;
13494 }
95+ private:
96+ Data *m_which;
13597 };
136-
98+
13799 //
138100 // Helper metafunction for determining the default CallPolicy to use
139101 // for attribute access. If T is a [reference to a] class type X
@@ -208,13 +170,8 @@ namespace detail
208170 template <class D , class Policies >
209171 inline object make_getter (D* d, Policies const & policies, mpl::false_, int )
210172 {
211- return objects::function_object (
212- objects::py_function (
213- ::boost::bind (
214- &detail::datum<D,Policies>::get, d, _1, _2
215- , policies)
216- , mpl::vector1<D>()
217- )
173+ return python::make_function (
174+ detail::datum<D>(d), policies, mpl::vector1<D&>()
218175 );
219176 }
220177
@@ -230,14 +187,16 @@ namespace detail
230187 template <class C , class D , class Policies >
231188 inline object make_getter (D C::*pm, Policies const & policies, mpl::true_, int )
232189 {
233- return objects::function_object (
234- objects::py_function (
235- ::boost::bind (
236- &detail::member<D,C,Policies>::get, pm, _1, _2
237- , policies)
238- , mpl::vector2<D, C const *>()
239- )
240- );
190+ #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
191+ typedef typename remove_cv<C>::type Class;
192+ #else
193+ typedef C Class;
194+ #endif
195+ return python::make_function (
196+ detail::member<D,Class>(pm)
197+ , policies
198+ , mpl::vector2<D&,Class&>()
199+ );
241200 }
242201
243202 // Handle pointers-to-members without policies
@@ -268,27 +227,19 @@ namespace detail
268227 template <class D , class Policies >
269228 inline object make_setter (D* p, Policies const & policies, mpl::false_, int )
270229 {
271- return objects::function_object (
272- objects::py_function (
273- ::boost::bind (
274- &detail::datum<D,Policies>::set, p, _1, _2
275- , policies)
276- , mpl::vector2<void, D const &>()
277- )
230+ return python::make_function (
231+ detail::datum<D>(p), policies, mpl::vector2<void ,D const &>()
278232 );
279233 }
280234
281235 // Handle pointers-to-members
282236 template <class C , class D , class Policies >
283237 inline object make_setter (D C::*pm, Policies const & policies, mpl::true_, int )
284238 {
285- return objects::function_object (
286- objects::py_function (
287- ::boost::bind (
288- &detail::member<D,C,Policies>::set, pm, _1, _2
289- , policies)
290- , mpl::vector3<void, C*, D const &>()
291- )
239+ return python::make_function (
240+ detail::member<D,C>(pm)
241+ , policies
242+ , mpl::vector3<void , C&, D const &>()
292243 );
293244 }
294245
0 commit comments