2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-24 18:12:43 +00:00

Auto-detection of class memebers wrapped with make_getter()

[SVN r16241]
This commit is contained in:
Dave Abrahams
2002-11-14 17:41:13 +00:00
parent a21727741f
commit f2797ec262
8 changed files with 81 additions and 14 deletions

View File

@@ -38,6 +38,11 @@ namespace detail
struct builtin_to_python
{
static bool convertible() { return true; }
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
// but it will have to serve for now.
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
};
}

View File

@@ -9,11 +9,15 @@
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/mpl/if.hpp>
# include <boost/bind.hpp>
namespace boost { namespace python {
@@ -44,7 +48,7 @@ namespace detail
static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
{
// check that each of the arguments is convertible
arg_from_python<Class*> c0(PyTuple_GET_ITEM(args_, 0));
arg_from_python<Class&> c0(PyTuple_GET_ITEM(args_, 0));
if (!c0.convertible()) return 0;
typedef typename add_const<Data>::type target1;
@@ -55,22 +59,40 @@ namespace detail
if (!policies.precall(args_)) return 0;
(c0(PyTuple_GET_ITEM(args_, 0)))->*pm = c1(PyTuple_GET_ITEM(args_, 1));
(c0(PyTuple_GET_ITEM(args_, 0))).*pm = c1(PyTuple_GET_ITEM(args_, 1));
return policies.postcall(args_, detail::none());
}
};
// If it's a regular class type (not an object manager or other
// type for which we have to_python specializations, use
// return_internal_reference so that we can do things like
// x.y.z = 1
// and get the right result.
template <class T>
struct default_getter_policy
: mpl::if_c<
to_python_value<
typename add_reference<
typename add_const<T>::type
>::type
>::uses_registry
, return_internal_reference<>
, return_value_policy<return_by_value>
>
{};
}
template <class C, class D>
object make_getter(D C::*pm)
{
typedef return_value_policy<return_by_value> default_policy;
typedef typename detail::default_getter_policy<D>::type policy;
return objects::function_object(
::boost::bind(
&detail::member<D,C,default_policy>::get, pm, _1, _2
, default_policy())
&detail::member<D,C,policy>::get, pm, _1, _2
, policy())
, 1);
}

View File

@@ -29,6 +29,11 @@ namespace detail
static bool convertible();
PyObject* operator()(argument_type) const;
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
// but it will have to serve for now.
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
};
@@ -41,6 +46,11 @@ namespace detail
static bool convertible();
PyObject* operator()(argument_type) const;
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
// but it will have to serve for now.
BOOST_STATIC_CONSTANT(bool, uses_registry = true);
};
}