From 86699b42f619960bfefd4d0b479dd44a90527ea4 Mon Sep 17 00:00:00 2001 From: gatecat Date: Sat, 26 Feb 2022 15:17:46 +0000 Subject: Switch to potentially-sparse net users array This uses a new data structure for net.users that allows gaps, so removing a port from a net is no longer an O(n) operation on the number of users the net has. Signed-off-by: gatecat --- common/pycontainers.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'common/pycontainers.h') diff --git a/common/pycontainers.h b/common/pycontainers.h index a93230ab..ff49c34c 100644 --- a/common/pycontainers.h +++ b/common/pycontainers.h @@ -186,6 +186,63 @@ struct vector_wrapper #define WRAP_VECTOR(m, t, conv) vector_wrapper().wrap(m, #t, #t "Iterator") +template > +struct indexed_store_wrapper +{ + typedef decltype(std::declval().begin()) iterator_t; + typedef decltype(*(std::declval())) value_t; + typedef typename PythonConversion::ContextualWrapper wrapped_vector; + typedef typename PythonConversion::ContextualWrapper> wrapped_pair; + using return_t = typename value_conv::ret_type; + static wrapped_pair iter(wrapped_vector &range) + { + return wrapped_pair(range.ctx, std::make_pair(range.base.begin(), range.base.end())); + } + + static std::string repr(wrapped_vector &range) + { + PythonConversion::string_converter conv; + bool first = true; + std::stringstream ss; + ss << "["; + for (const auto &item : range.base) { + if (!first) + ss << ", "; + ss << "'" << conv.to_str(range.ctx, item) << "'"; + first = false; + } + ss << "]"; + return ss.str(); + } + + static int len(wrapped_vector &range) { return range.base.capacity(); } + + static py::object getitem(wrapped_vector &range, int i) + { + store_index> idx(i); + if (!range.base.count(idx)) + throw py::none(); + return py::cast(value_conv()(range.ctx, boost::ref(range.base.at(idx)))); + } + + 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) + .def("__len__", len) + .def("__getitem__", getitem); + + iterator_wrapper().wrap(m, iter_name); + } + + typedef iterator_wrapper iter_wrap; +}; + +#define WRAP_INDEXSTORE(m, t, conv) \ + indexed_store_wrapper().wrap(m, #t, #t "Iterator") + /* Wrapper for a pair, allows accessing either using C++-style members (.first and .second) or as a Python iterable and indexable object -- cgit v1.2.3