python: Add support for vector<vector<primitive>> input

This commit is contained in:
Mizux Seiha
2021-02-19 15:34:10 +01:00
parent ccf8efc4c9
commit d1b86cb16f
2 changed files with 54 additions and 71 deletions

View File

@@ -53,54 +53,6 @@ DEFINE_INDEX_TYPE_TYPEDEF(
operations_research::RoutingVehicleClassIndex,
operations_research::RoutingModel::VehicleClassIndex);
%ignore operations_research::RoutingModel::RegisterUnaryTransitVector(
std::vector<int64> values);
%ignore operations_research::RoutingModel::AddVectorDimension(
std::vector<int64> values,
int64 capacity,
bool fix_start_cumul_to_zero,
const std::string& name);
%ignore operations_research::RoutingModel::RegisterTransitMatrix(
std::vector<std::vector<int64> > values);
%ignore operations_research::RoutingModel::AddMatrixDimension(
std::vector<std::vector<int64> > values,
int64 capacity,
bool fix_start_cumul_to_zero,
const std::string& name);
%extend operations_research::RoutingModel {
int RegisterUnaryTransitVector(
const std::vector<int64>& values) {
return $self->RegisterUnaryTransitVector(values);
}
std::pair<int, bool> AddVectorDimension(
const std::vector<int64>& values,
int64 capacity,
bool fix_start_cumul_to_zero,
const std::string& name) {
return $self->AddVectorDimension(values, capacity, fix_start_cumul_to_zero, name);
}
int RegisterTransitMatrix(
const std::vector<std::vector<int64> >& values) {
return $self->RegisterTransitMatrix(values);
}
std::pair<int, bool> AddMatrixDimension(
const std::vector<std::vector<int64> >& values,
int64 capacity,
bool fix_start_cumul_to_zero,
const std::string& name) {
return $self->AddMatrixDimension(values, capacity, fix_start_cumul_to_zero, name);
}
}
%ignore operations_research::RoutingModel::RegisterStateDependentTransitCallback;
%ignore operations_research::RoutingModel::StateDependentTransitCallback;
%ignore operations_research::RoutingModel::MakeStateDependentTransit;

View File

@@ -92,6 +92,38 @@ PY_LIST_OUTPUT_TYPEMAP(double, PyFloat_Check, PyFloat_FromDouble);
// TODO(user): see if we can also get rid of this and utilize already
// existing code.
%define PY_LIST_LIST_INPUT_TYPEMAP(type, checker)
%typecheck(SWIG_TYPECHECK_POINTER) const std::vector<std::vector<type> >&,
std::vector<std::vector<type> > {
if (!PyList_Check($input)) {
$1 = 0;
} else {
const int size = PyList_Size($input);
bool failed = false;
for (size_t i = 0; i < size; ++i) {
PyObject* const tuple = PyList_GetItem($input, i);
if (!PyTuple_Check(tuple) && !PyList_Check(tuple)) {
$1 = 0;
break;
} else {
const bool is_tuple = PyTuple_Check(tuple);
const int arity = is_tuple ? PyTuple_Size(tuple) : PyList_Size(tuple);
for (size_t j = 0; j < arity; ++j) {
PyObject* const entry =
is_tuple ? PyTuple_GetItem(tuple, j) : PyList_GetItem(tuple, j);
if (!checker(entry)) {
failed = true;
break;
}
}
}
if (failed) {
break;
}
}
$1 = failed ? 0 : 1;
}
}
%typemap(in) const std::vector<std::vector<type> >&
(std::vector<std::vector<type> > temp) {
if (!PyList_Check($input)) {
@@ -124,34 +156,33 @@ PY_LIST_OUTPUT_TYPEMAP(double, PyFloat_Check, PyFloat_FromDouble);
$1 = &temp;
}
%typecheck(SWIG_TYPECHECK_POINTER) const std::vector<std::vector<type> >& {
%typemap(in) std::vector<std::vector<type> > {
if (!PyList_Check($input)) {
$1 = 0;
} else {
const int size = PyList_Size($input);
bool failed = false;
for (size_t i = 0; i < size; ++i) {
PyObject* const tuple = PyList_GetItem($input, i);
PyErr_SetString(PyExc_TypeError, "Expecting a list of tuples");
SWIG_fail;
}
int len = PyList_Size($input);
int arity = -1;
if (len > 0) {
$1.resize(len);
for (size_t i = 0; i < len; ++i) {
PyObject *tuple = PyList_GetItem($input, i);
if (!PyTuple_Check(tuple) && !PyList_Check(tuple)) {
$1 = 0;
break;
} else {
const bool is_tuple = PyTuple_Check(tuple);
const int arity = is_tuple ? PyTuple_Size(tuple) : PyList_Size(tuple);
for (size_t j = 0; j < arity; ++j) {
PyObject* const entry =
is_tuple ? PyTuple_GetItem(tuple, j) : PyList_GetItem(tuple, j);
if (!checker(entry)) {
failed = true;
break;
}
PyErr_SetString(PyExc_TypeError, "Expecting a sequence");
SWIG_fail;
}
bool is_tuple = PyTuple_Check(tuple);
int arity = is_tuple ? PyTuple_Size(tuple) : PyList_Size(tuple);
$1[i].resize(arity);
for (size_t j = 0; j < arity; ++j) {
bool success = PyObjAs<type>(is_tuple ?
PyTuple_GetItem(tuple, j) :
PyList_GetItem(tuple, j), &$1[i][j]);
if (!success) {
SWIG_fail;
}
}
if (failed) {
break;
}
}
$1 = failed ? 0 : 1;
}
}