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