24#ifndef PXR_BASE_TF_PY_OPTIONAL_H
25#define PXR_BASE_TF_PY_OPTIONAL_H
32#include <boost/noncopyable.hpp>
33#include <boost/optional.hpp>
34#include <boost/python/converter/from_python.hpp>
35#include <boost/python/extract.hpp>
36#include <boost/python/to_python_converter.hpp>
37#include <boost/python/to_python_value.hpp>
41PXR_NAMESPACE_OPEN_SCOPE
46namespace TfPyOptional {
48template <
typename T,
typename TfromPy>
49struct object_from_python
51 object_from_python() {
52 boost::python::converter::registry::push_back
53 (&TfromPy::convertible, &TfromPy::construct,
54 boost::python::type_id<T>());
58template <
typename T,
typename TtoPy,
typename TfromPy>
59struct register_python_conversion
61 register_python_conversion() {
62 boost::python::to_python_converter<T, TtoPy>();
63 object_from_python<T, TfromPy>();
68struct python_optional :
public boost::noncopyable
70 template <
typename Optional>
71 struct optional_to_python
73 static PyObject * convert(
const Optional& value)
76 boost::python::object obj =
TfPyObject(*value);
80 return boost::python::detail::none();
84 template <
typename Optional>
85 struct optional_from_python
87 static void * convertible(PyObject * source)
89 using namespace boost::python::converter;
91 if ((source == Py_None) || boost::python::extract<T>(source).check())
97 static void construct(PyObject * source,
98 boost::python::converter::rvalue_from_python_stage1_data * data)
100 using namespace boost::python::converter;
102 void *
const storage =
103 ((rvalue_from_python_storage<T> *)data)->storage.bytes;
105 if (data->convertible == Py_None) {
106 new (storage) Optional();
108 new (storage) Optional(boost::python::extract<T>(source));
111 data->convertible = storage;
115 explicit python_optional() {
116 register_python_conversion<
118 optional_to_python<std::optional<T>>,
119 optional_from_python<std::optional<T>>>();
120 register_python_conversion<
122 optional_to_python<boost::optional<T>>,
123 optional_from_python<boost::optional<T>>>();
129PXR_NAMESPACE_CLOSE_SCOPE
Miscellaneous Utilities for dealing with script.
boost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Return a python object for the given C++ object, loading the appropriate wrapper code if necessary.