From 8f2b707d026597018333ac60e707e5ab78c25a91 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 23 Jul 2020 18:35:18 +0200 Subject: Initial conversion to pybind11 --- common/pycontainers.h | 170 +++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 91 deletions(-) (limited to 'common/pycontainers.h') diff --git a/common/pycontainers.h b/common/pycontainers.h index 2b9ee208..15e502d1 100644 --- a/common/pycontainers.h +++ b/common/pycontainers.h @@ -21,9 +21,7 @@ #ifndef COMMON_PYCONTAINERS_H #define COMMON_PYCONTAINERS_H -#include -#include -#include +#include #include #include #include @@ -33,12 +31,12 @@ NEXTPNR_NAMESPACE_BEGIN -using namespace boost::python; +namespace py = pybind11; inline void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); - boost::python::throw_error_already_set(); + throw py::error_already_set(); } /* @@ -47,7 +45,7 @@ pair containing (current, end), wrapped in a ContextualWrapp */ -template > struct iterator_wrapper +template > struct iterator_wrapper { typedef decltype(*(std::declval())) value_t; @@ -62,16 +60,13 @@ template (python_name, no_init).def("__next__", next, P()); + py::class_(m, python_name).def("__next__", next, P); } }; @@ -81,7 +76,7 @@ and end() which return iterator-like objects supporting ++, * and != Full STL iterator semantics are not required, unlike the standard Boost wrappers */ -template , +template > struct range_wrapper { @@ -110,23 +105,23 @@ struct range_wrapper return ss.str(); } - static void wrap(const char *range_name, const char *iter_name) + static void wrap(py::module &m, const char *range_name, const char *iter_name) { - class_(range_name, no_init).def("__iter__", iter).def("__repr__", repr); - iterator_wrapper().wrap(iter_name); + py::class_(m, range_name).def("__iter__", iter).def("__repr__", repr); + iterator_wrapper().wrap(m, iter_name); } typedef iterator_wrapper iter_wrap; }; -#define WRAP_RANGE(t, conv) \ - range_wrapper, conv>().wrap(#t "Range", #t "Iterator") +#define WRAP_RANGE(m, t, conv) \ + range_wrapper().wrap(m, #t "Range", #t "Iterator") /* A wrapper for a vector or similar structure. With support for conversion */ -template , +template > struct vector_wrapper { @@ -163,21 +158,21 @@ struct vector_wrapper return value_conv()(range.ctx, boost::ref(range.base.at(i))); } - static void wrap(const char *range_name, const char *iter_name) + static void wrap(py::module &m, const char *range_name, const char *iter_name) { - class_(range_name, no_init) + py::class_(m, range_name) .def("__iter__", iter) .def("__repr__", repr) .def("__len__", len) .def("__getitem__", getitem); - iterator_wrapper().wrap(iter_name); + iterator_wrapper().wrap(m, iter_name); } typedef iterator_wrapper iter_wrap; }; -#define WRAP_VECTOR(t, conv) vector_wrapper, conv>().wrap(#t, #t "Iterator") +#define WRAP_VECTOR(m, t, conv) vector_wrapper().wrap(m, #t, #t "Iterator") /* Wrapper for a pair, allows accessing either using C++-style members (.first and @@ -189,58 +184,55 @@ template struct pair_wrapper struct pair_iterator_wrapper { - static object next(std::pair &iter) + static py::object next(std::pair &iter) { if (iter.second == 0) { iter.second++; - return object(iter.first.first); + return py::cast(iter.first.first); } else if (iter.second == 1) { iter.second++; - return object(iter.first.second); + return py::cast(iter.first.second); } else { PyErr_SetString(PyExc_StopIteration, "End of range reached"); - boost::python::throw_error_already_set(); - // Should be unreachable, but prevent control may reach end of - // non-void - throw std::runtime_error("unreachable"); + throw py::error_already_set(); } } - static void wrap(const char *python_name) + static void wrap(py::module &m, const char *python_name) { - class_>(python_name, no_init).def("__next__", next); + py::class_>(m, python_name).def("__next__", next); } }; - static object get(T &x, int i) + static py::object get(T &x, int i) { if ((i >= 2) || (i < 0)) KeyError(); - return (i == 1) ? object(x.second) : object(x.first); + return (i == 1) ? py::object(x.second) : py::object(x.first); } - static void set(T &x, int i, object val) + static void set(T &x, int i, py::object val) { if ((i >= 2) || (i < 0)) KeyError(); if (i == 0) - x.first = extract(val); + x.first = val.cast(); if (i == 1) - x.second = extract(val); + x.second = val.cast(); } static int len(T &x) { return 2; } static std::pair iter(T &x) { return std::make_pair(boost::ref(x), 0); }; - static void wrap(const char *pair_name, const char *iter_name) + static void wrap(py::module &m, const char *pair_name, const char *iter_name) { - pair_iterator_wrapper::wrap(iter_name); - class_(pair_name, no_init) + pair_iterator_wrapper::wrap(m, iter_name); + py::class_(m, pair_name) .def("__iter__", iter) .def("__len__", len) .def("__getitem__", get) - .def("__setitem__", set, with_custodian_and_ward<1, 2>()) + .def("__setitem__", set, py::keep_alive<1, 2>()) .def_readwrite("first", &T::first) .def_readwrite("second", &T::second); } @@ -257,36 +249,34 @@ template struct map_pair_wrapper struct pair_iterator_wrapper { - static object next(std::pair &iter) + static py::object next(std::pair &iter) { if (iter.second == 0) { iter.second++; - return object(PythonConversion::string_converter().to_str( + return py::cast(PythonConversion::string_converter().to_str( iter.first.ctx, iter.first.base.first)); } else if (iter.second == 1) { iter.second++; - return object(value_conv()(iter.first.ctx, iter.first.base.second)); + return py::cast(value_conv()(iter.first.ctx, iter.first.base.second)); } else { PyErr_SetString(PyExc_StopIteration, "End of range reached"); - boost::python::throw_error_already_set(); - // Should be unreachable, but prevent control may reach end of - // non-void - throw std::runtime_error("unreachable"); + throw py::error_already_set(); } } - static void wrap(const char *python_name) + static void wrap(py::module &m, const char *python_name) { - class_>(python_name, no_init).def("__next__", next); + //FIXME + //py::class_>(m, python_name).def("__next__", next); } }; - static object get(wrapped_pair &x, int i) + static py::object get(wrapped_pair &x, int i) { if ((i >= 2) || (i < 0)) KeyError(); - return (i == 1) ? object(value_conv()(x.ctx, x.base.second)) - : object(PythonConversion::string_converter().to_str(x.ctx, + return (i == 1) ? py::cast(value_conv()(x.ctx, x.base.second)) + : py::cast(PythonConversion::string_converter().to_str(x.ctx, x.base.first)); } @@ -301,15 +291,15 @@ template struct map_pair_wrapper static typename value_conv::ret_type second_getter(wrapped_pair &t) { return value_conv()(t.ctx, t.base.second); } - static void wrap(const char *pair_name, const char *iter_name) + static void wrap(py::module &m, const char *pair_name, const char *iter_name) { - pair_iterator_wrapper::wrap(iter_name); - class_(pair_name, no_init) + pair_iterator_wrapper::wrap(m, iter_name); + py::class_(m, pair_name) .def("__iter__", iter) .def("__len__", len) .def("__getitem__", get) - .add_property("first", first_getter) - .add_property("second", second_getter); + .def_property_readonly("first", first_getter) + .def_property_readonly("second", second_getter); } }; @@ -358,17 +348,17 @@ template struct map_wrapper return x.base.count(k); } - static void wrap(const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name) + static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name) { - map_pair_wrapper::wrap(kv_name, kv_iter_name); - typedef range_wrapper, PythonConversion::wrap_context> rw; - typename rw::iter_wrap().wrap(iter_name); - class_(map_name, no_init) + map_pair_wrapper::wrap(m, kv_name, kv_iter_name); + typedef range_wrapper> rw; + typename rw::iter_wrap().wrap(m, iter_name); + py::class_(m, map_name) .def("__iter__", rw::iter) .def("__len__", len) .def("__contains__", contains) .def("__getitem__", get) - .def("__setitem__", set, with_custodian_and_ward<1, 2>()); + .def("__setitem__", set, py::keep_alive<1, 2>()); } }; @@ -383,36 +373,34 @@ template struct map_pair_wrapper_uptr struct pair_iterator_wrapper { - static object next(std::pair &iter) + static py::object next(std::pair &iter) { if (iter.second == 0) { iter.second++; - return object(PythonConversion::string_converter().to_str( + return py::cast(PythonConversion::string_converter().to_str( iter.first.ctx, iter.first.base.first)); } else if (iter.second == 1) { iter.second++; - return object(PythonConversion::ContextualWrapper(iter.first.ctx, *iter.first.base.second.get())); + return py::cast(PythonConversion::ContextualWrapper(iter.first.ctx, *iter.first.base.second.get())); } else { PyErr_SetString(PyExc_StopIteration, "End of range reached"); - boost::python::throw_error_already_set(); - // Should be unreachable, but prevent control may reach end of - // non-void - throw std::runtime_error("unreachable"); + throw py::error_already_set(); } } - static void wrap(const char *python_name) + static void wrap(py::module &m, const char *python_name) { - class_>(python_name, no_init).def("__next__", next); + //FIXME + //py::class_>(m, python_name).def("__next__", next); } }; - static object get(wrapped_pair &x, int i) + static py::object get(wrapped_pair &x, int i) { if ((i >= 2) || (i < 0)) KeyError(); - return (i == 1) ? object(PythonConversion::ContextualWrapper(x.ctx, *x.base.second.get())) - : object(PythonConversion::string_converter().to_str(x.ctx, + return (i == 1) ? py::cast(PythonConversion::ContextualWrapper(x.ctx, *x.base.second.get())) + : py::cast(PythonConversion::string_converter().to_str(x.ctx, x.base.first)); } @@ -430,15 +418,15 @@ template struct map_pair_wrapper_uptr return PythonConversion::ContextualWrapper(t.ctx, *t.base.second.get()); } - static void wrap(const char *pair_name, const char *iter_name) + static void wrap(py::module &m, const char *pair_name, const char *iter_name) { - pair_iterator_wrapper::wrap(iter_name); - class_(pair_name, no_init) + pair_iterator_wrapper::wrap(m, iter_name); + py::class_(m, pair_name) .def("__iter__", iter) .def("__len__", len) .def("__getitem__", get) - .add_property("first", first_getter) - .add_property("second", second_getter); + .def_property_readonly("first", first_getter) + .def_property_readonly("second", second_getter); } }; @@ -487,24 +475,24 @@ template struct map_wrapper_uptr return x.base.count(k); } - static void wrap(const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name) + static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name) { - map_pair_wrapper_uptr::wrap(kv_name, kv_iter_name); - typedef range_wrapper, PythonConversion::wrap_context> rw; - typename rw::iter_wrap().wrap(iter_name); - class_(map_name, no_init) + map_pair_wrapper_uptr::wrap(m, kv_name, kv_iter_name); + typedef range_wrapper> rw; + typename rw::iter_wrap().wrap(m, iter_name); + py::class_(m, map_name) .def("__iter__", rw::iter) .def("__len__", len) .def("__contains__", contains) .def("__getitem__", get) - .def("__setitem__", set, with_custodian_and_ward<1, 2>()); + .def("__setitem__", set, py::keep_alive<1, 2>()); } }; -#define WRAP_MAP(t, conv, name) \ - map_wrapper().wrap(#name, #name "KeyValue", #name "KeyValueIter", #name "Iterator") -#define WRAP_MAP_UPTR(t, name) \ - map_wrapper_uptr().wrap(#name, #name "KeyValue", #name "KeyValueIter", #name "Iterator") +#define WRAP_MAP(m, t, conv, name) \ + map_wrapper().wrap(m, #name, #name "KeyValue", #name "KeyValueIter", #name "Iterator") +#define WRAP_MAP_UPTR(m, t, name) \ + map_wrapper_uptr().wrap(m, #name, #name "KeyValue", #name "KeyValueIter", #name "Iterator") NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From cca7d3aef7e97228bddc04601e5c6f1d03894be9 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 23 Jul 2020 19:55:25 +0200 Subject: possible fix --- common/pycontainers.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'common/pycontainers.h') diff --git a/common/pycontainers.h b/common/pycontainers.h index 15e502d1..0a5092a3 100644 --- a/common/pycontainers.h +++ b/common/pycontainers.h @@ -249,7 +249,7 @@ template struct map_pair_wrapper struct pair_iterator_wrapper { - static py::object next(std::pair &iter) + static py::object next(std::pair &&iter) { if (iter.second == 0) { iter.second++; @@ -266,8 +266,7 @@ template struct map_pair_wrapper static void wrap(py::module &m, const char *python_name) { - //FIXME - //py::class_>(m, python_name).def("__next__", next); + py::class_>(m, python_name).def("__next__", next); } }; @@ -373,7 +372,7 @@ template struct map_pair_wrapper_uptr struct pair_iterator_wrapper { - static py::object next(std::pair &iter) + static py::object next(std::pair &&iter) { if (iter.second == 0) { iter.second++; @@ -390,8 +389,7 @@ template struct map_pair_wrapper_uptr static void wrap(py::module &m, const char *python_name) { - //FIXME - //py::class_>(m, python_name).def("__next__", next); + py::class_>(m, python_name).def("__next__", next); } }; -- cgit v1.2.3 From bb6e6a15f1f1a061f4b59c3eddd3430d57681c6d Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 24 Jul 2020 16:27:47 +0100 Subject: pycontainers: Fix kv-pair-iter type Signed-off-by: David Shah --- common/pycontainers.h | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'common/pycontainers.h') diff --git a/common/pycontainers.h b/common/pycontainers.h index 0a5092a3..d0d7d92a 100644 --- a/common/pycontainers.h +++ b/common/pycontainers.h @@ -70,6 +70,16 @@ template struct iter_pair { + iter_pair() {}; + iter_pair(const Ta &first, const Tb &second) : first(first), second(second) {}; + Ta first; + Tb second; +}; + /* A wrapper for a nextpnr Range. Ranges should have two functions, begin() and end() which return iterator-like objects supporting ++, * and != @@ -184,7 +194,7 @@ template struct pair_wrapper struct pair_iterator_wrapper { - static py::object next(std::pair &iter) + static py::object next(iter_pair &iter) { if (iter.second == 0) { iter.second++; @@ -200,7 +210,7 @@ template struct pair_wrapper static void wrap(py::module &m, const char *python_name) { - py::class_>(m, python_name).def("__next__", next); + py::class_>(m, python_name).def("__next__", next); } }; @@ -223,7 +233,7 @@ template struct pair_wrapper static int len(T &x) { return 2; } - static std::pair iter(T &x) { return std::make_pair(boost::ref(x), 0); }; + static iter_pair iter(T &x) { return iter_pair(boost::ref(x), 0); }; static void wrap(py::module &m, const char *pair_name, const char *iter_name) { @@ -249,7 +259,7 @@ template struct map_pair_wrapper struct pair_iterator_wrapper { - static py::object next(std::pair &&iter) + static py::object next(iter_pair &iter) { if (iter.second == 0) { iter.second++; @@ -266,7 +276,7 @@ template struct map_pair_wrapper static void wrap(py::module &m, const char *python_name) { - py::class_>(m, python_name).def("__next__", next); + py::class_>(m, python_name).def("__next__", next); } }; @@ -281,7 +291,7 @@ template struct map_pair_wrapper static int len(wrapped_pair &x) { return 2; } - static std::pair iter(wrapped_pair &x) { return std::make_pair(boost::ref(x), 0); }; + static iter_pair iter(wrapped_pair &x) { return iter_pair(boost::ref(x), 0); }; static std::string first_getter(wrapped_pair &t) { @@ -372,7 +382,7 @@ template struct map_pair_wrapper_uptr struct pair_iterator_wrapper { - static py::object next(std::pair &&iter) + static py::object next(iter_pair &iter) { if (iter.second == 0) { iter.second++; @@ -389,7 +399,7 @@ template struct map_pair_wrapper_uptr static void wrap(py::module &m, const char *python_name) { - py::class_>(m, python_name).def("__next__", next); + py::class_>(m, python_name).def("__next__", next); } }; @@ -404,7 +414,7 @@ template struct map_pair_wrapper_uptr static int len(wrapped_pair &x) { return 2; } - static std::pair iter(wrapped_pair &x) { return std::make_pair(boost::ref(x), 0); }; + static iter_pair iter(wrapped_pair &x) { return iter_pair(boost::ref(x), 0); }; static std::string first_getter(wrapped_pair &t) { -- cgit v1.2.3 From fe398ab983aee9283f61c288dc98d94542c30332 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 25 Jul 2020 10:17:13 +0200 Subject: clangformat --- common/pycontainers.h | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'common/pycontainers.h') diff --git a/common/pycontainers.h b/common/pycontainers.h index d0d7d92a..dfcf8ab8 100644 --- a/common/pycontainers.h +++ b/common/pycontainers.h @@ -45,7 +45,8 @@ pair containing (current, end), wrapped in a ContextualWrapp */ -template > struct iterator_wrapper +template > +struct iterator_wrapper { typedef decltype(*(std::declval())) value_t; @@ -73,9 +74,10 @@ template struct iter_pair { - iter_pair() {}; - iter_pair(const Ta &first, const Tb &second) : first(first), second(second) {}; +template struct iter_pair +{ + iter_pair(){}; + iter_pair(const Ta &first, const Tb &second) : first(first), second(second){}; Ta first; Tb second; }; @@ -117,14 +119,14 @@ struct range_wrapper static void wrap(py::module &m, const char *range_name, const char *iter_name) { - py::class_(m, range_name).def("__iter__", iter).def("__repr__", repr); + py::class_(m, range_name).def("__iter__", iter).def("__repr__", repr); iterator_wrapper().wrap(m, iter_name); } typedef iterator_wrapper iter_wrap; }; -#define WRAP_RANGE(m, t, conv) \ +#define WRAP_RANGE(m, t, conv) \ range_wrapper().wrap(m, #t "Range", #t "Iterator") /* @@ -286,12 +288,15 @@ template struct map_pair_wrapper KeyError(); return (i == 1) ? py::cast(value_conv()(x.ctx, x.base.second)) : py::cast(PythonConversion::string_converter().to_str(x.ctx, - x.base.first)); + x.base.first)); } static int len(wrapped_pair &x) { return 2; } - static iter_pair iter(wrapped_pair &x) { return iter_pair(boost::ref(x), 0); }; + static iter_pair iter(wrapped_pair &x) + { + return iter_pair(boost::ref(x), 0); + }; static std::string first_getter(wrapped_pair &t) { @@ -357,7 +362,8 @@ template struct map_wrapper return x.base.count(k); } - static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name) + static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, + const char *iter_name) { map_pair_wrapper::wrap(m, kv_name, kv_iter_name); typedef range_wrapper> rw; @@ -390,7 +396,8 @@ template struct map_pair_wrapper_uptr iter.first.ctx, iter.first.base.first)); } else if (iter.second == 1) { iter.second++; - return py::cast(PythonConversion::ContextualWrapper(iter.first.ctx, *iter.first.base.second.get())); + return py::cast( + PythonConversion::ContextualWrapper(iter.first.ctx, *iter.first.base.second.get())); } else { PyErr_SetString(PyExc_StopIteration, "End of range reached"); throw py::error_already_set(); @@ -409,12 +416,15 @@ template struct map_pair_wrapper_uptr KeyError(); return (i == 1) ? py::cast(PythonConversion::ContextualWrapper(x.ctx, *x.base.second.get())) : py::cast(PythonConversion::string_converter().to_str(x.ctx, - x.base.first)); + x.base.first)); } static int len(wrapped_pair &x) { return 2; } - static iter_pair iter(wrapped_pair &x) { return iter_pair(boost::ref(x), 0); }; + static iter_pair iter(wrapped_pair &x) + { + return iter_pair(boost::ref(x), 0); + }; static std::string first_getter(wrapped_pair &t) { @@ -483,7 +493,8 @@ template struct map_wrapper_uptr return x.base.count(k); } - static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name) + static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, + const char *iter_name) { map_pair_wrapper_uptr::wrap(m, kv_name, kv_iter_name); typedef range_wrapper> rw; @@ -497,9 +508,9 @@ template struct map_wrapper_uptr } }; -#define WRAP_MAP(m, t, conv, name) \ +#define WRAP_MAP(m, t, conv, name) \ map_wrapper().wrap(m, #name, #name "KeyValue", #name "KeyValueIter", #name "Iterator") -#define WRAP_MAP_UPTR(m, t, name) \ +#define WRAP_MAP_UPTR(m, t, name) \ map_wrapper_uptr().wrap(m, #name, #name "KeyValue", #name "KeyValueIter", #name "Iterator") NEXTPNR_NAMESPACE_END -- cgit v1.2.3