All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
28 // See the description in vt/operators.h for a better understanding regarding
29 // the purpose and usage of macros defined below.
30 
31 PXR_NAMESPACE_OPEN_SCOPE
32 
33 // -------------------------------------------------------------------------
34 // Python operator definitions
35 // -------------------------------------------------------------------------
36 // These will define the operator to work with tuples and lists from Python.
37 
38 // base macro called by wrapping layers below for various operators, python
39 // types (lists and tuples), and special methods
40 #define VTOPERATOR_WRAP_PYTYPE_BASE(op,method,pytype,rettype,expr) \
41  template <typename T> static \
42  VtArray<rettype> method##pytype(VtArray<T> vec, pytype obj) \
43  { \
44  size_t length = len(obj); \
45  if (length != vec.size()) { \
46  TfPyThrowValueError("Non-conforming inputs for operator " #op); \
47  return VtArray<T>(); \
48  } \
49  VtArray<rettype> ret(vec.size()); \
50  for (size_t i = 0; i < length; ++i) { \
51  if (!extract<T>(obj[i]).check()) \
52  TfPyThrowValueError("Element is of incorrect type."); \
53  ret[i] = expr; \
54  } \
55  return ret; \
56  }
57 
58 // wrap Array op pytype
59 #define VTOPERATOR_WRAP_PYTYPE(op,lmethod,tuple,T) \
60  VTOPERATOR_WRAP_PYTYPE_BASE(op,lmethod,tuple,T, \
61  (vec[i] op (T)extract<T>(obj[i])) )
62 
63 // wrap pytype op Array (for noncommutative ops like subtraction)
64 #define VTOPERATOR_WRAP_PYTYPE_R(op,lmethod,tuple,T) \
65  VTOPERATOR_WRAP_PYTYPE_BASE(op,lmethod,tuple,T, \
66  ((T)extract<T>(obj[i]) op vec[i]) )
67 
68 
69 // operator that needs a special method plus a reflected special method,
70 // each defined on tuples and lists
71 #define VTOPERATOR_WRAP(op,lmethod,rmethod) \
72  VTOPERATOR_WRAP_PYTYPE(op,lmethod,tuple,T) \
73  VTOPERATOR_WRAP_PYTYPE(op,lmethod,list,T) \
74  VTOPERATOR_WRAP_PYTYPE(op,rmethod,tuple,T) \
75  VTOPERATOR_WRAP_PYTYPE(op,rmethod,list,T)
76 
77 // like above, but for non-commutative ops like subtraction
78 #define VTOPERATOR_WRAP_NONCOMM(op,lmethod,rmethod) \
79  VTOPERATOR_WRAP_PYTYPE(op,lmethod,tuple,T) \
80  VTOPERATOR_WRAP_PYTYPE(op,lmethod,list,T) \
81  VTOPERATOR_WRAP_PYTYPE_R(op,rmethod,tuple,T) \
82  VTOPERATOR_WRAP_PYTYPE_R(op,rmethod,list,T)
83 
84 // to be used to actually declare the wrapping with def() on the class
85 #define VTOPERATOR_WRAPDECLARE_BASE(op,method,rettype) \
86  .def(self op self) \
87  .def(self op Type()) \
88  .def(Type() op self) \
89  .def(#method,method##tuple<rettype>) \
90  .def(#method,method##list<rettype>)
91 
92 #define VTOPERATOR_WRAPDECLARE(op,lmethod,rmethod) \
93  VTOPERATOR_WRAPDECLARE_BASE(op,lmethod,Type) \
94  .def(#rmethod,rmethod##tuple<Type>) \
95  .def(#rmethod,rmethod##list<Type>)
96 
97 // to be used for wrapping conditional functions that return bool arrays
98 // (i.e. Equal, etc)
99 #define VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func,arg1,arg2,expr) \
100  template <typename T> static \
101  VtArray<bool> Vt##func(arg1, arg2) \
102  { \
103  size_t length = len(obj); \
104  if (length != vec.size()) { \
105  TfPyThrowValueError("Non-conforming inputs for " #func); \
106  return VtArray<bool>(); \
107  } \
108  VtArray<bool> ret(vec.size()); \
109  for (size_t i = 0; i < length; ++i) { \
110  if (!extract<T>(obj[i]).check()) \
111  TfPyThrowValueError("Element is of incorrect type."); \
112  ret[i] = expr; \
113  } \
114  return ret; \
115  }
116 
117 // array OP pytype
118 // pytype OP array
119 #define VTOPERATOR_WRAP_PYTYPE_BOOL(func,pytype,op) \
120  VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
121  VtArray<T> const &vec, pytype const &obj, \
122  (vec[i] op (T)extract<T>(obj[i])) ) \
123  VTOPERATOR_WRAP_PYTYPE_BOOL_BASE(func, \
124  pytype const &obj,VtArray<T> const &vec, \
125  ((T)extract<T>(obj[i]) op vec[i]) )
126 
127 #define VTOPERATOR_WRAP_BOOL(func,op) \
128  VTOPERATOR_WRAP_PYTYPE_BOOL(func,list,op) \
129  VTOPERATOR_WRAP_PYTYPE_BOOL(func,tuple,op)
130 
131 // to be used to actually declare the wrapping with def() on the class
132 #define VTOPERATOR_WRAPDECLARE_BOOL(func) \
133  def(#func,(VtArray<bool> (*) \
134  (VtArray<Type> const &,VtArray<Type> const &)) \
135  Vt##func<Type>); \
136  def(#func,(VtArray<bool> (*) \
137  (Type const &,VtArray<Type> const &)) \
138  Vt##func<Type>); \
139  def(#func,(VtArray<bool> (*) \
140  (VtArray<Type> const &,Type const &)) \
141  Vt##func<Type>); \
142  def(#func,(VtArray<bool> (*) \
143  (VtArray<Type> const &,tuple const &)) \
144  Vt##func<Type>); \
145  def(#func,(VtArray<bool> (*) \
146  (tuple const &,VtArray<Type> const &)) \
147  Vt##func<Type>); \
148  def(#func,(VtArray<bool> (*) \
149  (VtArray<Type> const &,list const &)) \
150  Vt##func<Type>); \
151  def(#func,(VtArray<bool> (*) \
152  (list const &,VtArray<Type> const &)) \
153  Vt##func<Type>);
154 
155 PXR_NAMESPACE_CLOSE_SCOPE