All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyChildrenView.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 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 #ifndef PXR_USD_SDF_PY_CHILDREN_VIEW_H
25 #define PXR_USD_SDF_PY_CHILDREN_VIEW_H
26 
28 
29 #include "pxr/pxr.h"
31 #include "pxr/base/arch/demangle.h"
32 #include "pxr/base/tf/pyUtils.h"
34 #include <boost/python.hpp>
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 template <class _View>
39 class SdfPyWrapChildrenView {
40 public:
41  typedef _View View;
42  typedef typename View::ChildPolicy ChildPolicy;
43  typedef typename View::Predicate Predicate;
44  typedef typename View::key_type key_type;
45  typedef typename View::value_type value_type;
46  typedef typename View::const_iterator const_iterator;
47  typedef SdfPyWrapChildrenView<View> This;
48 
49  SdfPyWrapChildrenView()
50  {
51  TfPyWrapOnce<View>(&This::_Wrap);
52  }
53 
54 private:
55  struct _ExtractItem {
56  static boost::python::object Get(const View& x, const const_iterator& i)
57  {
58  return boost::python::make_tuple(x.key(i), *i);
59  }
60  };
61 
62  struct _ExtractKey {
63  static boost::python::object Get(const View& x, const const_iterator& i)
64  {
65  return boost::python::object(x.key(i));
66  }
67  };
68 
69  struct _ExtractValue {
70  static boost::python::object Get(const View& x, const const_iterator& i)
71  {
72  return boost::python::object(*i);
73  }
74  };
75 
76  template <class E>
77  class _Iterator {
78  public:
79  _Iterator(const boost::python::object& object) :
80  _object(object),
81  _owner(boost::python::extract<const View&>(object)),
82  _cur(_owner.begin()),
83  _end(_owner.end())
84  {
85  // Do nothing
86  }
87 
88  _Iterator<E> GetCopy() const
89  {
90  return *this;
91  }
92 
93  boost::python::object GetNext()
94  {
95  if (_cur == _end) {
96  TfPyThrowStopIteration("End of ChildrenProxy iteration");
97  }
98  boost::python::object result = E::Get(_owner, _cur);
99  ++_cur;
100  return result;
101  }
102 
103  private:
104  boost::python::object _object;
105  const View& _owner;
106  const_iterator _cur;
107  const_iterator _end;
108  };
109 
110  static void _Wrap()
111  {
112  using namespace boost::python;
113 
114  std::string name = _GetName();
115 
116  // Note: Using the value iterator for the __iter__ method is not
117  // consistent with Python dicts (which iterate over keys).
118  // However, we're emulating TfPyKeyedVector, which iterates
119  // over values as a vector would.
120  scope thisScope =
121  class_<View>(name.c_str(), no_init)
122  .def("__repr__", &This::_GetRepr)
123  .def("__len__", &View::size)
124  .def("__getitem__", &This::_GetItemByKey)
125  .def("__getitem__", &This::_GetItemByIndex)
126  .def("get", &This::_PyGet)
127  .def("__contains__", &This::_HasKey)
128  .def("__contains__", &This::_HasValue)
129  .def("__iter__", &This::_GetValueIterator)
130 #if PY_MAJOR_VERSION < 3
131  .def("has_key", &This::_HasKey)
132  .def("itervalues", &This::_GetValueIterator)
133  .def("iterkeys", &This::_GetKeyIterator)
134  .def("iteritems", &This::_GetItemIterator)
135  .def("items", &This::_GetItems)
136  .def("keys", &This::_GetKeys)
137  .def("values", &This::_GetValues)
138 #else
139  .def("items", &This::_GetItemIterator)
140  .def("keys", &This::_GetKeyIterator)
141  .def("values", &This::_GetValueIterator)
142 #endif
143  .def("index", &This::_FindIndexByKey)
144  .def("index", &This::_FindIndexByValue)
145  .def(self == self)
146  .def(self != self)
147  ;
148 
149  class_<_Iterator<_ExtractItem> >
150  ((name + "_Iterator").c_str(), no_init)
151  .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
152  .def(TfPyIteratorNextMethodName, &This::template _Iterator<_ExtractItem>::GetNext)
153  ;
154 
155  class_<_Iterator<_ExtractKey> >
156  ((name + "_KeyIterator").c_str(), no_init)
157  .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
158  .def(TfPyIteratorNextMethodName, &This::template _Iterator<_ExtractKey>::GetNext)
159  ;
160 
161  class_<_Iterator<_ExtractValue> >
162  ((name + "_ValueIterator").c_str(), no_init)
163  .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
164  .def(TfPyIteratorNextMethodName, &This::template _Iterator<_ExtractValue>::GetNext)
165  ;
166  }
167 
168  static std::string _GetName()
169  {
170  std::string name = "ChildrenView_" +
171  ArchGetDemangled<ChildPolicy>() + "_" +
172  ArchGetDemangled<Predicate>();
173  name = TfStringReplace(name, " ", "_");
174  name = TfStringReplace(name, ",", "_");
175  name = TfStringReplace(name, "::", "_");
176  name = TfStringReplace(name, "<", "_");
177  name = TfStringReplace(name, ">", "_");
178  return name;
179  }
180 
181  static std::string _GetRepr(const View& x)
182  {
183  std::string result("{");
184  if (! x.empty()) {
185  const_iterator i = x.begin(), n = x.end();
186  result += TfPyRepr(x.key(i)) + ": " + TfPyRepr(*i);
187  while (++i != n) {
188  result += ", " + TfPyRepr(x.key(i)) + ": " + TfPyRepr(*i);
189  }
190  }
191  result += "}";
192  return result;
193  }
194 
195  static value_type _GetItemByKey(const View& x, const key_type& key)
196  {
197  const_iterator i = x.find(key);
198  if (i == x.end()) {
200  return value_type();
201  }
202  else {
203  return *i;
204  }
205  }
206 
207  static value_type _GetItemByIndex(const View& x, size_t index)
208  {
209  if (index >= x.size()) {
210  TfPyThrowIndexError("list index out of range");
211  }
212  return x[index];
213  }
214 
215  static boost::python::object _PyGet(const View& x, const key_type& key)
216  {
217  const_iterator i = x.find(key);
218  return i == x.end() ? boost::python::object() :
219  boost::python::object(*i);
220  }
221 
222  static bool _HasKey(const View& x, const key_type& key)
223  {
224  return x.find(key) != x.end();
225  }
226 
227  static bool _HasValue(const View& x, const value_type& value)
228  {
229  return x.find(value) != x.end();
230  }
231 
232  static
233  _Iterator<_ExtractItem> _GetItemIterator(const boost::python::object& x)
234  {
235  return _Iterator<_ExtractItem>(x);
236  }
237 
238  static
239  _Iterator<_ExtractKey> _GetKeyIterator(const boost::python::object& x)
240  {
241  return _Iterator<_ExtractKey>(x);
242  }
243 
244  static
245  _Iterator<_ExtractValue> _GetValueIterator(const boost::python::object& x)
246  {
247  return _Iterator<_ExtractValue>(x);
248  }
249 
250  template <class E>
251  static boost::python::list _Get(const View& x)
252  {
253  boost::python::list result;
254  for (const_iterator i = x.begin(), n = x.end(); i != n; ++i) {
255  result.append(E::Get(x, i));
256  }
257  return result;
258  }
259 
260 #if PY_MAJOR_VERSION < 3
261  static boost::python::list _GetItems(const View& x)
262  {
263  return _Get<_ExtractItem>(x);
264  }
265 
266  static boost::python::list _GetKeys(const View& x)
267  {
268  return _Get<_ExtractKey>(x);
269  }
270 
271  static boost::python::list _GetValues(const View& x)
272  {
273  return _Get<_ExtractValue>(x);
274  }
275 #endif
276 
277  static int _FindIndexByKey(const View& x, const key_type& key)
278  {
279  size_t i = std::distance(x.begin(), x.find(key));
280  return i == x.size() ? -1 : i;
281  }
282 
283  static int _FindIndexByValue(const View& x, const value_type& value)
284  {
285  size_t i = std::distance(x.begin(), x.find(value));
286  return i == x.size() ? -1 : i;
287  }
288 };
289 
290 PXR_NAMESPACE_CLOSE_SCOPE
291 
292 #endif // PXR_USD_SDF_PY_CHILDREN_VIEW_H
Definitions of basic string utilities in tf.
Miscellaneous Utilities for dealing with script.
TF_API void TfPyThrowIndexError(std::string const &msg)
Raises a python IndexError and throws a C++ exception.
Demangle C++ typenames generated by the typeid() facility.
std::string TfPyRepr(T const &t)
Return repr(t).
Definition: pyUtils.h:138
TF_API void TfPyThrowStopIteration(std::string const &msg)
Raises a python StopIteration exception and throws a C++ exception.
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
Replaces all occurrences of string from with to in source.