Loading...
Searching...
No Matches
pyOperators.h
1
//
2
// Copyright 2017 Pixar
3
//
4
// Licensed under the terms set forth in the LICENSE.txt file available at
5
// https://openusd.org/license.
6
//
7
8
#ifndef PXR_BASE_VT_PY_OPERATORS_H
9
#define PXR_BASE_VT_PY_OPERATORS_H
10
11
#include "
pxr/pxr.h
"
12
#include "pxr/base/vt/api.h"
13
14
PXR_NAMESPACE_OPEN_SCOPE
15
16
namespace
{
17
// Per-op helpers with auto return so the result type is deduced from the
18
// element operation. This enables heterogeneous results for list/tuple
19
// operands (e.g. __sub__ on a TimeCode array produces a Duration array).
20
// The bool specialization preserves existing Hyrum's-Law behavior.
21
template
<
class
T>
22
struct
_ArrayPyOpHelp {
23
static
auto
__add__(T l, T r) {
return
l + r; }
24
static
auto
__sub__(T l, T r) {
return
l - r; }
25
static
auto
__mul__(T l, T r) {
return
l * r; }
26
static
auto
__div__(T l, T r) {
return
l / r; }
27
static
auto
__mod__(T l, T r) {
return
l % r; }
28
};
29
30
// These operations on bool-arrays are highly questionable, but this preserves
31
// existing behavior in the name of Hyrum's Law.
32
template
<>
33
struct
_ArrayPyOpHelp<bool> {
34
static
bool
__add__(
bool
l,
bool
r) {
return
l | r; }
35
static
bool
__sub__(
bool
l,
bool
r) {
return
l ^ r; }
36
static
bool
__mul__(
bool
l,
bool
r) {
return
l & r; }
37
static
bool
__div__(
bool
l,
bool
r) {
return
l; }
38
static
bool
__mod__(
bool
l,
bool
r) {
return
false
; }
39
};
40
41
}
// anon
42
43
// -------------------------------------------------------------------------
44
// Python operator definitions
45
// -------------------------------------------------------------------------
46
// These will define the operator to work with tuples and lists from Python.
47
48
// base macro called by wrapping layers below for various operators, python
49
// types (lists and tuples), and special methods.
50
// The return type is deduced from _ArrayPyOpHelp<T>::op so that heterogeneous
51
// results work correctly (e.g. __sub__ on a TimeCode array returns a Duration
52
// array). Elements are extracted as T and the op result is stored in
53
// VtArray<RetElem>.
54
#define VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, isRightVer) \
55
template <typename T> static \
56
auto method##pytype(VtArray<T> vec, pytype obj) \
57
{ \
58
using RetElem = decltype( \
59
_ArrayPyOpHelp<T>:: op (std::declval<T>(), std::declval<T>())); \
60
size_t length = len(obj); \
61
if (length != vec.size()) { \
62
TfPyThrowValueError("Non-conforming inputs for operator " \
63
#method); \
64
return VtArray<RetElem>(); \
65
} \
66
VtArray<RetElem> ret(vec.size()); \
67
for (size_t i = 0; i < length; ++i) { \
68
if (!extract<T>(obj[i]).check()) \
69
TfPyThrowValueError("Element is of incorrect type."); \
70
if (isRightVer) { \
71
ret[i] = _ArrayPyOpHelp<T>:: op ( \
72
(T)extract<T>(obj[i]), vec[i]); \
73
} \
74
else { \
75
ret[i] = _ArrayPyOpHelp<T>:: op ( \
76
vec[i], (T)extract<T>(obj[i])); \
77
} \
78
} \
79
return ret; \
80
}
81
82
// wrap Array op pytype
83
#define VTOPERATOR_WRAP_PYTYPE(op, method, pytype) \
84
VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, false)
85
86
// wrap pytype op Array (for noncommutative ops like subtraction)
87
#define VTOPERATOR_WRAP_PYTYPE_R(op, method, pytype) \
88
VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, true)
89
90
91
// operator that needs a special method plus a reflected special method,
92
// each defined on tuples and lists
93
#define VTOPERATOR_WRAP(lmethod,rmethod) \
94
VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,tuple) \
95
VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,list) \
96
VTOPERATOR_WRAP_PYTYPE(lmethod,rmethod,tuple) \
97
VTOPERATOR_WRAP_PYTYPE(lmethod,rmethod,list)
98
99
// like above, but for non-commutative ops like subtraction
100
#define VTOPERATOR_WRAP_NONCOMM(lmethod,rmethod) \
101
VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,tuple) \
102
VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,list) \
103
VTOPERATOR_WRAP_PYTYPE_R(lmethod,rmethod,tuple) \
104
VTOPERATOR_WRAP_PYTYPE_R(lmethod,rmethod,list)
105
106
// to be used to actually declare the wrapping with def() on the class
107
#define VTOPERATOR_WRAPDECLARE_BASE(op,method,rettype) \
108
.def(self op self) \
109
.def(self op Type()) \
110
.def(Type() op self) \
111
.def(#method,method##tuple<rettype>) \
112
.def(#method,method##list<rettype>)
113
114
#define VTOPERATOR_WRAPDECLARE(op,lmethod,rmethod) \
115
VTOPERATOR_WRAPDECLARE_BASE(op,lmethod,Type) \
116
.def(#rmethod,rmethod##tuple<Type>) \
117
.def(#rmethod,rmethod##list<Type>)
118
119
// array OP pytype
120
// pytype OP array
121
#define VTOPERATOR_WRAP_PYTYPE_BOOL(func,pytype,op) \
122
VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
123
VtArray<T> const &vec, pytype const &obj, \
124
(vec[i] op (T)extract<T>(obj[i])) ) \
125
VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
126
pytype const &obj,VtArray<T> const &vec, \
127
((T)extract<T>(obj[i]) op vec[i]) )
128
129
#define VTOPERATOR_WRAP_BOOL(func,op) \
130
VTOPERATOR_WRAP_PYTYPE_BOOL(func,list,op) \
131
VTOPERATOR_WRAP_PYTYPE_BOOL(func,tuple,op)
132
133
134
PXR_NAMESPACE_CLOSE_SCOPE
135
136
#endif
// PXR_BASE_VT_PY_OPERATORS_H
pxr.h
pxr
base
vt
pyOperators.h
© Copyright 2026, Pixar Animation Studios. |
Terms of Use
| Generated on Tue Sep 8 2026 12:32:19 by
1.12.0