Commit 14a6f50e authored by Gemma Guest's avatar Gemma Guest
Browse files

Add support for property lists

Uses recursive variant so supports lists of lists etc.
parent ee55dd6e
......@@ -10,27 +10,33 @@
#include <vector>
#include <boost/python/extract.hpp>
#include <boost/python/list.hpp>
#include <boost/python/object.hpp>
#include <boost/variant.hpp>
#include <exception>
namespace Mantid::PythonInterface {
struct PyNativeTypeExtractor {
using PythonOutputT = std::variant<bool, int, double, std::string>;
using PythonOutputT =
boost::make_recursive_variant<bool, int, double, std::string, std::vector<boost::recursive_variant_>>::type;
static PythonOutputT convert(const boost::python::object &obj) {
using namespace boost::python;
const PyObject *rawptr = obj.ptr();
PyObject *rawptr = obj.ptr();
PythonOutputT out;
// This currently doesn't handle lists, but this could be retrofitted in future work
if (PyBool_Check(rawptr) == 1) {
if (PyList_Check(rawptr)) {
out = handleList(obj);
} else if (PyBool_Check(rawptr)) {
bool val = extract<bool>(obj);
out = val;
} else if (PyFloat_Check(rawptr) == 1) {
} else if (PyFloat_Check(rawptr)) {
double val = extract<double>(obj);
out = val;
} else if (PyLong_Check(rawptr) == 1) {
} else if (PyLong_Check(rawptr)) {
int val = extract<int>(obj);
out = val;
} else if (PyUnicode_Check(rawptr)) {
......@@ -41,6 +47,18 @@ struct PyNativeTypeExtractor {
}
return out;
}
private:
static PythonOutputT handleList(const boost::python::object &obj) {
auto rawptr = obj.ptr();
auto n = PyList_Size(rawptr);
auto vec = std::vector<PythonOutputT>();
vec.reserve(n);
for (Py_ssize_t i = 0; i < n; ++i) {
vec.emplace_back(convert(obj[i]));
}
return vec;
}
};
} // namespace Mantid::PythonInterface
\ No newline at end of file
......@@ -99,15 +99,26 @@ template <typename T> void extractKwargs(const dict &kwargs, const std::string &
}
}
class SetPropertyVisitor {
class SetPropertyVisitor : public boost::static_visitor<> {
public:
SetPropertyVisitor(Mantid::API::Algorithm_sptr &alg, std::string const &propName)
: m_alg(alg), m_propName(propName) {}
void operator()(bool value) { m_alg->setProperty(m_propName, value); }
void operator()(int value) { m_alg->setProperty(m_propName, value); }
void operator()(double value) { m_alg->setProperty(m_propName, value); }
void operator()(std::string const &value) { m_alg->setPropertyValue(m_propName, value); }
void operator()(bool value) const { m_alg->setProperty(m_propName, value); }
void operator()(int value) const { m_alg->setProperty(m_propName, value); }
void operator()(double value) const { m_alg->setProperty(m_propName, value); }
void operator()(std::string const &value) const { m_alg->setPropertyValue(m_propName, value); }
void operator()(std::vector<bool> const &value) const { m_alg->setProperty(m_propName, value); }
void operator()(std::vector<int> const &value) const { m_alg->setProperty(m_propName, value); }
void operator()(std::vector<double> const &value) const { m_alg->setProperty(m_propName, value); }
void operator()(std::vector<std::string> const &value) const { m_alg->setProperty(m_propName, value); }
void operator()(std::vector<Mantid::PythonInterface::PyNativeTypeExtractor::PythonOutputT> const &values) const {
for (auto const &value : values) {
boost::apply_visitor(SetPropertyVisitor(m_alg, m_propName), value);
}
}
private:
Mantid::API::Algorithm_sptr &m_alg;
......@@ -152,7 +163,7 @@ object createChildWithProps(tuple args, dict kwargs) {
using Mantid::PythonInterface::PyNativeTypeExtractor;
auto nativeObj = PyNativeTypeExtractor::convert(curArg);
std::visit(SetPropertyVisitor(childAlg, propName), nativeObj);
boost::apply_visitor(SetPropertyVisitor(childAlg, propName), nativeObj);
}
return object(childAlg);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment