Loading...
Searching...
No Matches
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"
32#include "pxr/base/tf/pyUtils.h"
34#include <boost/python.hpp>
35
36PXR_NAMESPACE_OPEN_SCOPE
37
38template <class _View>
39class SdfPyWrapChildrenView {
40public:
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
54private:
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 .def("items", &This::_GetItemIterator)
131 .def("keys", &This::_GetKeyIterator)
132 .def("values", &This::_GetValueIterator)
133 .def("index", &This::_FindIndexByKey)
134 .def("index", &This::_FindIndexByValue)
135 .def(self == self)
136 .def(self != self)
137 ;
138
139 class_<_Iterator<_ExtractItem> >
140 ((name + "_Iterator").c_str(), no_init)
141 .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
142 .def("__next__", &This::template _Iterator<_ExtractItem>::GetNext)
143 ;
144
145 class_<_Iterator<_ExtractKey> >
146 ((name + "_KeyIterator").c_str(), no_init)
147 .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
148 .def("__next__", &This::template _Iterator<_ExtractKey>::GetNext)
149 ;
150
151 class_<_Iterator<_ExtractValue> >
152 ((name + "_ValueIterator").c_str(), no_init)
153 .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
154 .def("__next__", &This::template _Iterator<_ExtractValue>::GetNext)
155 ;
156 }
157
158 static std::string _GetName()
159 {
160 std::string name = "ChildrenView_" +
161 ArchGetDemangled<ChildPolicy>() + "_" +
162 ArchGetDemangled<Predicate>();
163 name = TfStringReplace(name, " ", "_");
164 name = TfStringReplace(name, ",", "_");
165 name = TfStringReplace(name, "::", "_");
166 name = TfStringReplace(name, "<", "_");
167 name = TfStringReplace(name, ">", "_");
168 return name;
169 }
170
171 static std::string _GetRepr(const View& x)
172 {
173 std::string result("{");
174 if (! x.empty()) {
175 const_iterator i = x.begin(), n = x.end();
176 result += TfPyRepr(x.key(i)) + ": " + TfPyRepr(*i);
177 while (++i != n) {
178 result += ", " + TfPyRepr(x.key(i)) + ": " + TfPyRepr(*i);
179 }
180 }
181 result += "}";
182 return result;
183 }
184
185 static value_type _GetItemByKey(const View& x, const key_type& key)
186 {
187 const_iterator i = x.find(key);
188 if (i == x.end()) {
190 return value_type();
191 }
192 else {
193 return *i;
194 }
195 }
196
197 static value_type _GetItemByIndex(const View& x, size_t index)
198 {
199 if (index >= x.size()) {
200 TfPyThrowIndexError("list index out of range");
201 }
202 return x[index];
203 }
204
205 static boost::python::object _PyGet(const View& x, const key_type& key)
206 {
207 const_iterator i = x.find(key);
208 return i == x.end() ? boost::python::object() :
209 boost::python::object(*i);
210 }
211
212 static bool _HasKey(const View& x, const key_type& key)
213 {
214 return x.find(key) != x.end();
215 }
216
217 static bool _HasValue(const View& x, const value_type& value)
218 {
219 return x.find(value) != x.end();
220 }
221
222 static
223 _Iterator<_ExtractItem> _GetItemIterator(const boost::python::object& x)
224 {
225 return _Iterator<_ExtractItem>(x);
226 }
227
228 static
229 _Iterator<_ExtractKey> _GetKeyIterator(const boost::python::object& x)
230 {
231 return _Iterator<_ExtractKey>(x);
232 }
233
234 static
235 _Iterator<_ExtractValue> _GetValueIterator(const boost::python::object& x)
236 {
237 return _Iterator<_ExtractValue>(x);
238 }
239
240 template <class E>
241 static boost::python::list _Get(const View& x)
242 {
243 boost::python::list result;
244 for (const_iterator i = x.begin(), n = x.end(); i != n; ++i) {
245 result.append(E::Get(x, i));
246 }
247 return result;
248 }
249
250 static int _FindIndexByKey(const View& x, const key_type& key)
251 {
252 size_t i = std::distance(x.begin(), x.find(key));
253 return i == x.size() ? -1 : i;
254 }
255
256 static int _FindIndexByValue(const View& x, const value_type& value)
257 {
258 size_t i = std::distance(x.begin(), x.find(value));
259 return i == x.size() ? -1 : i;
260 }
261};
262
263PXR_NAMESPACE_CLOSE_SCOPE
264
265#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 boost::python::error_already_set exc...
TF_API void TfPyThrowStopIteration(const char *msg)
Raises a Python StopIteration with the given error msg and throws a boost::python::error_already_set ...
std::string TfPyRepr(T const &t)
Return repr(t).
Definition: pyUtils.h:180
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.