summaryrefslogtreecommitdiff
path: root/src/pyutils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/pyutils.h')
-rw-r--r--src/pyutils.h74
1 files changed, 65 insertions, 9 deletions
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<class T, class TfromPy>
-struct ObjFromPy {
- ObjFromPy() {
+template <typename T, typename TfromPy>
+struct object_from_python
+{
+ object_from_python() {
boost::python::converter::registry::push_back
- (&TfromPy::convertible,
- &TfromPy::construct,
- boost::python::type_id<T>());
+ (&TfromPy::convertible, &TfromPy::construct,
+ boost::python::type_id<T>());
}
};
-template<class T, class TtoPy, class TfromPy>
-struct register_python_conversion {
+template <typename T, typename TtoPy, typename TfromPy>
+struct register_python_conversion
+{
register_python_conversion() {
boost::python::to_python_converter<T, TtoPy>();
- ObjFromPy<T, TfromPy>();
+ object_from_python<T, TfromPy>();
}
};
+template <typename T>
+struct python_optional : public boost::noncopyable
+{
+ struct optional_to_python
+ {
+ static PyObject * convert(const boost::optional<T>& value)
+ {
+ return (value ? boost::python::to_python_value<T>()(*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<T>::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<T> *) data)->storage.bytes;
+
+ if (data->convertible == source) // == None
+ new (storage) boost::optional<T>(); // A Boost uninitialized value
+ else
+ new (storage) boost::optional<T>(*static_cast<T *>(data->convertible));
+
+ data->convertible = storage;
+ }
+ };
+
+ explicit python_optional() {
+ register_python_conversion<boost::optional<T>,
+ optional_to_python, optional_from_python>();
+ }
+};
+
+//boost::python::register_ptr_to_python< boost::shared_ptr<Base> >();
+
#endif // _PY_UTILS_H