HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyMapEditProxy.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
8 #define PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
9 
10 /// \file sdf/pyMapEditProxy.h
11 
12 #include "pxr/pxr.h"
14 #include "pxr/base/arch/demangle.h"
15 #include "pxr/base/tf/iterator.h"
16 #include "pxr/base/tf/pyUtils.h"
18 #include "pxr/external/boost/python.hpp"
19 
21 
22 template <class T>
24 public:
25  typedef T Type;
26  typedef typename Type::key_type key_type;
27  typedef typename Type::mapped_type mapped_type;
28  typedef typename Type::value_type value_type;
29  typedef typename Type::iterator iterator;
30  typedef typename Type::const_iterator const_iterator;
32 
34  {
35  TfPyWrapOnce<Type>(&This::_Wrap);
36  }
37 
38 private:
39  typedef std::pair<key_type, mapped_type> pair_type;
40 
41  struct _ExtractItem {
42  static pxr_boost::python::object Get(const const_iterator& i)
43  {
44  return pxr_boost::python::make_tuple(i->first, i->second);
45  }
46  };
47 
48  struct _ExtractKey {
49  static pxr_boost::python::object Get(const const_iterator& i)
50  {
51  return pxr_boost::python::object(i->first);
52  }
53  };
54 
55  struct _ExtractValue {
56  static pxr_boost::python::object Get(const const_iterator& i)
57  {
58  return pxr_boost::python::object(i->second);
59  }
60  };
61 
62  template <class E>
63  class _Iterator {
64  public:
65  _Iterator(const pxr_boost::python::object& object) :
66  _object(object),
67  _owner(pxr_boost::python::extract<const Type&>(object)),
68  _cur(_owner.begin()),
69  _end(_owner.end())
70  {
71  // Do nothing
72  }
73 
74  _Iterator<E> GetCopy() const
75  {
76  return *this;
77  }
78 
80  {
81  if (_cur == _end) {
82  TfPyThrowStopIteration("End of MapEditProxy iteration");
83  }
84  pxr_boost::python::object result = E::Get(_cur);
85  ++_cur;
86  return result;
87  }
88 
89  private:
91  const Type& _owner;
92  const_iterator _cur;
93  const_iterator _end;
94  };
95 
96  static void _Wrap()
97  {
98  using namespace pxr_boost::python;
99 
100  std::string name = _GetName();
101 
102  scope thisScope =
103  class_<Type>(name.c_str())
104  .def("__repr__", &This::_GetRepr)
105  .def("__str__", &This::_GetStr)
106  .def("__len__", &Type::size)
107  .def("__getitem__", &This::_GetItem)
108  .def("__setitem__", &This::_SetItem)
109  .def("__delitem__", &This::_DelItem)
110  .def("__contains__", &This::_HasKey)
111  .def("__iter__", &This::_GetKeyIterator)
112  .def("values", &This::_GetValueIterator)
113  .def("keys", &This::_GetKeyIterator)
114  .def("items", &This::_GetItemIterator)
115  .def("clear", &Type::clear)
116  .def("get", &This::_PyGet)
117  .def("get", &This::_PyGetDefault)
118  .def("pop", &This::_Pop)
119  .def("popitem", &This::_PopItem)
120  .def("setdefault", &This::_SetDefault)
121  .def("update", &This::_UpdateDict)
122  .def("update", &This::_UpdateList)
123  .def("copy", &This::_Copy)
124  .add_property("expired", &Type::IsExpired)
125  .def("__bool__", &This::_IsValid)
126  .def(self == self)
127  .def(self != self)
128  ;
129 
130  class_<_Iterator<_ExtractItem> >
131  ((name + "_Iterator").c_str(), no_init)
132  .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
133  .def("__next__", &This::template _Iterator<_ExtractItem>::GetNext)
134  ;
135 
136  class_<_Iterator<_ExtractKey> >
137  ((name + "_KeyIterator").c_str(), no_init)
138  .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
139  .def("__next__", &This::template _Iterator<_ExtractKey>::GetNext)
140  ;
141 
142  class_<_Iterator<_ExtractValue> >
143  ((name + "_ValueIterator").c_str(), no_init)
144  .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
145  .def("__next__", &This::template _Iterator<_ExtractValue>::GetNext)
146  ;
147  }
148 
149  static std::string _GetName()
150  {
151  std::string name = "MapEditProxy_" +
152  ArchGetDemangled<typename Type::Type>();
153  name = TfStringReplace(name, " ", "_");
154  name = TfStringReplace(name, ",", "_");
155  name = TfStringReplace(name, "::", "_");
156  name = TfStringReplace(name, "<", "_");
157  name = TfStringReplace(name, ">", "_");
158  return name;
159  }
160 
161  static std::string _GetRepr(const Type& x)
162  {
163  std::string arg;
164  if (x) {
165  arg = TfStringPrintf("<%s>", x._Location().c_str());
166  }
167  else {
168  arg = "<invalid>";
169  }
170  return TF_PY_REPR_PREFIX + _GetName() + "(" + arg + ")";
171  }
172 
173  static std::string _GetStr(const Type& x)
174  {
175  std::string result("{");
176  if (x && ! x.empty()) {
177  const_iterator i = x.begin(), n = x.end();
178  result += TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
179  while (++i != n) {
180  result +=", " + TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
181  }
182  }
183  result += "}";
184  return result;
185  }
186 
187  static mapped_type _GetItem(const Type& x, const key_type& key)
188  {
189  const_iterator i = x.find(key);
190  if (i == x.end()) {
192  return mapped_type();
193  }
194  else {
195  return i->second;
196  }
197  }
198 
199  static void _SetItem(Type& x, const key_type& key, const mapped_type& value)
200  {
201  std::pair<typename Type::iterator, bool> i =
202  x.insert(value_type(key, value));
203  if (! i.second && i.first != typename Type::iterator()) {
204  i.first->second = value;
205  }
206  }
207 
208  static void _DelItem(Type& x, const key_type& key)
209  {
210  x.erase(key);
211  }
212 
213  static bool _HasKey(const Type& x, const key_type& key)
214  {
215  return x.count(key) != 0;
216  }
217 
218  static _Iterator<_ExtractItem>
219  _GetItemIterator(const pxr_boost::python::object& x)
220  {
221  return _Iterator<_ExtractItem>(x);
222  }
223 
224  static _Iterator<_ExtractKey>
225  _GetKeyIterator(const pxr_boost::python::object& x)
226  {
227  return _Iterator<_ExtractKey>(x);
228  }
229 
230  static _Iterator<_ExtractValue>
231  _GetValueIterator(const pxr_boost::python::object& x)
232  {
233  return _Iterator<_ExtractValue>(x);
234  }
235 
236  static pxr_boost::python::object _PyGet(const Type& x, const key_type& key)
237  {
238  const_iterator i = x.find(key);
239  return i == x.end() ? pxr_boost::python::object() :
240  pxr_boost::python::object(i->second);
241  }
242 
243  static mapped_type _PyGetDefault(const Type& x, const key_type& key,
244  const mapped_type& def)
245  {
246  const_iterator i = x.find(key);
247  return i == x.end() ? def : i->second;
248  }
249 
250  template <class E>
251  static pxr_boost::python::list _Get(const Type& x)
252  {
253  pxr_boost::python::list result;
254  for (const_iterator i = x.begin(), n = x.end(); i != n; ++i) {
255  result.append(E::Get(i));
256  }
257  return result;
258  }
259 
260  static mapped_type _Pop(Type& x, const key_type& key)
261  {
262  iterator i = x.find(key);
263  if (i == x.end()) {
265  return mapped_type();
266  }
267  else {
268  mapped_type result = i->second;
269  x.erase(i);
270  return result;
271  }
272  }
273 
274  static pxr_boost::python::tuple _PopItem(Type& x)
275  {
276  if (x.empty()) {
277  TfPyThrowKeyError("MapEditProxy is empty");
278  return pxr_boost::python::tuple();
279  }
280  else {
281  iterator i = x.begin();
282  value_type result = *i;
283  x.erase(i);
284  return pxr_boost::python::make_tuple(result.first, result.second);
285  }
286  }
287 
288  static mapped_type _SetDefault(Type& x, const key_type& key,
289  const mapped_type& def)
290  {
291  const_iterator i = x.find(key);
292  if (i != x.end()) {
293  return i->second;
294  }
295  else {
296  return x[key] = def;
297  }
298  }
299 
300  static void _Update(Type& x, const std::vector<pair_type>& values)
301  {
302  SdfChangeBlock block;
303  TF_FOR_ALL(i, values) {
304  x[i->first] = i->second;
305  }
306  }
307 
308  static void _UpdateDict(Type& x, const pxr_boost::python::dict& d)
309  {
310  _UpdateList(x, d.items());
311  }
312 
313  static void _UpdateList(Type& x, const pxr_boost::python::list& pairs)
314  {
315  using namespace pxr_boost::python;
316 
317  std::vector<pair_type> values;
318  for (int i = 0, n = len(pairs); i != n; ++i) {
319  values.push_back(pair_type(
320  extract<key_type>(pairs[i][0])(),
321  extract<mapped_type>(pairs[i][1])()));
322  }
323  _Update(x, values);
324  }
325 
326  static void _Copy(Type& x, const typename Type::Type& other)
327  {
328  x = other;
329  }
330 
331  static bool _IsValid(const Type& x)
332  {
333  return static_cast<bool>(x);
334  }
335 };
336 
338 
339 #endif // PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
TF_API std::string TfStringPrintf(const char *fmt,...)
Type::mapped_type mapped_type
SdfPyWrapMapEditProxy< Type > This
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Type::key_type key_type
TF_API void TfPyThrowStopIteration(const char *msg)
**But if you need a result
Definition: thread.h:622
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1859
uint64 value_type
Definition: GA_PrimCompat.h:29
std::string TfPyRepr(T const &t)
Definition: pyUtils.h:163
OIIO_FORCEINLINE bool extract(const vbool4 &a)
Definition: simd.h:3542
GLdouble n
Definition: glcorearb.h:2008
Type::iterator iterator
GLuint GLuint end
Definition: glcorearb.h:475
GLuint const GLchar * name
Definition: glcorearb.h:786
GLint GLenum GLint x
Definition: glcorearb.h:409
GLsizeiptr size
Definition: glcorearb.h:664
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
Type::const_iterator const_iterator
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
TF_API void TfPyThrowKeyError(const char *msg)
OIIO_UTIL_API const char * c_str(string_view str)
#define TF_FOR_ALL(iter, c)
Definition: iterator.h:373
#define TF_PY_REPR_PREFIX
Definition: pyUtils.h:42
Type::value_type value_type
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:566