26#ifndef PYRAP_PYCBASICDATA_H
27#define PYRAP_PYCBASICDATA_H
30#include <boost/python.hpp>
31#include <boost/python/object.hpp>
32#include <casacore/python/Converters/PycArray.h>
33#include <casacore/casa/BasicSL/String.h>
34#include <casacore/casa/Arrays/IPosition.h>
35#include <casacore/casa/Arrays/Vector.h>
36#include <casacore/casa/Utilities/Assert.h>
37#include <casacore/casa/Exceptions/Error.h>
41#if PY_MAJOR_VERSION >= 3
70 return boost::python::object((
const std::string&)s);
79 boost::python::type_id<String>());
84 if (!PyUnicode_Check(obj_ptr))
return 0;
86 if (!PyString_Check(obj_ptr) && !PyUnicode_Check(obj_ptr))
return 0;
92 boost::python::converter::rvalue_from_python_stage1_data* data) {
94 boost::python::object temp_bytes_obj;
95 if (PyUnicode_Check(obj_ptr)) {
96 PyObject* temp_bytes =
97 PyUnicode_AsEncodedString(obj_ptr,
"UTF-8",
"strict");
99 if (temp_bytes != NULL) {
101 temp_bytes_obj = boost::python::object(boost::python::handle<>(temp_bytes));
102 value = PyBytes_AS_STRING(temp_bytes);
104 boost::python::throw_error_already_set();
107 }
else if (PyString_Check(obj_ptr)) {
108 value = PyString_AsString(obj_ptr);
111 boost::python::throw_error_already_set();
113 if (
value == 0) boost::python::throw_error_already_set();
115 ((boost::python::converter::rvalue_from_python_storage<String>*)data)->storage.bytes;
135 template <
typename ContainerType>
136 static bool check_size(boost::type<ContainerType>, std::size_t) {
140 template <
typename ContainerType>
141 static void assert_size(boost::type<ContainerType>, std::size_t) {}
143 template <
typename ContainerType>
144 static void reserve(ContainerType&, std::size_t) {}
159 template <
typename ContainerType>
160 static void reserve(ContainerType& a, std::size_t sz) {
164 template <
typename ContainerType,
typename ValueType>
165 static void set_value(ContainerType& a, std::size_t i, ValueType
const& v) {
172 template <
typename ContainerType>
173 static void reserve(ContainerType& a, std::size_t sz) {
177 template <
typename ContainerType,
typename ValueType>
178 static void set_value(ContainerType& a, std::size_t i, ValueType
const& v) {
179 assert(a.size() > i);
185 template <
typename ContainerType>
186 static void reserve(ContainerType& a, std::size_t sz) {
190 template <
typename ContainerType,
typename ValueType>
191 static void set_value(ContainerType& a, std::size_t i, ValueType
const& v) {
192 assert(a.size() > i);
193 a[a.size() - i - 1] = v;
209template <
typename ContainerType>
216 static boost::python::object
makeobject(ContainerType
const& c) {
217 boost::python::list result;
218 typename ContainerType::const_iterator i = c.begin();
219 typename ContainerType::const_iterator iEnd = c.end();
220 for (; i != iEnd; ++i) {
225 static PyObject*
convert(ContainerType
const& c) {
226 return boost::python::incref(
makeobject(c).ptr());
235 boost::python::list result;
236 for (
int i = c.size() - 1; i >= 0; --i) {
242 return boost::python::incref(
makeobject(c).ptr());
255 boost::python::list result;
256 ContainerType::const_iterator i = c.begin();
257 ContainerType::const_iterator iEnd = c.end();
258 for (; i != iEnd; ++i) {
265 return boost::python::incref(
makeobject(c).ptr());
272 boost::python::list result;
273 ContainerType::const_iterator i = c.begin();
274 ContainerType::const_iterator iEnd = c.end();
275 for (; i != iEnd; ++i) {
276 result.append((std::string
const&)(*i));
281 return boost::python::incref(
makeobject(c).ptr());
288 boost::python::list result;
291 for (; i != iEnd; ++i) {
292 result.append((std::string
const&)(*i));
297 return boost::python::incref(
makeobject(c).ptr());
304 boost::python::list result;
307 for (; i != iEnd; ++i) {
308 result.append((std::string
const&)(*i));
313 return boost::python::incref(
makeobject(c).ptr());
345 boost::python::to_python_converter<casacore::IPosition, to_list<casacore::IPosition>>();
358template <
typename ContainerType,
typename ConversionPolicy>
364 boost::python::type_id<ContainerType>());
370 using namespace boost::python;
371 handle<> py_hdl(obj_ptr);
372 if (PyErr_Occurred()) {
376 object py_obj(py_hdl);
379 if (PyBool_Check(obj_ptr) || PyLong_Check(obj_ptr) || PyFloat_Check(obj_ptr) ||
380 PyComplex_Check(obj_ptr)
382 || PyInt_Check(obj_ptr) || PyString_Check(obj_ptr)
384 || PyUnicode_Check(obj_ptr)) {
385 extract<container_element_type> elem_proxy(py_obj);
386 if (!elem_proxy.check())
return 0;
401 handle<> obj_iter(allow_null(PyObject_GetIter(py_obj.ptr())));
402 if (!obj_iter.get()) {
414 boost::python::converter::rvalue_from_python_stage1_data* data) {
415 using namespace boost::python;
416 using boost::python::converter::rvalue_from_python_storage;
417 void*
storage = ((rvalue_from_python_storage<ContainerType>*)data)->storage.bytes;
420 ContainerType& result = *((ContainerType*)
storage);
421 if (PyBool_Check(obj_ptr) || PyLong_Check(obj_ptr) || PyFloat_Check(obj_ptr) ||
422 PyComplex_Check(obj_ptr) || PyUnicode_Check(obj_ptr)
424 || PyString_Check(obj_ptr) || PyInt_Check(obj_ptr)
427 extract<container_element_type> elem_proxy(obj_ptr);
428 ConversionPolicy::reserve(result, 1);
429 ConversionPolicy::set_value(result, 0, elem_proxy());
432 handle<> py_hdl(obj_ptr);
433 object py_obj = object(py_hdl);
444 ContainerType result;
451 using namespace boost::python;
452 int obj_size = PyObject_Length(obj_ptr);
453 handle<> obj_iter(PyObject_GetIter(obj_ptr));
454 ConversionPolicy::reserve(result, obj_size);
457 handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get())));
458 if (PyErr_Occurred()) throw_error_already_set();
459 if (!py_elem_hdl.get())
break;
460 object py_elem_obj(py_elem_hdl);
461 extract<container_element_type> elem_proxy(py_elem_obj);
462 ConversionPolicy::set_value(result, i, elem_proxy());
464 ConversionPolicy::assert_size(boost::type<ContainerType>(), i);
468 using namespace boost::python;
469 handle<> obj_iter(allow_null(PyObject_GetIter(obj_ptr)));
470 if (!obj_iter.get()) {
474 int obj_size = PyObject_Length(obj_ptr);
479 if (ConversionPolicy::check_convertibility_per_element()) {
480 if (!ConversionPolicy::check_size(boost::type<ContainerType>(), obj_size))
return false;
483 bool is_same = PyRange_Check(obj_ptr) || (PySequence_Check(obj_ptr) &&
484 !PyTuple_Check(obj_ptr) && !PyList_Check(obj_ptr));
485 [[maybe_unused]]
int i = 0;
487 handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get())));
488 if (PyErr_Occurred()) {
492 if (!py_elem_hdl.get())
break;
493 object py_elem_obj(py_elem_hdl);
494 extract<container_element_type> elem_proxy(py_elem_obj);
495 if (!elem_proxy.check())
return false;
499 if (!is_same) assert(i == obj_size);
521 std::string tname(
typeid(std::vector<T>).
name());
#define AlwaysAssert(expr, exception)
These marcos are provided for use instead of simply using the assert_ function directly.
ConstIteratorSTL const_iterator
String: the storage and methods of handling collections of characters.
Prevent a converter from being registered multiple times.
static std::map< std::string, bool > _registry
static bool get(const std::string &name)
static void set(const std::string &name)
void register_convert_casa_string()
void register_convert_basicdata()
Register all standard basic conversions.
Bool PycArrayScalarCheck(PyObject *obj_ptr)
Check if the PyObject is an array scalar object.
void register_convert_casa_iposition()
void register_convert_casa_vector()
bool getSeqObject(boost::python::object &py_obj)
Check if the given object is a sequence object.
void register_convert_std_vector()
For temporary backward namespace compatibility, use casa as alias for casacore.
T * storage()
If you really, really, need a "raw" pointer to the beginning of the storage area this will give it to...
String name() const
Return the name of the field.
NewDelAllocator< T > NewDelAllocator< T >::value
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
static void reserve(ContainerType &a, std::size_t sz)
static void * convertible(PyObject *obj_ptr)
casa_string_from_python_str()
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
Convert a String object to python.
static PyObject * convert(String const &s)
static boost::python::object makeobject(String const &s)
static void reserve(ContainerType &a, std::size_t sz)
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
Register the IPosition conversion.
Register the String conversion.
Register the casacore::Vector conversions.
Register the std::vector conversions.
Default operations on all containers for conversion from Python container to C++ one.
static void assert_size(boost::type< ContainerType >, std::size_t)
static bool check_size(boost::type< ContainerType >, std::size_t)
static bool check_convertibility_per_element()
static void reserve(ContainerType &, std::size_t)
Conversion of Python sequence to C++ container.
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
Constructs a C++ container from a Python sequence.
static ContainerType make_container(PyObject *obj_ptr)
Constructs a C++ container from a Python sequence.
static void fill_container(ContainerType &result, PyObject *obj_ptr)
static void * convertible(PyObject *obj_ptr)
Appears to return obj_ptr if it is type of Python sequence that can be convertible to C++ container.
static bool check_convertibility(PyObject *obj_ptr)
ContainerType::value_type container_element_type
Converts an STL vector or casa Array of T objects to Python list.
Operations on containers that have variable capacity for conversion from Python container to C++ one.
static void reserve(ContainerType &a, std::size_t sz)
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
static boost::python::object makeobject(ContainerType const &c)
static PyObject * convert(ContainerType const &c)
casacore::Array< casacore::String > ContainerType
static PyObject * convert(ContainerType const &c)
static boost::python::list makeobject(ContainerType const &c)
static PyObject * convert(ContainerType const &c)
casacore::Vector< casacore::String > ContainerType
static boost::python::object makeobject(ContainerType const &c)
std::vector< bool > ContainerType
static PyObject * convert(ContainerType const &c)
static boost::python::list makeobject(ContainerType const &c)
static boost::python::list makeobject(ContainerType const &c)
static PyObject * convert(ContainerType const &c)
std::vector< casacore::String > ContainerType
A wrapper of a conversion function to convert a STL vector to a Python list.
static PyObject * convert(ContainerType const &c)
static boost::python::object makeobject(ContainerType const &c)
Creates and returns a Python list from the elements copied from a STL container.