Loading...
Searching...
No Matches
pyOperators.h
1//
2// Copyright 2017 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24
25#include "pxr/pxr.h"
26#include "pxr/base/vt/api.h"
27
28PXR_NAMESPACE_OPEN_SCOPE
29
30namespace {
31template <class T>
32struct _ArrayPyOpHelp {
33 static T __add__(T l, T r) { return l + r; }
34 static T __sub__(T l, T r) { return l - r; }
35 static T __mul__(T l, T r) { return l * r; }
36 static T __div__(T l, T r) { return l / r; }
37 static T __mod__(T l, T r) { return l % r; }
38};
39
40// These operations on bool-arrays are highly questionable, but this preserves
41// existing behavior in the name of Hyrum's Law.
42template <>
43struct _ArrayPyOpHelp<bool> {
44 static bool __add__(bool l, bool r) { return l | r; }
45 static bool __sub__(bool l, bool r) { return l ^ r; }
46 static bool __mul__(bool l, bool r) { return l & r; }
47 static bool __div__(bool l, bool r) { return l; }
48 static bool __mod__(bool l, bool r) { return false; }
49};
50
51} // anon
52
53// -------------------------------------------------------------------------
54// Python operator definitions
55// -------------------------------------------------------------------------
56// These will define the operator to work with tuples and lists from Python.
57
58// base macro called by wrapping layers below for various operators, python
59// types (lists and tuples), and special methods
60#define VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, isRightVer) \
61 template <typename T> static \
62 VtArray<T> method##pytype(VtArray<T> vec, pytype obj) { \
63 size_t length = len(obj); \
64 if (length != vec.size()) { \
65 TfPyThrowValueError("Non-conforming inputs for operator " \
66 #method); \
67 return VtArray<T>(); \
68 } \
69 VtArray<T> ret(vec.size()); \
70 for (size_t i = 0; i < length; ++i) { \
71 if (!extract<T>(obj[i]).check()) \
72 TfPyThrowValueError("Element is of incorrect type."); \
73 if (isRightVer) { \
74 ret[i] = _ArrayPyOpHelp<T>:: op ( \
75 (T)extract<T>(obj[i]), vec[i]); \
76 } \
77 else { \
78 ret[i] = _ArrayPyOpHelp<T>:: op ( \
79 vec[i], (T)extract<T>(obj[i])); \
80 } \
81 } \
82 return ret; \
83 }
84
85// wrap Array op pytype
86#define VTOPERATOR_WRAP_PYTYPE(op, method, pytype) \
87 VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, false)
88
89// wrap pytype op Array (for noncommutative ops like subtraction)
90#define VTOPERATOR_WRAP_PYTYPE_R(op, method, pytype) \
91 VTOPERATOR_WRAP_PYTYPE_BASE(op, method, pytype, true)
92
93
94// operator that needs a special method plus a reflected special method,
95// each defined on tuples and lists
96#define VTOPERATOR_WRAP(lmethod,rmethod) \
97 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,tuple) \
98 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,list) \
99 VTOPERATOR_WRAP_PYTYPE(lmethod,rmethod,tuple) \
100 VTOPERATOR_WRAP_PYTYPE(lmethod,rmethod,list)
101
102// like above, but for non-commutative ops like subtraction
103#define VTOPERATOR_WRAP_NONCOMM(lmethod,rmethod) \
104 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,tuple) \
105 VTOPERATOR_WRAP_PYTYPE(lmethod,lmethod,list) \
106 VTOPERATOR_WRAP_PYTYPE_R(lmethod,rmethod,tuple) \
107 VTOPERATOR_WRAP_PYTYPE_R(lmethod,rmethod,list)
108
109// to be used to actually declare the wrapping with def() on the class
110#define VTOPERATOR_WRAPDECLARE_BASE(op,method,rettype) \
111 .def(self op self) \
112 .def(self op Type()) \
113 .def(Type() op self) \
114 .def(#method,method##tuple<rettype>) \
115 .def(#method,method##list<rettype>)
116
117#define VTOPERATOR_WRAPDECLARE(op,lmethod,rmethod) \
118 VTOPERATOR_WRAPDECLARE_BASE(op,lmethod,Type) \
119 .def(#rmethod,rmethod##tuple<Type>) \
120 .def(#rmethod,rmethod##list<Type>)
121
122// to be used for wrapping conditional functions that return bool arrays
123// (i.e. Equal, etc)
124#define VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func,arg1,arg2,expr) \
125 template <typename T> static \
126 VtArray<bool> Vt##func(arg1, arg2) \
127 { \
128 size_t length = len(obj); \
129 if (length != vec.size()) { \
130 TfPyThrowValueError("Non-conforming inputs for " #func); \
131 return VtArray<bool>(); \
132 } \
133 VtArray<bool> ret(vec.size()); \
134 for (size_t i = 0; i < length; ++i) { \
135 if (!extract<T>(obj[i]).check()) \
136 TfPyThrowValueError("Element is of incorrect type."); \
137 ret[i] = expr; \
138 } \
139 return ret; \
140 }
141
142// array OP pytype
143// pytype OP array
144#define VTOPERATOR_WRAP_PYTYPE_BOOL(func,pytype,op) \
145 VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
146 VtArray<T> const &vec, pytype const &obj, \
147 (vec[i] op (T)extract<T>(obj[i])) ) \
148 VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
149 pytype const &obj,VtArray<T> const &vec, \
150 ((T)extract<T>(obj[i]) op vec[i]) )
151
152#define VTOPERATOR_WRAP_BOOL(func,op) \
153 VTOPERATOR_WRAP_PYTYPE_BOOL(func,list,op) \
154 VTOPERATOR_WRAP_PYTYPE_BOOL(func,tuple,op)
155
156// to be used to actually declare the wrapping with def() on the class
157#define VTOPERATOR_WRAPDECLARE_BOOL(func) \
158 def(#func,(VtArray<bool> (*) \
159 (VtArray<Type> const &,VtArray<Type> const &)) \
160 Vt##func<Type>); \
161 def(#func,(VtArray<bool> (*) \
162 (Type const &,VtArray<Type> const &)) \
163 Vt##func<Type>); \
164 def(#func,(VtArray<bool> (*) \
165 (VtArray<Type> const &,Type const &)) \
166 Vt##func<Type>); \
167 def(#func,(VtArray<bool> (*) \
168 (VtArray<Type> const &,tuple const &)) \
169 Vt##func<Type>); \
170 def(#func,(VtArray<bool> (*) \
171 (tuple const &,VtArray<Type> const &)) \
172 Vt##func<Type>); \
173 def(#func,(VtArray<bool> (*) \
174 (VtArray<Type> const &,list const &)) \
175 Vt##func<Type>); \
176 def(#func,(VtArray<bool> (*) \
177 (list const &,VtArray<Type> const &)) \
178 Vt##func<Type>);
179
180PXR_NAMESPACE_CLOSE_SCOPE