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