aboutsummaryrefslogtreecommitdiffstats
path: root/common/pybindings.h
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-07 09:47:00 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-07 09:47:00 +0200
commit3769b2058019ce7c6be824085e1047e1beec07dc (patch)
tree466d3c0e213b736086a840dde3c6c85214e2f871 /common/pybindings.h
parent0f6ebd638402ca1ac2a202621e9db63c2cb5eb5f (diff)
downloadnextpnr-3769b2058019ce7c6be824085e1047e1beec07dc.tar.gz
nextpnr-3769b2058019ce7c6be824085e1047e1beec07dc.tar.bz2
nextpnr-3769b2058019ce7c6be824085e1047e1beec07dc.zip
Adding Python to/from string wrappers for internal IDs
Diffstat (limited to 'common/pybindings.h')
-rw-r--r--common/pybindings.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/common/pybindings.h b/common/pybindings.h
index 84280908..5b2adc6a 100644
--- a/common/pybindings.h
+++ b/common/pybindings.h
@@ -76,6 +76,54 @@ struct range_wrapper {
}
};
+/*
+A wrapper to enable custom type/ID to/from string conversions
+ */
+template <typename T> struct string_wrapper {
+ template<typename F>
+ struct from_pystring_converter {
+ from_pystring_converter() {
+ converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id<T>());
+ };
+
+ static void* convertible(PyObject* object) {
+ return PyUnicode_Check(object) ? object : 0;
+ }
+
+ static void construct(
+ PyObject* object,
+ converter::rvalue_from_python_stage1_data* data) {
+ const wchar_t* value = PyUnicode_AsUnicode(object);
+ const std::wstring value_ws(value);
+ if (value == 0) throw_error_already_set();
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage<T>*)
+ data)->storage.bytes;
+ new (storage) T(fn(std::string(value_ws.begin(), value_ws.end())));
+ data->convertible = storage;
+ }
+
+ static F fn;
+ };
+
+ template<typename F> struct to_str_wrapper {
+ static F fn;
+ std::string str(T& x) {
+ return fn(x);
+ }
+ };
+
+ template<typename F1, typename F2> static void wrap(const char *type_name, F1 to_str_fn, F2 from_str_fn) {
+ from_pystring_converter<F2>::fn = from_str_fn;
+ from_pystring_converter<F2>();
+ to_str_wrapper<F1>::fn = to_str_fn;
+ class_<T>(type_name, no_init).def("__str__", to_str_wrapper<F1>::str);
+ };
+};
+
#define WRAP_RANGE(t) range_wrapper<t##Range>().wrap(#t "Range", #t "Iterator")
void init_python(const char *executable);