HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyOperators.h
Go to the documentation of this file.
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 
29 
30 namespace {
31 template <class T>
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.
42 template <>
43 struct _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 
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GLboolean r
Definition: glcorearb.h:1222