7 #ifndef PXR_BASE_TF_PY_CONTAINER_CONVERSIONS_H
8 #define PXR_BASE_TF_PY_CONTAINER_CONVERSIONS_H
30 #include "pxr/external/boost/python/list.hpp"
31 #include "pxr/external/boost/python/tuple.hpp"
32 #include "pxr/external/boost/python/extract.hpp"
33 #include "pxr/external/boost/python/to_python_converter.hpp"
44 template <
typename ContainerType>
49 pxr_boost::python::list
result;
53 return pxr_boost::python::incref(result.ptr());
58 template <
typename ContainerType>
63 PyObject*
result = PySet_New(
nullptr);
64 for (
const auto &elem : c) {
71 template <
typename ContainerType>
80 namespace TfPyContainerConversions {
82 template <
typename ContainerType>
87 pxr_boost::python::list
result;
88 typedef typename ContainerType::const_iterator const_iter;
89 for(const_iter p=a.begin();p!=a.end();p++) {
92 return pxr_boost::python::incref(pxr_boost::python::tuple(result).
ptr());
96 template <
typename First,
typename Second>
98 static PyObject*
convert(std::pair<First, Second>
const&
a)
100 pxr_boost::python::tuple
result =
101 pxr_boost::python::make_tuple(a.first, a.second);
102 return pxr_boost::python::incref(result.ptr());
106 template <
typename...
T>
108 static PyObject*
convert(std::tuple<T...>
const&
a)
112 pxr_boost::python::tuple
result =
113 pxr_boost::python::make_tuple(v...);
114 return pxr_boost::python::incref(result.ptr());
123 template <
typename ContainerType>
129 template <
typename ContainerType>
132 template <
typename ContainerType>
140 template <
typename ContainerType>
146 template <
typename ContainerType>
150 PyErr_SetString(PyExc_RuntimeError,
151 "Insufficient elements for fixed-size array.");
152 pxr_boost::python::throw_error_already_set();
156 template <
typename ContainerType>
160 PyErr_SetString(PyExc_RuntimeError,
161 "Too many elements for fixed-size array.");
162 pxr_boost::python::throw_error_already_set();
166 template <
typename ContainerType,
typename ValueType>
176 template <
typename ContainerType>
182 template <
typename ContainerType,
typename ValueType>
197 template <
typename ContainerType>
200 return ContainerType::max_size() >= sz;
206 template <
typename ContainerType,
typename ValueType>
215 template <
typename ContainerType,
typename ValueType>
222 template <
typename ContainerType,
typename ConversionPolicy>
229 pxr_boost::python::converter::registry::push_back(
232 pxr_boost::python::type_id<ContainerType>());
237 if (!( PyList_Check(obj_ptr)
238 || PyTuple_Check(obj_ptr)
239 || PySet_Check(obj_ptr)
240 || PyFrozenSet_Check(obj_ptr)
241 || PyIter_Check(obj_ptr)
242 || PyRange_Check(obj_ptr)
243 || ( !PyBytes_Check(obj_ptr)
244 && !PyUnicode_Check(obj_ptr)
245 && ( Py_TYPE(obj_ptr) == 0
246 || Py_TYPE(Py_TYPE(obj_ptr)) == 0
247 || Py_TYPE(Py_TYPE(obj_ptr))->tp_name == 0
249 Py_TYPE(Py_TYPE(obj_ptr))->tp_name,
250 "Boost.Python.class") != 0)
251 && PyObject_HasAttrString(obj_ptr,
"__len__")
252 && PyObject_HasAttrString(obj_ptr,
"__getitem__"))))
return 0;
253 pxr_boost::python::handle<> obj_iter(
254 pxr_boost::python::allow_null(PyObject_GetIter(obj_ptr)));
255 if (!obj_iter.get()) {
259 if (ConversionPolicy::check_convertibility_per_element()) {
260 Py_ssize_t obj_size = PyObject_Length(obj_ptr);
265 if (!ConversionPolicy::check_size(
267 bool is_range = PyRange_Check(obj_ptr);
270 if (!is_range) assert(i == (std::size_t)obj_size);
279 pxr_boost::python::handle<>& obj_iter,
284 pxr_boost::python::handle<> py_elem_hdl(
285 pxr_boost::python::allow_null(PyIter_Next(obj_iter.get())));
286 if (PyErr_Occurred()) {
290 if (!py_elem_hdl.get())
break;
292 pxr_boost::python::extract<container_element_type>
293 elem_proxy(py_elem_obj);
294 if (!elem_proxy.check())
return false;
302 pxr_boost::python::converter::rvalue_from_python_stage1_data*
data)
304 pxr_boost::python::handle<> obj_iter(PyObject_GetIter(obj_ptr));
306 (pxr_boost::python::converter::rvalue_from_python_storage<ContainerType>*)
307 data)->storage.bytes;
313 pxr_boost::python::handle<> py_elem_hdl(
314 pxr_boost::python::allow_null(PyIter_Next(obj_iter.get())));
315 if (PyErr_Occurred()) pxr_boost::python::throw_error_already_set();
316 if (!py_elem_hdl.get())
break;
318 pxr_boost::python::extract<container_element_type> elem_proxy(py_elem_obj);
319 ConversionPolicy::set_value(result, i, elem_proxy());
325 template <
typename Indexes,
typename TupleType,
typename...
T>
328 template <
size_t... I,
typename TupleType,
typename...
T>
333 pxr_boost::python::converter::registry::push_back(
336 pxr_boost::python::type_id<TupleType>());
341 if (!PyTuple_Check(obj_ptr) || PyTuple_Size(obj_ptr) !=
sizeof...(
T)) {
344 if ((!pxr_boost::python::extract<T>(
345 PyTuple_GetItem(obj_ptr, I)).check() || ...)) {
353 pxr_boost::python::converter::rvalue_from_python_stage1_data*
data)
356 (pxr_boost::python::converter::rvalue_from_python_storage<TupleType>*)
357 data)->storage.bytes;
359 pxr_boost::python::extract<T>(PyTuple_GetItem(obj_ptr, I))()...);
364 template <
typename PairType>
367 std::make_index_sequence<2>, PairType,
368 typename PairType::first_type, typename PairType::second_type
373 template <
typename TupleType>
376 template <
typename...
T>
379 std::index_sequence_for<T...>, std::tuple<T...>, T...
384 template <
typename ContainerType>
388 pxr_boost::python::to_python_converter<
394 template <
typename ContainerType,
typename ConversionPolicy>
404 template <
typename ContainerType>
414 template <
typename ContainerType>
424 template <
typename ContainerType>
434 template <
typename ContainerType>
444 template <
typename ContainerType>
448 pxr_boost::python::to_python_converter<
460 using namespace TfPyContainerConversions;
471 #endif // PXR_BASE_TF_PY_CONTAINER_CONVERSIONS_H
static bool check_convertibility_per_element()
static bool check_convertibility_per_element()
static bool check_size(ContainerType *, std::size_t sz)
static void construct(PyObject *obj_ptr, pxr_boost::python::converter::rvalue_from_python_stage1_data *data)
static bool all_elements_convertible(pxr_boost::python::handle<> &obj_iter, bool is_range, std::size_t &i)
tuple_mapping_variable_capacity()
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
getFileOption("OpenEXR:storage") storage
static PyObject * convert(std::tuple< T...> const &a)
tuple_mapping_fixed_capacity()
static bool check_size(ContainerType *, std::size_t sz)
GLboolean GLboolean GLboolean GLboolean a
static PyObject * convert(ContainerType const &c)
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
ContainerType::value_type container_element_type
**But if you need a result
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
static PyObject * convert(ContainerType const &a)
tuple_mapping_fixed_size()
void TfPyRegisterStlSequencesFromPython()
static bool check_size(ContainerType *, std::size_t sz)
static void reserve(ContainerType &a, std::size_t sz)
static bool check_convertibility_per_element()
static void assert_size(ContainerType *c, std::size_t sz)
static PyObject * convert(ContainerType const &c)
static void * convertible(PyObject *obj_ptr)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
#define PXR_NAMESPACE_CLOSE_SCOPE
static void assert_size(ContainerType *, std::size_t sz)
static void set_value(ContainerType &a, std::size_t i, ValueType const &v)
static void construct(PyObject *obj_ptr, pxr_boost::python::converter::rvalue_from_python_stage1_data *data)
#define TF_FOR_ALL(iter, c)
static void reserve(ContainerType &a, std::size_t sz)
static PyObject * convert(std::pair< First, Second > const &a)
static PyObject * convert(ContainerType const &c)
static void * convertible(PyObject *obj_ptr)
pxr_boost::python::dict TfPyCopyMapToDictionary(Map const &map)
Creates a python dictionary from a std::map.
static void reserve(ContainerType &a, std::size_t sz)