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
14PXR_NAMESPACE_OPEN_SCOPE
15
16namespace {
17template <class T>
18struct _ArrayPyOpHelp {
19 static T __add__(T l, T r) { return l + r; }
20 static T __sub__(T l, T r) { return l - r; }
21 static T __mul__(T l, T r) { return l * r; }
22 static T __div__(T l, T r) { return l / r; }
23 static T __mod__(T l, T r) { return l % r; }
24};
25
26// These operations on bool-arrays are highly questionable, but this preserves
27// existing behavior in the name of Hyrum's Law.
28template <>
29struct _ArrayPyOpHelp<bool> {
30 static bool __add__(bool l, bool r) { return l | r; }
31 static bool __sub__(bool l, bool r) { return l ^ r; }
32 static bool __mul__(bool l, bool r) { return l & r; }
33 static bool __div__(bool l, bool r) { return l; }
34 static bool __mod__(bool l, bool r) { return false; }
35};
36
37} // anon
38
39// -------------------------------------------------------------------------
40// Python operator definitions
41// -------------------------------------------------------------------------
42// These will define the operator to work with tuples and lists from Python.
43
44// base macro called by wrapping layers below for various operators, python
45// types (lists and tuples), and special methods
46#define VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, isRightVer) \
47 template <typename T> static \
48 VtArray<T> method##pytype(VtArray<T> vec, pytype obj) { \
49 size_t length = len(obj); \
50 if (length != vec.size()) { \
51 TfPyThrowValueError("Non-conforming inputs for operator " \
52 #method); \
53 return VtArray<T>(); \
54 } \
55 VtArray<T> ret(vec.size()); \
56 for (size_t i = 0; i < length; ++i) { \
57 if (!extract<T>(obj[i]).check()) \
58 TfPyThrowValueError("Element is of incorrect type."); \
59 if (isRightVer) { \
60 ret[i] = _ArrayPyOpHelp<T>:: op ( \
61 (T)extract<T>(obj[i]), vec[i]); \
62 } \
63 else { \
64 ret[i] = _ArrayPyOpHelp<T>:: op ( \
65 vec[i], (T)extract<T>(obj[i])); \
66 } \
67 } \
68 return ret; \
69 }
70
71// wrap Array op pytype
72#define VTOPERATOR_WRAP_PYTYPE(op, method, pytype) \
73 VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, false)
74
75// wrap pytype op Array (for noncommutative ops like subtraction)
76#define VTOPERATOR_WRAP_PYTYPE_R(op, method, pytype) \
77 VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, true)
78
79
80// operator that needs a special method plus a reflected special method,
81// each defined on tuples and lists
82#define VTOPERATOR_WRAP(lmethod,rmethod) \
83 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,tuple) \
84 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,list) \
85 VTOPERATOR_WRAP_PYTYPE(lmethod,rmethod,tuple) \
86 VTOPERATOR_WRAP_PYTYPE(lmethod,rmethod,list)
87
88// like above, but for non-commutative ops like subtraction
89#define VTOPERATOR_WRAP_NONCOMM(lmethod,rmethod) \
90 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,tuple) \
91 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,list) \
92 VTOPERATOR_WRAP_PYTYPE_R(lmethod,rmethod,tuple) \
93 VTOPERATOR_WRAP_PYTYPE_R(lmethod,rmethod,list)
94
95// to be used to actually declare the wrapping with def() on the class
96#define VTOPERATOR_WRAPDECLARE_BASE(op,method,rettype) \
97 .def(self op self) \
98 .def(self op Type()) \
99 .def(Type() op self) \
100 .def(#method,method##tuple<rettype>) \
101 .def(#method,method##list<rettype>)
102
103#define VTOPERATOR_WRAPDECLARE(op,lmethod,rmethod) \
104 VTOPERATOR_WRAPDECLARE_BASE(op,lmethod,Type) \
105 .def(#rmethod,rmethod##tuple<Type>) \
106 .def(#rmethod,rmethod##list<Type>)
107
108// array OP pytype
109// pytype OP array
110#define VTOPERATOR_WRAP_PYTYPE_BOOL(func,pytype,op) \
111 VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
112 VtArray<T> const &vec, pytype const &obj, \
113 (vec[i] op (T)extract<T>(obj[i])) ) \
114 VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
115 pytype const &obj,VtArray<T> const &vec, \
116 ((T)extract<T>(obj[i]) op vec[i]) )
117
118#define VTOPERATOR_WRAP_BOOL(func,op) \
119 VTOPERATOR_WRAP_PYTYPE_BOOL(func,list,op) \
120 VTOPERATOR_WRAP_PYTYPE_BOOL(func,tuple,op)
121
122
123PXR_NAMESPACE_CLOSE_SCOPE
124
125#endif // PXR_BASE_VT_PY_OPERATORS_H