2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 16:32:16 +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

@@ -29,6 +29,11 @@
<hr>
<dl class="page-index">
<dt>14 November 2002</dt>
<dd>Auto-detection of class data members wrapped with <a href=
"v2/data_members.html#make_getter-spec"><code>make_getter</code></a></dd>
<dt>13 November 2002</dt>
<dd>Full Support for <code>std::auto_ptr&lt;&gt;</code> added.</dd>

View File

@@ -77,7 +77,15 @@ template &lt;class C, class D, class Policies&gt;
<code>C*</code>, and returns the corresponding member <code>D</code>
member of the <code>C</code> object, converted <code>to_python</code>.
If <code>policies</code> is supplied, it will be applied to the
function as described <a href="CallPolicies.html">here</a>.</dt>
function as described <a href="CallPolicies.html">here</a>. Otherwise,
the library attempts to determine whether <code>D</code> is a
user-defined class type, and if so uses <code><a href=
"return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a>&lt;&gt;</code></dt>
<dt>for <code>Policies</code>. Note that this test may inappropriately
choose <code>return_internal_reference&lt;&gt;</code> in some cases
when <code>D</code> is a smart pointer type. This is a known
defect.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
@@ -147,8 +155,8 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

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);
};
}

View File

@@ -24,12 +24,13 @@ double get_fair_value(X const& x) { return x.value(); }
struct Var
{
Var(std::string name_) : name(name_), value(), name2(name.c_str()) {}
Var(std::string name_) : name(name_), value(), name2(name.c_str()), y(6) {}
std::string const name;
std::string get_name1() const { return name; }
std::string const& get_name2() const { return name; }
float value;
char const* name2;
Y y;
};
BOOST_PYTHON_MODULE(data_members_ext)
@@ -51,6 +52,7 @@ BOOST_PYTHON_MODULE(data_members_ext)
.def_readonly("name", &Var::name)
.def_readonly("name2", &Var::name2)
.def_readwrite("value", &Var::value)
.def_readonly("y", &Var::y)
// Test return_by_value for plain values and for
// pointers... return_by_value was implemented as a

View File

@@ -30,6 +30,11 @@
>>> v.get_name2()
'pi'
>>> v.y.x
6
>>> v.y.x = -7
>>> v.y.x
-7
'''
def run(args = None):

View File

@@ -1,11 +1,21 @@
Wrap enums as a subclass of Python int
High Priority:
--------------
Document builtin correspondences between builtiin Python types and C++
types
Medium Priority:
----------------
Implement type_info streaming for GCC
(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html)
Low Priority:
------------
Write "inside the Python type system", a survey of typeobject.c in
Python source -- may go hand-in-hand with enum wrapping
Better overload resolution - choose best match
Implement type_info streaming for GCC
(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html)