1616# include < boost/python/converter/lvalue_from_python_chain.hpp>
1717# include < boost/python/converter/rvalue_from_python_chain.hpp>
1818# include < boost/python/detail/void_ptr.hpp>
19+ # include < boost/python/back_reference.hpp>
20+
21+ namespace boost { namespace python
22+ {
23+ template <class T > struct from_python ;
24+ }}
1925
2026namespace boost { namespace python { namespace converter {
2127
@@ -82,6 +88,21 @@ class rvalue_from_python
8288 rvalue_data<result_type> m_data;
8389};
8490
91+ // ------- back-reference converters --------
92+
93+ // Converts to a (PyObject*,T) bundle, for when you need a reference
94+ // back to the Python object
95+
96+ template <class T >
97+ struct back_reference_from_python
98+ : boost::python::from_python<typename T::type>
99+ {
100+ back_reference_from_python (PyObject*);
101+ T operator ()(PyObject*);
102+ private:
103+ typedef boost::python::from_python<typename T::type> base;
104+ };
105+
85106template <class T >
86107struct select_from_python
87108{
@@ -100,6 +121,10 @@ struct select_from_python
100121 boost::python::detail::is_reference_to_non_const<T>::value
101122 || boost::python::detail::is_reference_to_volatile<T>::value);
102123
124+ BOOST_STATIC_CONSTANT (
125+ bool , back_ref =
126+ boost::python::is_back_reference<T>::value);
127+
103128 typedef typename mpl::select_type<
104129 ptr
105130 , pointer_from_python<T>
@@ -109,7 +134,11 @@ struct select_from_python
109134 , typename mpl::select_type<
110135 ref
111136 , reference_from_python<T>
112- , rvalue_from_python<T>
137+ , typename mpl::select_type<
138+ back_ref
139+ , back_reference_from_python<T>
140+ , rvalue_from_python<T>
141+ >::type
113142 >::type
114143 >::type
115144 >::type type;
@@ -232,6 +261,19 @@ rvalue_from_python<T>::operator()(PyObject* p)
232261 return python::detail::void_ptr_to_reference (m_data.stage1 .convertible , (result_type (*)())0 );
233262}
234263
264+ template <class T >
265+ back_reference_from_python<T>::back_reference_from_python(PyObject* x)
266+ : base(x)
267+ {
268+ }
269+
270+ template <class T >
271+ inline T
272+ back_reference_from_python<T>::operator ()(PyObject* x)
273+ {
274+ return T (x, base::operator ()(x));
275+ }
276+
235277}}} // namespace boost::python::converter
236278
237279#endif // FROM_PYTHON_DWA2002127_HPP
0 commit comments