12 #ifndef PY_CONVERSIONS_H
13 #define PY_CONVERSIONS_H
16 #include <boost/python.hpp>
21 using namespace boost::python;
36 template <
typename ContainerType >
43 static PyObject*
convert (ContainerType
const& c)
45 using boost::python::incref;
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>());
162 static void* convertible(PyObject* obj_ptr)
164 using namespace boost::python;
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 );
214 static void construct(
216 boost::python::converter::rvalue_from_python_stage1_data*
data)
218 using namespace boost::python;
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