From 0528a1e49a82221e63039abc7f759a43f4d4ffc9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 4 May 2007 13:41:23 +0000 Subject: Added boost::optional support for using with Boost.Python. --- src/pyutils.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 9 deletions(-) (limited to 'src/pyutils.h') diff --git a/src/pyutils.h b/src/pyutils.h index 4ff33f8f..84a0db7e 100644 --- a/src/pyutils.h +++ b/src/pyutils.h @@ -1,22 +1,78 @@ #ifndef _PY_UTILS_H #define _PY_UTILS_H -template -struct ObjFromPy { - ObjFromPy() { +template +struct object_from_python +{ + object_from_python() { boost::python::converter::registry::push_back - (&TfromPy::convertible, - &TfromPy::construct, - boost::python::type_id()); + (&TfromPy::convertible, &TfromPy::construct, + boost::python::type_id()); } }; -template -struct register_python_conversion { +template +struct register_python_conversion +{ register_python_conversion() { boost::python::to_python_converter(); - ObjFromPy(); + object_from_python(); } }; +template +struct python_optional : public boost::noncopyable +{ + struct optional_to_python + { + static PyObject * convert(const boost::optional& value) + { + return (value ? boost::python::to_python_value()(*value) : + boost::python::detail::none()); + } + }; + + struct optional_from_python + { + static void * convertible(PyObject * source) + { + using namespace boost::python::converter; + + if (source == Py_None) + return source; + + const registration& converters(registered::converters); + + if (implicit_rvalue_convertible_from_python(source, converters)) { + rvalue_from_python_stage1_data data = + rvalue_from_python_stage1(source, converters); + return rvalue_from_python_stage2(source, data, converters); + } + return NULL; + } + + static void construct(PyObject * source, + boost::python::converter::rvalue_from_python_stage1_data * data) + { + using namespace boost::python::converter; + + void * const storage = ((rvalue_from_python_storage *) data)->storage.bytes; + + if (data->convertible == source) // == None + new (storage) boost::optional(); // A Boost uninitialized value + else + new (storage) boost::optional(*static_cast(data->convertible)); + + data->convertible = storage; + } + }; + + explicit python_optional() { + register_python_conversion, + optional_to_python, optional_from_python>(); + } +}; + +//boost::python::register_ptr_to_python< boost::shared_ptr >(); + #endif // _PY_UTILS_H -- cgit v1.2.3