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