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:
@@ -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<></code> added.</dd>
|
||||
|
||||
@@ -77,7 +77,15 @@ template <class C, class D, class Policies>
|
||||
<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><></code></dt>
|
||||
|
||||
<dt>for <code>Policies</code>. Note that this test may inappropriately
|
||||
choose <code>return_internal_reference<></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>© Copyright <a href=
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
>>> v.get_name2()
|
||||
'pi'
|
||||
|
||||
>>> v.y.x
|
||||
6
|
||||
>>> v.y.x = -7
|
||||
>>> v.y.x
|
||||
-7
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
|
||||
18
todo.txt
18
todo.txt
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user