All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pyAnnotatedBoolResult.h
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_ANNOTATED_BOOL_RESULT_H
8#define PXR_BASE_TF_PY_ANNOTATED_BOOL_RESULT_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/base/tf/pyLock.h"
13#include "pxr/base/tf/pyUtils.h"
14
15#include "pxr/external/boost/python/class.hpp"
16#include "pxr/external/boost/python/operators.hpp"
17#include "pxr/external/boost/python/return_by_value.hpp"
18
19#include <string>
20
21PXR_NAMESPACE_OPEN_SCOPE
22
23template <class Annotation>
24struct TfPyAnnotatedBoolResult
25{
26 TfPyAnnotatedBoolResult() {}
27
28 TfPyAnnotatedBoolResult(bool val, Annotation const &annotation) :
29 _val(val), _annotation(annotation) {}
30
31 bool GetValue() const {
32 return _val;
33 }
34
35 Annotation const &GetAnnotation() const {
36 return _annotation;
37 }
38
39 std::string GetRepr() const {
40 return GetValue() ? "True" :
41 "(False, " + TfPyRepr(GetAnnotation()) + ")";
42 }
43
45 bool operator==(bool rhs) const {
46 return _val == rhs;
47 }
48
49 friend bool operator==(bool lhs, const TfPyAnnotatedBoolResult& rhs) {
50 return rhs == lhs;
51 }
52
53 friend bool operator!=(const TfPyAnnotatedBoolResult& lhs, bool rhs) {
54 return !(lhs == rhs);
55 }
56
57 friend bool operator!=(bool lhs, const TfPyAnnotatedBoolResult& rhs) {
58 return !(lhs == rhs);
59 }
60
61 template <class Derived>
62 static pxr_boost::python::class_<Derived>
63 Wrap(char const *name, char const *annotationName) {
64 typedef TfPyAnnotatedBoolResult<Annotation> This;
65 using namespace pxr_boost::python;
66 TfPyLock lock;
67 return class_<Derived>(name, init<bool, Annotation>())
68 .def("__bool__", &Derived::GetValue)
69 .def("__repr__", &Derived::GetRepr)
70 .def(self == bool())
71 .def(self != bool())
72 .def(bool() == self)
73 .def(bool() != self)
74 // Use a helper function. We'd like to def_readonly the
75 // _annotation member but there are two problems with that.
76 // First, we can't control the return_value_policy and if the
77 // Annotation type has a custom to-Python converter then the
78 // def_readonly return_value_policy of return_internal_reference
79 // won't work since the object needs conversion. Second, if we
80 // try to use GetAnnotation() with add_property then we'll get
81 // a failure at runtime because Python has a Derived but
82 // GetAnnotation takes a TfPyAnnotatedBoolResult<Annotation>
83 // and boost python doesn't know the former is-a latter because
84 // TfPyAnnotatedBoolResult<Annotation> is not wrapped.
85 //
86 // So we provide a templated static method that takes a Derived
87 // and returns Annotation by value. We can add_property that
88 // with no problem.
89 .add_property(annotationName, &This::_GetAnnotation<Derived>)
90 .def("__getitem__", &This::_GetItem<Derived>)
91 ;
92 }
93
94 using AnnotationType = Annotation;
95
96private:
97 // Helper function for wrapper.
98 template <class Derived>
99 static Annotation _GetAnnotation(const Derived& x)
100 {
101 return x.GetAnnotation();
102 }
103
104 template <class Derived>
105 static pxr_boost::python::object _GetItem(const Derived& x, int i)
106 {
107 if (i == 0) {
108 return pxr_boost::python::object(x._val);
109 }
110 if (i == 1) {
111 return pxr_boost::python::object(x._annotation);
112 }
113
114 PyErr_SetString(PyExc_IndexError, "Index must be 0 or 1.");
115 pxr_boost::python::throw_error_already_set();
116
117 return pxr_boost::python::object();
118 }
119
120private:
121 bool _val;
122 Annotation _annotation;
123
124};
125
127template <class Annotation>
128bool operator==(bool lhs, TfPyAnnotatedBoolResult<Annotation>& rhs)
129{
130 return rhs == lhs;
131}
132
134template <class Annotation>
135bool operator!=(bool lhs, TfPyAnnotatedBoolResult<Annotation>& rhs)
136{
137 return rhs != lhs;
138}
139
140PXR_NAMESPACE_CLOSE_SCOPE
141
142#endif // PXR_BASE_TF_PY_ANNOTATED_BOOL_RESULT_H
Miscellaneous Utilities for dealing with script.
std::string TfPyRepr(T const &t)
Return repr(t).
Definition: pyUtils.h:163
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:105