Loading...
Searching...
No Matches
pyChildrenView.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_CHILDREN_VIEW_H
8#define PXR_USD_SDF_PY_CHILDREN_VIEW_H
9
11
12#include "pxr/pxr.h"
15#include "pxr/base/tf/pyUtils.h"
17#include "pxr/external/boost/python.hpp"
18
19PXR_NAMESPACE_OPEN_SCOPE
20
21template <class _View>
22class SdfPyWrapChildrenView {
23public:
24 typedef _View View;
25 typedef typename View::ChildPolicy ChildPolicy;
26 typedef typename View::Predicate Predicate;
27 typedef typename View::key_type key_type;
28 typedef typename View::value_type value_type;
29 typedef typename View::const_iterator const_iterator;
30 typedef SdfPyWrapChildrenView<View> This;
31
32 SdfPyWrapChildrenView()
33 {
34 TfPyWrapOnce<View>(&This::_Wrap);
35 }
36
37private:
38 struct _ExtractItem {
39 static pxr_boost::python::object Get(const View& x, const const_iterator& i)
40 {
41 return pxr_boost::python::make_tuple(x.key(i), *i);
42 }
43 };
44
45 struct _ExtractKey {
46 static pxr_boost::python::object Get(const View& x, const const_iterator& i)
47 {
48 return pxr_boost::python::object(x.key(i));
49 }
50 };
51
52 struct _ExtractValue {
53 static pxr_boost::python::object Get(const View& x, const const_iterator& i)
54 {
55 return pxr_boost::python::object(*i);
56 }
57 };
58
59 template <class E>
60 class _Iterator {
61 public:
62 _Iterator(const pxr_boost::python::object& object) :
63 _object(object),
64 _owner(pxr_boost::python::extract<const View&>(object)),
65 _cur(_owner.begin()),
66 _end(_owner.end())
67 {
68 // Do nothing
69 }
70
71 _Iterator<E> GetCopy() const
72 {
73 return *this;
74 }
75
76 pxr_boost::python::object GetNext()
77 {
78 if (_cur == _end) {
79 TfPyThrowStopIteration("End of ChildrenProxy iteration");
80 }
81 pxr_boost::python::object result = E::Get(_owner, _cur);
82 ++_cur;
83 return result;
84 }
85
86 private:
87 pxr_boost::python::object _object;
88 const View& _owner;
89 const_iterator _cur;
90 const_iterator _end;
91 };
92
93 static void _Wrap()
94 {
95 using namespace pxr_boost::python;
96
97 std::string name = _GetName();
98
99 // Note: Using the value iterator for the __iter__ method is not
100 // consistent with Python dicts (which iterate over keys).
101 // However, we're emulating TfPyKeyedVector, which iterates
102 // over values as a vector would.
103 scope thisScope =
104 class_<View>(name.c_str(), no_init)
105 .def("__repr__", &This::_GetRepr)
106 .def("__len__", &View::size)
107 .def("__getitem__", &This::_GetItemByKey)
108 .def("__getitem__", &This::_GetItemByIndex)
109 .def("get", &This::_PyGet)
110 .def("__contains__", &This::_HasKey)
111 .def("__contains__", &This::_HasValue)
112 .def("__iter__", &This::_GetValueIterator)
113 .def("items", &This::_GetItemIterator)
114 .def("keys", &This::_GetKeyIterator)
115 .def("values", &This::_GetValueIterator)
116 .def("index", &This::_FindIndexByKey)
117 .def("index", &This::_FindIndexByValue)
118 .def(self == self)
119 .def(self != self)
120 ;
121
122 class_<_Iterator<_ExtractItem> >
123 ((name + "_Iterator").c_str(), no_init)
124 .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
125 .def("__next__", &This::template _Iterator<_ExtractItem>::GetNext)
126 ;
127
128 class_<_Iterator<_ExtractKey> >
129 ((name + "_KeyIterator").c_str(), no_init)
130 .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
131 .def("__next__", &This::template _Iterator<_ExtractKey>::GetNext)
132 ;
133
134 class_<_Iterator<_ExtractValue> >
135 ((name + "_ValueIterator").c_str(), no_init)
136 .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
137 .def("__next__", &This::template _Iterator<_ExtractValue>::GetNext)
138 ;
139 }
140
141 static std::string _GetName()
142 {
143 std::string name = "ChildrenView_" +
144 ArchGetDemangled<ChildPolicy>() + "_" +
145 ArchGetDemangled<Predicate>();
146 name = TfStringReplace(name, " ", "_");
147 name = TfStringReplace(name, ",", "_");
148 name = TfStringReplace(name, "::", "_");
149 name = TfStringReplace(name, "<", "_");
150 name = TfStringReplace(name, ">", "_");
151 return name;
152 }
153
154 static std::string _GetRepr(const View& x)
155 {
156 std::string result("{");
157 if (! x.empty()) {
158 const_iterator i = x.begin(), n = x.end();
159 result += TfPyRepr(x.key(i)) + ": " + TfPyRepr(*i);
160 while (++i != n) {
161 result += ", " + TfPyRepr(x.key(i)) + ": " + TfPyRepr(*i);
162 }
163 }
164 result += "}";
165 return result;
166 }
167
168 static value_type _GetItemByKey(const View& x, const key_type& key)
169 {
170 const_iterator i = x.find(key);
171 if (i == x.end()) {
173 return value_type();
174 }
175 else {
176 return *i;
177 }
178 }
179
180 static value_type _GetItemByIndex(const View& x, size_t index)
181 {
182 if (index >= x.size()) {
183 TfPyThrowIndexError("list index out of range");
184 }
185 return x[index];
186 }
187
188 static pxr_boost::python::object _PyGet(const View& x, const key_type& key)
189 {
190 const_iterator i = x.find(key);
191 return i == x.end() ? pxr_boost::python::object() :
192 pxr_boost::python::object(*i);
193 }
194
195 static bool _HasKey(const View& x, const key_type& key)
196 {
197 return x.find(key) != x.end();
198 }
199
200 static bool _HasValue(const View& x, const value_type& value)
201 {
202 return x.find(value) != x.end();
203 }
204
205 static
206 _Iterator<_ExtractItem> _GetItemIterator(const pxr_boost::python::object& x)
207 {
208 return _Iterator<_ExtractItem>(x);
209 }
210
211 static
212 _Iterator<_ExtractKey> _GetKeyIterator(const pxr_boost::python::object& x)
213 {
214 return _Iterator<_ExtractKey>(x);
215 }
216
217 static
218 _Iterator<_ExtractValue> _GetValueIterator(const pxr_boost::python::object& x)
219 {
220 return _Iterator<_ExtractValue>(x);
221 }
222
223 template <class E>
224 static pxr_boost::python::list _Get(const View& x)
225 {
226 pxr_boost::python::list result;
227 for (const_iterator i = x.begin(), n = x.end(); i != n; ++i) {
228 result.append(E::Get(x, i));
229 }
230 return result;
231 }
232
233 static int _FindIndexByKey(const View& x, const key_type& key)
234 {
235 size_t i = std::distance(x.begin(), x.find(key));
236 return i == x.size() ? -1 : i;
237 }
238
239 static int _FindIndexByValue(const View& x, const value_type& value)
240 {
241 size_t i = std::distance(x.begin(), x.find(value));
242 return i == x.size() ? -1 : i;
243 }
244};
245
246PXR_NAMESPACE_CLOSE_SCOPE
247
248#endif // PXR_USD_SDF_PY_CHILDREN_VIEW_H
Miscellaneous Utilities for dealing with script.
TF_API void TfPyThrowIndexError(const char *msg)
Raises a Python IndexError with the given error msg and throws a pxr_boost::python::error_already_set...
TF_API void TfPyThrowStopIteration(const char *msg)
Raises a Python StopIteration with the given error msg and throws a pxr_boost::python::error_already_...
std::string TfPyRepr(T const &t)
Return repr(t).
Definition: pyUtils.h:163
Demangle C++ typenames generated by the typeid() facility.
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.
Definitions of basic string utilities in tf.