diff --git a/doc/news.html b/doc/news.html
index 0fca1204..6ae58360 100644
--- a/doc/news.html
+++ b/doc/news.html
@@ -29,6 +29,11 @@
+ - 14 November 2002
+
+ - Auto-detection of class data members wrapped with
make_getter
+
- 13 November 2002
- Full Support for
std::auto_ptr<> added.
diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html
index 1bf16cd4..0f015780 100644
--- a/doc/v2/data_members.html
+++ b/doc/v2/data_members.html
@@ -77,7 +77,15 @@ template <class C, class D, class Policies>
C*, and returns the corresponding member D
member of the C object, converted to_python.
If policies is supplied, it will be applied to the
- function as described here.
+ function as described here. Otherwise,
+ the library attempts to determine whether D is a
+ user-defined class type, and if so uses return_internal_reference<>
+
+ - for
Policies. Note that this test may inappropriately
+ choose return_internal_reference<> in some cases
+ when D is a smart pointer type. This is a known
+ defect.
- Returns: An instance of object which holds the new Python
@@ -147,8 +155,8 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)
- 13 November, 2002
-
+ 13 November, 2002
+
© Copyright
# include
# include
-# include
+# include
+# include
# include
# include
+# include
# include
# include
+# include
+# include
# include
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 c0(PyTuple_GET_ITEM(args_, 0));
+ arg_from_python c0(PyTuple_GET_ITEM(args_, 0));
if (!c0.convertible()) return 0;
typedef typename add_const::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
+ struct default_getter_policy
+ : mpl::if_c<
+ to_python_value<
+ typename add_reference<
+ typename add_const::type
+ >::type
+ >::uses_registry
+ , return_internal_reference<>
+ , return_value_policy
+ >
+ {};
}
template
object make_getter(D C::*pm)
{
- typedef return_value_policy default_policy;
+ typedef typename detail::default_getter_policy::type policy;
return objects::function_object(
::boost::bind(
- &detail::member::get, pm, _1, _2
- , default_policy())
+ &detail::member::get, pm, _1, _2
+ , policy())
, 1);
}
diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp
index 3b9cd76c..de5122a2 100644
--- a/include/boost/python/to_python_value.hpp
+++ b/include/boost/python/to_python_value.hpp
@@ -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);
};
}
diff --git a/test/data_members.cpp b/test/data_members.cpp
index 5a87eeae..e5affba4 100644
--- a/test/data_members.cpp
+++ b/test/data_members.cpp
@@ -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
diff --git a/test/data_members.py b/test/data_members.py
index c908f515..820b4f12 100644
--- a/test/data_members.py
+++ b/test/data_members.py
@@ -30,6 +30,11 @@
>>> v.get_name2()
'pi'
+>>> v.y.x
+6
+>>> v.y.x = -7
+>>> v.y.x
+-7
'''
def run(args = None):
diff --git a/todo.txt b/todo.txt
index 3bcd16ac..6ee55157 100644
--- a/todo.txt
+++ b/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)
-