18#include <boost/python.hpp>
19#include <boost/python/class.hpp>
20#include <boost/python/extract.hpp>
21#include <boost/python/list.hpp>
22#include <boost/python/object.hpp>
36using PyTypeIndex = std::map<const PyTypeObject *, std::shared_ptr<PropertyValueHandler>>;
41void initTypeLookup(PyTypeIndex &
index) {
42 assert(
index.empty());
45 using FloatHandler = TypedPropertyValueHandler<double>;
46 index.emplace(&PyFloat_Type, std::make_shared<FloatHandler>());
48 using BoolHandler = TypedPropertyValueHandler<bool>;
49 index.emplace(&PyBool_Type, std::make_shared<BoolHandler>());
53 using IntHandler = TypedPropertyValueHandler<long>;
54 index.emplace(&PyLong_Type, std::make_shared<IntHandler>());
59 using AsciiStrHandler = TypedPropertyValueHandler<std::string>;
61 index.emplace(&PyUnicode_Type, std::make_shared<AsciiStrHandler>());
63 index.emplace(&PyDict_Type, std::make_shared<MappingTypeHandler>());
69const PyTypeIndex &getTypeIndex() {
70 static PyTypeIndex
index;
72 initTypeLookup(
index);
77using PyArrayIndex = std::map<std::string, std::shared_ptr<PropertyValueHandler>>;
82void initArrayLookup(PyArrayIndex &
index) {
83 assert(
index.empty());
86 using FloatArrayHandler = SequenceTypeHandler<std::vector<double>>;
87 index.emplace(
"FloatArray", std::make_shared<FloatArrayHandler>());
89 using StringArrayHandler = SequenceTypeHandler<std::vector<std::string>>;
90 index.emplace(
"StringArray", std::make_shared<StringArrayHandler>());
92 using LongIntArrayHandler = SequenceTypeHandler<std::vector<long>>;
93 index.emplace(
"LongIntArray", std::make_shared<LongIntArrayHandler>());
99const PyArrayIndex &getArrayIndex() {
100 static PyArrayIndex
index;
102 initArrayLookup(
index);
118 const boost::python::object &defaultValue,
119 const boost::python::object &validator,
120 const unsigned int direction) {
121 const auto &propHandle =
lookup(defaultValue.ptr());
122 return propHandle.create(name, defaultValue, validator, direction);
135 const boost::python::object &defaultValue,
136 const unsigned int direction) {
137 boost::python::object validator;
138 return create(name, defaultValue, validator, direction);
149 const list &defaultValue) {
152 auto obj = object(defaultValue[0]).ptr();
153 auto val = defaultValue[0];
160 if (PyBool_Check(
obj)) {
161 return std::make_unique<TimeSeriesProperty<bool>>(name);
162 }
else if (extract<int>(val).check()) {
163 return std::make_unique<TimeSeriesProperty<int>>(name);
164 }
else if (extract<double>(val).check()) {
165 return std::make_unique<TimeSeriesProperty<double>>(name);
166 }
else if (extract<std::string>(val).check()) {
167 return std::make_unique<TimeSeriesProperty<std::string>>(name);
172 throw std::runtime_error(
"Cannot create a TimeSeriesProperty with that data type!");
185 const auto arrayType =
isArray(
object);
186 if (!arrayType.empty()) {
187 const PyArrayIndex &arrayIndex = getArrayIndex();
188 auto ait = arrayIndex.find(arrayType);
189 if (ait != arrayIndex.end()) {
190 return *(ait->second);
194 const PyTypeIndex &typeIndex = getTypeIndex();
195 auto cit = typeIndex.find(object->ob_type);
196 if (cit == typeIndex.end()) {
197 std::ostringstream os;
198 os <<
"Cannot create PropertyWithValue from Python type " <<
object->ob_type->tp_name
199 <<
". No converter registered in PropertyWithValueFactory.";
200 throw std::invalid_argument(os.str());
202 return *(cit->second);
211 if (PyList_Check(
object) || PyTuple_Check(
object)) {
214 if (PySequence_Size(
object) < 1) {
215 throw std::runtime_error(
"Cannot have a sequence type of length zero in a mapping type.");
218 PyObject *item = PySequence_Fast_GET_ITEM(
object, 0);
221 if (PyBool_Check(item)) {
222 throw std::runtime_error(
"Unable to support extracting arrays of booleans.");
224 if (PyLong_Check(item)) {
225 return std::string(
"LongIntArray");
228 if (PyFloat_Check(item)) {
229 return std::string(
"FloatArray");
231 if (PyUnicode_Check(item)) {
232 return std::string(
"StringArray");
234 if (PyBytes_Check(item)) {
235 return std::string(
"StringArray");
239 std::ostringstream os;
240 os <<
"Cannot create PropertyWithValue from Python type " <<
object->ob_type->tp_name
241 <<
" containing items of type " << item->ob_type <<
". No converter registered in PropertyWithValueFactory.";
243 throw std::invalid_argument(os.str());
245 return std::string(
"");
std::map< DeltaEMode::Type, std::string > index
double obj
the value of the quadratic function
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
A specialised Property class for holding a series of time-value pairs.
Defines a static factory class that creates PropertyWithValue instances from python objects.
static std::unique_ptr< Kernel::Property > createTimeSeries(const std::string &name, const boost::python::list &defaultValue)
Creates a TimeSeriesProperty<Type> instance from the given information.
static std::unique_ptr< Kernel::Property > create(const std::string &name, const boost::python::object &defaultValue, const boost::python::object &validator, const unsigned int direction)
Creates a PropertyWithValue<Type> instance from the given information.
static const PropertyValueHandler & lookup(PyObject *const object)
Return a handler that maps the python type to a C++ type.
static const std::string isArray(PyObject *const object)
Return a string based on the python array type.
This class provides a base-class objects that are able to take a python object and set it on an algor...