12 #ifndef PY_CONVERSIONS_H 13 #define PY_CONVERSIONS_H 16 #include <boost/python.hpp> 36 template <
typename ContainerType >
43 static PyObject*
convert (ContainerType
const& c)
45 using boost::python::incref;
46 using boost::python::list;
48 typename ContainerType::const_iterator i = c.begin();
49 for( ; i != c.end(); ++i)
53 return incref(tuple(result).ptr());
68 template <
typename T >
73 to_python_converter < std::vector < T >,
94 template <
typename ContainerType>
95 static bool check_size(boost::type<ContainerType>, std::size_t )
100 template <
typename ContainerType>
104 template <
typename ContainerType>
105 static void reserve(ContainerType& a, std::size_t ) {}
122 template <
typename ContainerType>
123 static void reserve(ContainerType& a, std::size_t sz)
128 template <
typename ContainerType,
typename ValueType>
129 static void set_value(ContainerType& a, std::size_t i, ValueType
const& v)
131 assert(a.size() == i);
147 template <
typename ContainerType,
typename ConversionPolicy>
154 boost::python::converter::registry::push_back(
157 boost::python::type_id<ContainerType>());
165 using boost::python::allow_null;
172 if (!( PyList_Check(obj_ptr)
173 || PyTuple_Check(obj_ptr)
174 || PyIter_Check(obj_ptr)
175 || PyRange_Check(obj_ptr)
176 || PySequence_Check(obj_ptr) ))
return 0;
178 handle<> obj_iter(allow_null(PyObject_GetIter(obj_ptr)));
179 if (!obj_iter.get()) {
183 if (ConversionPolicy::check_convertibility_per_element()) {
184 int obj_size = PyObject_Length(obj_ptr);
190 boost::type<ContainerType>(), obj_size))
return 0;
191 bool is_range = PyRange_Check(obj_ptr);
194 #ifndef _MSC_VER // because it causes c1001: internal compiler error 196 handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get())));
197 if (PyErr_Occurred()) {
201 if (!py_elem_hdl.get())
break;
202 object py_elem_obj(py_elem_hdl);
203 extract<container_element_type> elem_proxy(py_elem_obj);
204 if (!elem_proxy.check())
return 0;
207 if (!is_range) assert(i == obj_size );
216 boost::python::converter::rvalue_from_python_stage1_data*
data)
219 using boost::python::allow_null;
220 using boost::python::converter::rvalue_from_python_storage;
221 using boost::python::throw_error_already_set;
222 handle<> obj_iter(PyObject_GetIter(obj_ptr));
224 (rvalue_from_python_storage<ContainerType>*)
225 data)->storage.bytes;
226 new (storage) ContainerType();
227 data->convertible = storage;
228 ContainerType& result = *((ContainerType*)storage);
231 handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get())));
232 if (PyErr_Occurred()) throw_error_already_set();
233 if (!py_elem_hdl.get())
break;
234 object py_elem_obj(py_elem_hdl);
235 extract<container_element_type> elem_proxy(py_elem_obj);
236 ConversionPolicy::set_value(result, i, elem_proxy());
238 ConversionPolicy::assert_size(boost::type<ContainerType>(), i);
243 #endif // PY_CONVERSIONS_H void check_size(boost::python::numeric::array arr, intp expected_size)
Throw an exception if the actual total size of the array is not equal to the expected size...
static PyObject * convert(ContainerType const &c)
Creates and returns a Python tuple from the elements copied from a STL container. ...
static void reserve(ContainerType &a, std::size_t)
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_size(boost::type< ContainerType >, std::size_t)
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
A wrapper of a conversion function to convert a STL vector to a Python tuple.
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *data)
Constructs a C++ container from a Python sequence.
ContainerType::value_type container_element_type
Default operations on all containers for conversion from Python container to C++ one.
Conversion of Python sequence to C++ container.
static bool check_convertibility_per_element()
Converts an STL vector of T objects to Python tuple.
void * data(numeric::array arr)
static void reserve(ContainerType &a, std::size_t sz)
Operations on containers that have variable capacity for conversion from Python container to C++ one...
static void assert_size(boost::type< ContainerType >, std::size_t)