python: Add wrapper for vectors to allow Python access to net.users
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
1731590160
commit
e48c9e73e7
@ -144,7 +144,7 @@ void CommandHandler::setupContext(Context *ctx)
|
|||||||
int r;
|
int r;
|
||||||
do {
|
do {
|
||||||
r = rand();
|
r = rand();
|
||||||
} while(r == 0);
|
} while (r == 0);
|
||||||
ctx->rngseed(r);
|
ctx->rngseed(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,19 @@ void translate_assertfail(const assertion_failure &e)
|
|||||||
PyErr_SetString(PyExc_AssertionError, e.what());
|
PyErr_SetString(PyExc_AssertionError, e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PythonConversion {
|
||||||
|
template <> struct string_converter<PortRef &>
|
||||||
|
{
|
||||||
|
inline PortRef from_str(Context *ctx, std::string name) { NPNR_ASSERT_FALSE("PortRef from_str not implemented"); }
|
||||||
|
|
||||||
|
inline std::string to_str(Context *ctx, const PortRef &pr)
|
||||||
|
{
|
||||||
|
return pr.cell->name.str(ctx) + "." + pr.port.str(ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace PythonConversion
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(MODULE_NAME)
|
BOOST_PYTHON_MODULE(MODULE_NAME)
|
||||||
{
|
{
|
||||||
register_exception_translator<assertion_failure>(&translate_assertfail);
|
register_exception_translator<assertion_failure>(&translate_assertfail);
|
||||||
@ -120,7 +133,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
|
|||||||
readwrite_wrapper<PortInfo &, decltype(&PortInfo::type), &PortInfo::type, pass_through<PortType>,
|
readwrite_wrapper<PortInfo &, decltype(&PortInfo::type), &PortInfo::type, pass_through<PortType>,
|
||||||
pass_through<PortType>>::def_wrap(pi_cls, "type");
|
pass_through<PortType>>::def_wrap(pi_cls, "type");
|
||||||
|
|
||||||
typedef std::vector<PortRef> PortVector;
|
typedef std::vector<PortRef> PortRefVector;
|
||||||
typedef std::unordered_map<WireId, PipMap> WireMap;
|
typedef std::unordered_map<WireId, PipMap> WireMap;
|
||||||
|
|
||||||
auto ni_cls = class_<ContextualWrapper<NetInfo &>>("NetInfo", no_init);
|
auto ni_cls = class_<ContextualWrapper<NetInfo &>>("NetInfo", no_init);
|
||||||
@ -128,7 +141,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
|
|||||||
conv_from_str<IdString>>::def_wrap(ni_cls, "name");
|
conv_from_str<IdString>>::def_wrap(ni_cls, "name");
|
||||||
readwrite_wrapper<NetInfo &, decltype(&NetInfo::driver), &NetInfo::driver, wrap_context<PortRef &>,
|
readwrite_wrapper<NetInfo &, decltype(&NetInfo::driver), &NetInfo::driver, wrap_context<PortRef &>,
|
||||||
unwrap_context<PortRef &>>::def_wrap(ni_cls, "driver");
|
unwrap_context<PortRef &>>::def_wrap(ni_cls, "driver");
|
||||||
readonly_wrapper<NetInfo &, decltype(&NetInfo::users), &NetInfo::users, wrap_context<PortVector &>>::def_wrap(
|
readonly_wrapper<NetInfo &, decltype(&NetInfo::users), &NetInfo::users, wrap_context<PortRefVector &>>::def_wrap(
|
||||||
ni_cls, "users");
|
ni_cls, "users");
|
||||||
readonly_wrapper<NetInfo &, decltype(&NetInfo::wires), &NetInfo::wires, wrap_context<WireMap &>>::def_wrap(ni_cls,
|
readonly_wrapper<NetInfo &, decltype(&NetInfo::wires), &NetInfo::wires, wrap_context<WireMap &>>::def_wrap(ni_cls,
|
||||||
"wires");
|
"wires");
|
||||||
@ -148,6 +161,8 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
|
|||||||
WRAP_MAP(PortMap, wrap_context<PortInfo &>, "PortMap");
|
WRAP_MAP(PortMap, wrap_context<PortInfo &>, "PortMap");
|
||||||
WRAP_MAP(PinMap, conv_to_str<IdString>, "PinMap");
|
WRAP_MAP(PinMap, conv_to_str<IdString>, "PinMap");
|
||||||
|
|
||||||
|
WRAP_VECTOR(PortRefVector, wrap_context<PortRef &>);
|
||||||
|
|
||||||
arch_wrap_python();
|
arch_wrap_python();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,10 +118,67 @@ struct range_wrapper
|
|||||||
#define WRAP_RANGE(t, conv) \
|
#define WRAP_RANGE(t, conv) \
|
||||||
range_wrapper<t##Range, return_value_policy<return_by_value>, conv>().wrap(#t "Range", #t "Iterator")
|
range_wrapper<t##Range, return_value_policy<return_by_value>, conv>().wrap(#t "Range", #t "Iterator")
|
||||||
|
|
||||||
|
/*
|
||||||
|
A wrapper for a vector or similar structure. With support for conversion
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename T, typename P = return_value_policy<return_by_value>,
|
||||||
|
typename value_conv = PythonConversion::pass_through<T>>
|
||||||
|
struct vector_wrapper
|
||||||
|
{
|
||||||
|
typedef decltype(std::declval<T>().begin()) iterator_t;
|
||||||
|
typedef decltype(*(std::declval<iterator_t>())) value_t;
|
||||||
|
typedef typename PythonConversion::ContextualWrapper<T &> wrapped_vector;
|
||||||
|
typedef typename PythonConversion::ContextualWrapper<std::pair<iterator_t, iterator_t>> 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<value_t> 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.size(); }
|
||||||
|
|
||||||
|
static return_t getitem(wrapped_vector &range, int i)
|
||||||
|
{
|
||||||
|
return value_conv()(range.ctx, boost::ref(range.base.at(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wrap(const char *range_name, const char *iter_name)
|
||||||
|
{
|
||||||
|
class_<wrapped_vector>(range_name, no_init)
|
||||||
|
.def("__iter__", iter)
|
||||||
|
.def("__repr__", repr)
|
||||||
|
.def("__len__", len)
|
||||||
|
.def("__getitem__", getitem);
|
||||||
|
|
||||||
|
iterator_wrapper<iterator_t, P, value_conv>().wrap(iter_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef iterator_wrapper<iterator_t, P, value_conv> iter_wrap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define WRAP_VECTOR(t, conv) vector_wrapper<t, return_value_policy<return_by_value>, conv>().wrap(#t, #t "Iterator")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Wrapper for a pair, allows accessing either using C++-style members (.first and
|
Wrapper for a pair, allows accessing either using C++-style members (.first and
|
||||||
.second) or as a Python iterable and indexable object
|
.second) or as a Python iterable and indexable object
|
||||||
*/
|
*/
|
||||||
template <typename T1, typename T2> struct pair_wrapper
|
template <typename T1, typename T2> struct pair_wrapper
|
||||||
{
|
{
|
||||||
typedef std::pair<T1, T2> T;
|
typedef std::pair<T1, T2> T;
|
||||||
|
Loading…
Reference in New Issue
Block a user