Loading...
Searching...
No Matches
childrenProxy.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_CHILDREN_PROXY_H
8#define PXR_USD_SDF_CHILDREN_PROXY_H
9
11
12#include "pxr/pxr.h"
13#include "pxr/usd/sdf/api.h"
14#include "pxr/usd/sdf/changeBlock.h"
15#include "pxr/base/vt/value.h"
18
19#include <iterator>
20#include <map>
21#include <utility>
22
23PXR_NAMESPACE_OPEN_SCOPE
24
25template <class _View>
26class SdfChildrenProxy {
27public:
28 typedef _View View;
29 typedef typename View::Adapter Adapter;
30 typedef typename View::ChildPolicy ChildPolicy;
31 typedef typename View::key_type key_type;
32 typedef typename View::value_type mapped_type;
33 typedef std::vector<mapped_type> mapped_vector_type;
34 typedef std::pair<const key_type, mapped_type> value_type;
35 typedef std::map<key_type, mapped_type> map_type;
36 typedef typename View::size_type size_type;
37 typedef SdfChildrenProxy<View> This;
38
39private:
40 typedef typename View::const_iterator _inner_iterator;
41
42 class _ValueProxy {
43 public:
44 _ValueProxy() : _owner(NULL) { }
45 _ValueProxy(This* owner, _inner_iterator i) : _owner(owner), _pos(i)
46 {
47 // Do nothing
48 }
49
50 operator mapped_type() const
51 {
52 return *_pos;
53 }
54
55 bool operator==(const mapped_type& other) const
56 {
57 return *_pos == other;
58 }
59
60 private:
61 This* _owner;
62 _inner_iterator _pos;
63 };
64
65 class _PairProxy {
66 public:
67 explicit _PairProxy(This* owner, _inner_iterator i) :
68 first(owner->_view.key(i)), second(owner, i) { }
69
70 const key_type first;
71 _ValueProxy second;
72
73 operator value_type() const
74 {
75 return value_type(first, second);
76 }
77 };
78 friend class _PairProxy;
79
80 class _Traits {
81 public:
82 static value_type Dereference(const This* owner, _inner_iterator i)
83 {
84 return value_type(owner->_view.key(i), *i);
85 }
86
87 static _PairProxy Dereference(This* owner, _inner_iterator i)
88 {
89 return _PairProxy(owner, i);
90 }
91 };
92
93 template <class _Owner, class _Iter, class _Value>
94 class _Iterator {
95 class _PtrProxy {
96 public:
97 _Value* operator->() { return &_value; }
98 private:
99 friend class _Iterator;
100 explicit _PtrProxy(const _Value& value) : _value(value) {}
101 _Value _value;
102 };
103 public:
104 static_assert(!std::is_reference<_Value>::value &&
105 !std::is_pointer<_Value>::value,
106 "_Value cannot be a pointer or reference type.");
107 using iterator_category = std::bidirectional_iterator_tag;
108 using value_type = _Value;
109 using reference = _Value;
110 using pointer = _PtrProxy;
111 using difference_type = std::ptrdiff_t;
112
113 _Iterator() = default;
114 _Iterator(_Owner owner, _inner_iterator i) : _owner(owner), _pos(i) { }
115 template <class O2, class I2, class V2>
116 _Iterator(const _Iterator<O2, I2, V2>& other) :
117 _owner(other._owner), _pos(other._pos) { }
118
119 reference operator*() const { return dereference(); }
120 pointer operator->() const { return pointer(dereference()); }
121
122 _Iterator& operator++() {
123 increment();
124 return *this;
125 }
126
127 _Iterator& operator--() {
128 decrement();
129 return *this;
130 }
131
132 _Iterator operator++(int) {
133 _Iterator result(*this);
134 increment();
135 return result;
136 }
137
138 _Iterator operator--(int) {
139 _Iterator result(*this);
140 decrement();
141 return result;
142 }
143
144 template <class O2, class I2, class V2>
145 bool operator==(const _Iterator<O2, I2, V2>& other) const {
146 return equal(other);
147 }
148
149 template <class O2, class I2, class V2>
150 bool operator!=(const _Iterator<O2, I2, V2>& other) const {
151 return !equal(other);
152 }
153
154 private:
155 _Value dereference() const
156 {
157 return _Traits::Dereference(_owner, _pos);
158 }
159
160 template <class O2, class I2, class V2>
161 bool equal(const _Iterator<O2, I2, V2>& other) const
162 {
163 return _pos == other._pos;
164 }
165
166 void increment() {
167 ++_pos;
168 }
169
170 void decrement() {
171 --_pos;
172 }
173
174 private:
175 _Owner _owner;
176 _inner_iterator _pos;
177
178 template <class O2, class I2, class V2>
179 friend class _Iterator;
180 };
181
182public:
183 typedef _ValueProxy reference;
184 typedef _Iterator<This*, _inner_iterator, _PairProxy> iterator;
185 typedef Tf_ProxyReferenceReverseIterator<iterator> reverse_iterator;
186 typedef _Iterator<const This*, _inner_iterator, value_type> const_iterator;
187 typedef Tf_ProxyReferenceReverseIterator<const_iterator> const_reverse_iterator;
188
189 static const int CanSet = 1;
190 static const int CanInsert = 2;
191 static const int CanErase = 4;
192
193 SdfChildrenProxy(const View& view, const std::string& type,
194 int permission = CanSet | CanInsert | CanErase) :
195 _view(view), _type(type), _permission(permission)
196 {
197 // Do nothing
198 }
199
200 template <class U>
201 SdfChildrenProxy(const SdfChildrenProxy<U>& other) :
202 _view(other._view), _type(other._type), _permission(other._permission)
203 {
204 // Do nothing
205 }
206
207 This& operator=(const This& other)
208 {
209 if (other._Validate()) {
210 _Copy(other._view.values());
211 }
212 return *this;
213 }
214
215 template <class U>
216 This& operator=(const SdfChildrenProxy<U>& other)
217 {
218 if (other._Validate()) {
219 _Copy(other._view.values());
220 }
221 return *this;
222 }
223
224 This& operator=(const mapped_vector_type& values)
225 {
226 _Copy(values);
227 return *this;
228 }
229
230 operator mapped_vector_type() const
231 {
232 return _Validate() ? _view.values() : mapped_vector_type();
233 }
234
235 map_type items() const
236 {
237 return _Validate() ? _view.template items_as<map_type>() :map_type();
238 }
239
240 iterator begin()
241 {
242 return iterator(_GetThis(), _view.begin());
243 }
244 iterator end()
245 {
246 return iterator(_GetThis(), _view.end());
247 }
248 const_iterator begin() const
249 {
250 return const_iterator(_GetThis(), _view.begin());
251 }
252 const_iterator end() const
253 {
254 return const_iterator(_GetThis(), _view.end());
255 }
256
257 reverse_iterator rbegin()
258 {
259 return reverse_iterator(end());
260 }
261 reverse_iterator rend()
262 {
263 return reverse_iterator(begin());
264 }
265 const_reverse_iterator rbegin() const
266 {
267 return reverse_iterator(end());
268 }
269 const_reverse_iterator rend() const
270 {
271 return reverse_iterator(begin());
272 }
273
274 size_type size() const
275 {
276 return _Validate() ? _view.size() : 0;
277 }
278
279 size_type max_size() const
280 {
281 return _view.max_size();
282 }
283
284 bool empty() const
285 {
286 return _Validate() ? _view.empty() : true;
287 }
288
289 std::pair<iterator, bool> insert(const mapped_type& value)
290 {
291 if (_Validate(CanInsert)) {
292 iterator i = find(_view.key(value));
293 if (i == end()) {
294 if (_PrimInsert(value, size())) {
295 return std::make_pair(find(_view.key(value)), true);
296 }
297 else {
298 return std::make_pair(end(), false);
299 }
300 }
301 else {
302 return std::make_pair(i, false);
303 }
304 }
305 else {
306 return std::make_pair(iterator(), false);
307 }
308 }
309
310 iterator insert(iterator pos, const mapped_type& value)
311 {
312 return insert(value).first;
313 }
314
315 template <class InputIterator>
316 void insert(InputIterator first, InputIterator last)
317 {
318 if (_Validate(CanInsert)) {
319 SdfChangeBlock block;
320 for (; first != last; ++first) {
321 _PrimInsert(*first, size());
322 }
323 }
324 }
325
326 void erase(iterator pos)
327 {
328 _Erase(pos->first);
329 }
330
331 size_type erase(const key_type& key)
332 {
333 return _Erase(key) ? 1 : 0;
334 }
335
336 void erase(iterator first, iterator last)
337 {
338 if (_Validate(CanErase)) {
339 SdfChangeBlock block;
340 while (first != last) {
341 const key_type& key = first->first;
342 ++first;
343 _PrimErase(key);
344 }
345 }
346 }
347
348 void clear()
349 {
350 _Copy(mapped_vector_type());
351 }
352
353 iterator find(const key_type& key)
354 {
355 return _Validate() ? iterator(this, _view.find(key)) : iterator();
356 }
357
358 const_iterator find(const key_type& key) const
359 {
360 return _Validate() ? const_iterator(this, _view.find(key)) :
361 const_iterator();
362 }
363
364 size_type count(const key_type& key) const
365 {
366 return _Validate() ? _view.count(key) : 0;
367 }
368
369 bool operator==(const This& other) const
370 {
371 return _view == other._view;
372 }
373
374 bool operator!=(const This& other) const
375 {
376 return !(*this == other);
377 }
378
381 explicit operator bool() const
382 {
383 return _view.IsValid();
384 }
385
386private:
387 const std::string& _GetType() const
388 {
389 return _type;
390 }
391
392 int _GetPermission() const
393 {
394 return _permission;
395 }
396
397 This* _GetThis()
398 {
399 return _Validate() ? this : NULL;
400 }
401
402 const This* _GetThis() const
403 {
404 return _Validate() ? this : NULL;
405 }
406
407 bool _Validate() const
408 {
409 if (_view.IsValid()) {
410 return true;
411 }
412 else {
413 TF_CODING_ERROR("Accessing expired %s", _type.c_str());
414 return false;
415 }
416 }
417
418 bool _Validate(int permission)
419 {
420 if (!_Validate()) {
421 return false;
422 }
423 if ((_permission & permission) == permission) {
424 return true;
425 }
426 const char* op = "edit";
427 if (~_permission & permission & CanSet) {
428 op = "replace";
429 }
430 else if (~_permission & permission & CanInsert) {
431 op = "insert";
432 }
433 else if (~_permission & permission & CanErase) {
434 op = "remove";
435 }
436 TF_CODING_ERROR("Cannot %s %s", op, _type.c_str());
437 return false;
438 }
439
440 bool _Copy(const mapped_vector_type& values)
441 {
442 return _Validate(CanSet) ? _PrimCopy(values) : false;
443 }
444
445 bool _Insert(const mapped_type& value, size_t index)
446 {
447 return _Validate(CanInsert) ? _PrimInsert(value, index) : false;
448 }
449
450 bool _Erase(const key_type& key)
451 {
452 return _Validate(CanErase) ? _PrimErase(key) : false;
453 }
454
455 bool _PrimCopy(const mapped_vector_type& values)
456 {
457 typedef std::vector<typename ChildPolicy::ValueType>
458 ChildrenValueVector;
459
460 ChildrenValueVector v;
461 for (size_t i = 0; i < values.size(); ++i)
462 v.push_back(Adapter::Convert(values[i]));
463
464 return _view.GetChildren().Copy(v, _type);
465 }
466
467 bool _PrimInsert(const mapped_type& value, size_t index)
468 {
469 return _view.GetChildren().Insert(
470 Adapter::Convert(value), index, _type);
471 }
472
473 bool _PrimErase(const key_type& key)
474 {
475 return _view.GetChildren().Erase(key, _type);
476 }
477
478private:
479 View _view;
480 std::string _type;
481 int _permission;
482
483 template <class V> friend class SdfChildrenProxy;
484 template <class V> friend class SdfPyChildrenProxy;
485};
486
487// Allow TfIteration over children proxies.
488template <typename _View>
489struct Tf_ShouldIterateOverCopy<SdfChildrenProxy<_View> > : std::true_type
490{
491};
492
493// Cannot get from a VtValue except as the correct type.
494template <class _View>
495struct Vt_DefaultValueFactory<SdfChildrenProxy<_View> > {
496 static Vt_DefaultValueHolder Invoke() = delete;
497};
498
499PXR_NAMESPACE_CLOSE_SCOPE
500
501#endif // PXR_USD_SDF_CHILDREN_PROXY_H
Low-level utilities for informing users of various internal and external diagnostic conditions.
A simple iterator adapter for STL containers.
DANGER DANGER DANGER
Definition: changeBlock.h:56
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:68