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>());
51 using IntHandler = TypedPropertyValueHandler<int>;
52 index.emplace(&PyLong_Type, std::make_shared<IntHandler>());
57 using AsciiStrHandler = TypedPropertyValueHandler<std::string>;
59 index.emplace(&PyUnicode_Type, std::make_shared<AsciiStrHandler>());
61 index.emplace(&PyDict_Type, std::make_shared<MappingTypeHandler>());
67const PyTypeIndex &getTypeIndex() {
68 static PyTypeIndex
index;
70 initTypeLookup(
index);
75using PyArrayIndex = std::map<std::string, std::shared_ptr<PropertyValueHandler>>;
80void initArrayLookup(PyArrayIndex &
index) {
81 assert(
index.empty());
84 using FloatArrayHandler = SequenceTypeHandler<std::vector<double>>;
85 index.emplace(
"FloatArray", std::make_shared<FloatArrayHandler>());
87 using StringArrayHandler = SequenceTypeHandler<std::vector<std::string>>;
88 index.emplace(
"StringArray", std::make_shared<StringArrayHandler>());
90 using IntArrayHandler = SequenceTypeHandler<std::vector<int>>;
91 index.emplace(
"IntArray", std::make_shared<IntArrayHandler>());
97const PyArrayIndex &getArrayIndex() {
98 static PyArrayIndex
index;
100 initArrayLookup(
index);
116 const boost::python::object &defaultValue,
117 const boost::python::object &validator,
118 const unsigned int direction) {
119 const auto &propHandle =
lookup(defaultValue.ptr());
120 return propHandle.create(
name, defaultValue, validator, direction);
133 const boost::python::object &defaultValue,
134 const unsigned int direction) {
135 boost::python::object validator;
136 return create(
name, defaultValue, validator, direction);
147 const list &defaultValue) {
150 auto obj = object(defaultValue[0]).ptr();
151 auto val = defaultValue[0];
158 if (PyBool_Check(
obj)) {
159 return std::make_unique<TimeSeriesProperty<bool>>(
name);
160 }
else if (extract<int>(val).check()) {
161 return std::make_unique<TimeSeriesProperty<int>>(
name);
162 }
else if (extract<double>(val).check()) {
163 return std::make_unique<TimeSeriesProperty<double>>(
name);
164 }
else if (extract<std::string>(val).check()) {
165 return std::make_unique<TimeSeriesProperty<std::string>>(
name);
170 throw std::runtime_error(
"Cannot create a TimeSeriesProperty with that data type!");
183 const auto arrayType =
isArray(
object);
184 if (!arrayType.empty()) {
185 const PyArrayIndex &arrayIndex = getArrayIndex();
186 auto ait = arrayIndex.find(arrayType);
187 if (ait != arrayIndex.end()) {
188 return *(ait->second);
192 const PyTypeIndex &typeIndex = getTypeIndex();
193 auto cit = typeIndex.find(object->ob_type);
194 if (cit == typeIndex.end()) {
195 std::ostringstream os;
196 os <<
"Cannot create PropertyWithValue from Python type " <<
object->ob_type->tp_name
197 <<
". No converter registered in PropertyWithValueFactory.";
198 throw std::invalid_argument(os.str());
200 return *(cit->second);
209 if (PyList_Check(
object) || PyTuple_Check(
object)) {
212 if (PySequence_Size(
object) < 1) {
213 throw std::runtime_error(
"Cannot have a sequence type of length zero in a mapping type.");
216 PyObject *item = PySequence_Fast_GET_ITEM(
object, 0);
219 if (PyBool_Check(item)) {
220 throw std::runtime_error(
"Unable to support extracting arrays of booleans.");
222 if (PyLong_Check(item)) {
223 return std::string(
"IntArray");
226 if (PyFloat_Check(item)) {
227 return std::string(
"FloatArray");
229 if (PyUnicode_Check(item)) {
230 return std::string(
"StringArray");
232 if (PyBytes_Check(item)) {
233 return std::string(
"StringArray");
237 std::ostringstream os;
238 os <<
"Cannot create PropertyWithValue from Python type " <<
object->ob_type->tp_name
239 <<
" containing items of type " << item->ob_type <<
". No converter registered in PropertyWithValueFactory.";
241 throw std::invalid_argument(os.str());
243 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...