99# include < boost/python/detail/config.hpp>
1010# include < boost/python/detail/wrap_python.hpp>
1111# include < boost/type_traits/transform_traits.hpp>
12- # include < boost/type_traits/cv_traits.hpp>
12+ # include < boost/type_traits/add_const.hpp>
13+ # include < boost/type_traits/add_reference.hpp>
1314# include < boost/python/return_value_policy.hpp>
1415# include < boost/python/return_by_value.hpp>
16+ # include < boost/python/return_internal_reference.hpp>
1517# include < boost/python/object/function_object.hpp>
1618# include < boost/python/arg_from_python.hpp>
19+ # include < boost/python/converter/builtin_converters.hpp>
20+ # include < boost/mpl/if.hpp>
1721# include < boost/bind.hpp>
1822
1923namespace boost { namespace python {
@@ -44,7 +48,7 @@ namespace detail
4448 static PyObject* set (Data Class::*pm, PyObject* args_, PyObject*, Policies const & policies)
4549 {
4650 // check that each of the arguments is convertible
47- arg_from_python<Class* > c0 (PyTuple_GET_ITEM (args_, 0 ));
51+ arg_from_python<Class& > c0 (PyTuple_GET_ITEM (args_, 0 ));
4852 if (!c0.convertible ()) return 0 ;
4953
5054 typedef typename add_const<Data>::type target1;
@@ -55,22 +59,40 @@ namespace detail
5559
5660 if (!policies.precall (args_)) return 0 ;
5761
58- (c0 (PyTuple_GET_ITEM (args_, 0 )))-> *pm = c1 (PyTuple_GET_ITEM (args_, 1 ));
62+ (c0 (PyTuple_GET_ITEM (args_, 0 ))). *pm = c1 (PyTuple_GET_ITEM (args_, 1 ));
5963
6064 return policies.postcall (args_, detail::none ());
6165 }
6266 };
67+
68+ // If it's a regular class type (not an object manager or other
69+ // type for which we have to_python specializations, use
70+ // return_internal_reference so that we can do things like
71+ // x.y.z = 1
72+ // and get the right result.
73+ template <class T >
74+ struct default_getter_policy
75+ : mpl::if_c<
76+ to_python_value<
77+ typename add_reference<
78+ typename add_const<T>::type
79+ >::type
80+ >::uses_registry
81+ , return_internal_reference<>
82+ , return_value_policy<return_by_value>
83+ >
84+ {};
6385}
6486
6587template <class C , class D >
6688object make_getter (D C::*pm)
6789{
68- typedef return_value_policy<return_by_value> default_policy ;
90+ typedef typename detail::default_getter_policy<D>::type policy ;
6991
7092 return objects::function_object (
7193 ::boost::bind (
72- &detail::member<D,C,default_policy >::get, pm, _1, _2
73- , default_policy ())
94+ &detail::member<D,C,policy >::get, pm, _1, _2
95+ , policy ())
7496 , 1);
7597
7698}
0 commit comments