All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pyOptional.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_TF_PY_OPTIONAL_H
8#define PXR_BASE_TF_PY_OPTIONAL_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/base/tf/pyUtils.h"
15#include "pxr/external/boost/python/converter/from_python.hpp"
16#include "pxr/external/boost/python/extract.hpp"
17#include "pxr/external/boost/python/to_python_converter.hpp"
18#include "pxr/external/boost/python/to_python_value.hpp"
19
20#include <optional>
21
22PXR_NAMESPACE_OPEN_SCOPE
23
24// Adapted from original at:
25// http://mail.python.org/pipermail/cplusplus-sig/2007-May/012003.html
26
27namespace TfPyOptional {
28
29template <typename T, typename TfromPy>
30struct object_from_python
31{
32 object_from_python() {
33 pxr_boost::python::converter::registry::push_back
34 (&TfromPy::convertible, &TfromPy::construct,
35 pxr_boost::python::type_id<T>());
36 }
37};
38
39template <typename T, typename TtoPy, typename TfromPy>
40struct register_python_conversion
41{
42 register_python_conversion() {
43 pxr_boost::python::to_python_converter<T, TtoPy>();
44 object_from_python<T, TfromPy>();
45 }
46};
47
48template <typename T>
49struct python_optional
50{
51 python_optional(const python_optional&) = delete;
52 python_optional& operator=(const python_optional&) = delete;
53 template <typename Optional>
54 struct optional_to_python
55 {
56 static PyObject * convert(const Optional& value)
57 {
58 if (value) {
59 pxr_boost::python::object obj = TfPyObject(*value);
60 Py_INCREF(obj.ptr());
61 return obj.ptr();
62 }
63 return pxr_boost::python::detail::none();
64 }
65 };
66
67 template <typename Optional>
68 struct optional_from_python
69 {
70 static void * convertible(PyObject * source)
71 {
72 using namespace pxr_boost::python::converter;
73
74 if ((source == Py_None) || pxr_boost::python::extract<T>(source).check())
75 return source;
76
77 return NULL;
78 }
79
80 static void construct(PyObject * source,
81 pxr_boost::python::converter::rvalue_from_python_stage1_data * data)
82 {
83 using namespace pxr_boost::python::converter;
84
85 void * const storage =
86 ((rvalue_from_python_storage<T> *)data)->storage.bytes;
87
88 if (data->convertible == Py_None) {
89 new (storage) Optional(); // An uninitialized optional
90 } else {
91 new (storage) Optional(pxr_boost::python::extract<T>(source));
92 }
93
94 data->convertible = storage;
95 }
96 };
97
98 explicit python_optional() {
99 register_python_conversion<
100 std::optional<T>,
101 optional_to_python<std::optional<T>>,
102 optional_from_python<std::optional<T>>>();
103 }
104};
105
106} // namespace TfPyOptional
107
108PXR_NAMESPACE_CLOSE_SCOPE
109
110#endif // PXR_BASE_TF_PY_OPTIONAL_H
Miscellaneous Utilities for dealing with script.
pxr_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.
Definition: pyUtils.h:127