Loading...
Searching...
No Matches
childrenView.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_VIEW_H
25#define PXR_USD_SDF_CHILDREN_VIEW_H
26
28
29#include "pxr/pxr.h"
30#include "pxr/usd/sdf/api.h"
31#include "pxr/usd/sdf/children.h"
33
34#include <algorithm>
35#include <vector>
36
37PXR_NAMESPACE_OPEN_SCOPE
38
47template <class T>
49public:
50 bool operator()(const T& x) const { return true; }
51};
52
57template <class T>
59public:
60 typedef T PrivateType;
61 typedef T PublicType;
62 static const PublicType& Convert(const PrivateType& t) { return t; }
63};
64
72template <typename _Owner, typename _InnerIterator, typename _DummyPredicate>
73class Sdf_ChildrenViewTraits {
74private:
75
76 // Owner's predicate object will be used by the filter iterator.
77 // In C++20, consider using the ranges library to simplify this
78 class _FilterIterator {
79 public:
80 using iterator_category = std::forward_iterator_tag;
81 using value_type = typename _InnerIterator::value_type;
82 using reference = typename _InnerIterator::reference;
83 using pointer = typename _InnerIterator::pointer;
84 using difference_type = typename _InnerIterator::difference_type;
85
86 _FilterIterator() = default;
87 _FilterIterator(const _Owner* owner,
88 const _InnerIterator& underlyingIterator,
89 const _InnerIterator& end) :
90 _owner(owner),
91 _underlyingIterator(underlyingIterator),
92 _end(end) {
93 _Filter();
94 }
95
96 reference operator*() const {
97 return *_underlyingIterator;
98 }
99
100 pointer operator->() const {
101 return _underlyingIterator.operator->();
102 }
103
104 _FilterIterator& operator++() {
105 TF_DEV_AXIOM(_underlyingIterator != _end);
106 ++_underlyingIterator;
107 _Filter();
108 return *this;
109 }
110
111 _FilterIterator operator++(int) {
112 TF_DEV_AXIOM(_underlyingIterator != _end);
113 _FilterIterator result(*this);
114 ++_underlyingIterator;
115 _Filter();
116 return result;
117 }
118
119 bool operator==(const _FilterIterator& other) const {
120 return _underlyingIterator == other._underlyingIterator;
121 }
122
123 bool operator!=(const _FilterIterator& other) const {
124 return _underlyingIterator != other._underlyingIterator;
125 }
126
127 const _InnerIterator& GetBase() const { return _underlyingIterator; }
128
129 private:
130 // Skip any iterators that don't satisfy the predicate
131 bool _ShouldFilter(const value_type& x) const
132 {
133 return !_owner->GetPredicate()(
134 _Owner::Adapter::Convert(x));
135 }
136
137 void _Filter()
138 {
139 while (_underlyingIterator != _end &&
140 _ShouldFilter(*_underlyingIterator)) {
141 ++_underlyingIterator;
142 }
143 }
144
145 const _Owner* _owner = nullptr;
146 _InnerIterator _underlyingIterator;
147 _InnerIterator _end;
148 };
149
150public:
151 using const_iterator = _FilterIterator;
152
153 // Convert from a private _InnerIterator to a public const_iterator.
154 // filter_iterator requires an end iterator, which is constructed using
155 // size.
156 static const_iterator GetIterator(const _Owner* owner,
157 const _InnerIterator& i,
158 size_t size)
159 {
160 _InnerIterator end(owner,size);
161 return const_iterator(owner, i, end);
162 }
163
164 // Convert from a public const_iterator to a private _InnerIterator.
165 static const _InnerIterator& GetBase(const const_iterator& i)
166 {
167 return i.GetBase();
168 }
169};
170
171// Children view traits specialization for trivial predicates. This
172// eliminates the predicate altogether and defines the public iterator type
173// to be the same as the inner iterator type.
174template <typename _Owner, typename _InnerIterator>
175class Sdf_ChildrenViewTraits<_Owner, _InnerIterator,
176 SdfChildrenViewTrivialPredicate<typename _Owner::ChildPolicy::ValueType> > {
177private:
178
179public:
180 typedef _InnerIterator const_iterator;
181
182 static const const_iterator& GetIterator(const _Owner*,
183 const _InnerIterator& i, size_t size)
184 {
185 return i;
186 }
187
188 static const _InnerIterator& GetBase(const const_iterator& i)
189 {
190 return i;
191 }
192};
193
215template <typename _ChildPolicy,
216 typename _Predicate =
218 typename _ChildPolicy::ValueType>,
219 typename _Adapter =
221 typename _ChildPolicy::ValueType> >
223public:
225
226 typedef _Adapter Adapter;
227 typedef _Predicate Predicate;
228 typedef _ChildPolicy ChildPolicy;
229 typedef typename ChildPolicy::KeyPolicy KeyPolicy;
230 typedef Sdf_Children<ChildPolicy> ChildrenType;
231
232 typedef typename ChildPolicy::KeyType key_type;
233 typedef typename Adapter::PublicType value_type;
234
235private:
236
237 // An iterator type for the internal unfiltered data storage. This
238 // iterator holds a pointer to its owning object and an index into
239 // the owner's storage. That allows the iterator to operate without
240 // knowing anything about the specific data storage that's used,
241 // which is important for providing both Gd and Lsd backed storage.
242 class _InnerIterator {
243 class _PtrProxy {
244 public:
245 SdfChildrenView::value_type* operator->() { return &_value; }
246 private:
247 friend class SdfChildrenView;
248 explicit _PtrProxy(const SdfChildrenView::value_type& value)
249 : _value(value) {}
250 SdfChildrenView::value_type _value;
251 };
252 public:
253 using iterator_category = std::random_access_iterator_tag;
254 using value_type = SdfChildrenView::value_type;
255 using reference = value_type;
256 using pointer = _PtrProxy;
257 using difference_type = std::ptrdiff_t;
258
259 _InnerIterator() = default;
260 _InnerIterator(const This* owner, const size_t& pos) :
261 _owner(owner), _pos(pos) { }
262
263 reference operator*() const { return dereference(); }
264 pointer operator->() const { return pointer(dereference()); }
265 reference operator[](const difference_type index) const {
266 _InnerIterator advanced(*this);
267 advanced.advance(index);
268 return advanced.dereference();
269 }
270
271 difference_type operator-(const _InnerIterator& other) const {
272 return -distance_to(other);
273 }
274
275 _InnerIterator& operator++() {
276 increment();
277 return *this;
278 }
279
280 _InnerIterator& operator--() {
281 decrement();
282 return *this;
283 }
284
285 _InnerIterator operator++(int) {
286 _InnerIterator result(*this);
287 increment();
288 return result;
289 }
290
291 _InnerIterator operator--(int) {
292 _InnerIterator result(*this);
293 decrement();
294 return result;
295 }
296
297 _InnerIterator operator+(const difference_type increment) const {
298 _InnerIterator result(*this);
299 result.advance(increment);
300 return result;
301 }
302
303 _InnerIterator operator-(const difference_type decrement) const {
304 _InnerIterator result(*this);
305 result.advance(-decrement);
306 return result;
307 }
308
309 _InnerIterator& operator+=(const difference_type increment) {
310 advance(increment);
311 return *this;
312 }
313
314 _InnerIterator& operator-=(const difference_type decrement) {
315 advance(-decrement);
316 return *this;
317 }
318
319 bool operator==(const _InnerIterator& other) const {
320 return equal(other);
321 }
322
323 bool operator!=(const _InnerIterator& other) const {
324 return !equal(other);
325 }
326
327 bool operator<(const _InnerIterator& other) const {
328 TF_DEV_AXIOM(_owner == other._owner);
329 return _pos < other._pos;
330 }
331
332 bool operator<=(const _InnerIterator& other) const {
333 TF_DEV_AXIOM(_owner == other._owner);
334 return _pos <= other._pos;
335 }
336
337 bool operator>(const _InnerIterator& other) const {
338 TF_DEV_AXIOM(_owner == other._owner);
339 return _pos > other._pos;
340 }
341
342 bool operator>=(const _InnerIterator& other) const {
343 TF_DEV_AXIOM(_owner == other._owner);
344 return _pos >= other._pos;
345 }
346
347 private:
348
349 reference dereference() const
350 {
351 return _owner->_Get(_pos);
352 }
353
354 bool equal(const _InnerIterator& other) const
355 {
356 return _pos == other._pos;
357 }
358
359 void increment() {
360 ++_pos;
361 }
362
363 void decrement() {
364 --_pos;
365 }
366
367 void advance(difference_type n) {
368 _pos += n;
369 }
370
371 difference_type distance_to(const _InnerIterator& other) const {
372 return other._pos-_pos;
373 }
374
375 private:
376 const This* _owner = nullptr;
377 size_t _pos = 0;
378 };
379
380public:
381 typedef Sdf_ChildrenViewTraits<This, _InnerIterator, Predicate> _Traits;
382 typedef typename _Traits::const_iterator const_iterator;
383 typedef Tf_ProxyReferenceReverseIterator<const_iterator> const_reverse_iterator;
384 typedef size_t size_type;
385 typedef ptrdiff_t difference_type;
386
388 {
389 }
390
391 SdfChildrenView(const SdfLayerHandle &layer, const SdfPath &path,
392 const TfToken &childrenKey,
393 const KeyPolicy& keyPolicy = KeyPolicy()) :
394 _children(layer, path, childrenKey, keyPolicy)
395 {
396 }
397
398 SdfChildrenView(const SdfLayerHandle &layer, const SdfPath &path,
399 const TfToken &childrenKey,
400 const Predicate& predicate,
401 const KeyPolicy& keyPolicy = KeyPolicy()) :
402 _children(layer, path, childrenKey, keyPolicy),
403 _predicate(predicate)
404 {
405 }
406
407 SdfChildrenView(const SdfChildrenView &other) :
408 _children(other._children),
409 _predicate(other._predicate)
410 {
411 }
412
413 template <class OtherAdapter>
414 SdfChildrenView(const SdfChildrenView<ChildPolicy, Predicate,
415 OtherAdapter> &other) :
416 _children(other._children),
417 _predicate(other._predicate)
418 {
419 }
420
422 {
423 }
424
425 SdfChildrenView& operator=(const SdfChildrenView &other)
426 {
427 _children= other._children;
428 _predicate = other._predicate;
429 return *this;
430 }
431
433 const_iterator begin() const {
434 _InnerIterator i(this,0);
435 return _Traits::GetIterator(this, i, _GetSize());
436 }
437
439 const_iterator end() const {
440 _InnerIterator i(this,_GetSize());
441 return _Traits::GetIterator(this, i, _GetSize());
442 }
443
446 const_reverse_iterator rbegin() const {
447 return const_reverse_iterator(end());
448 }
449
452 const_reverse_iterator rend() const {
453 return const_reverse_iterator(begin());
454 }
455
457 size_type size() const {
458 return std::distance(begin(), end());
459 }
460
462 bool empty() const {
463 return begin() == end();
464 }
465
467 value_type operator[](size_type n) const {
468 const_iterator i = begin();
469 std::advance(i, n);
470 return *i;
471 }
472
474 value_type front() const {
475 return *begin();
476 }
477
479 value_type back() const {
480 return *rbegin();
481 }
482
484 const_iterator find(const key_type& x) const {
485 _InnerIterator inner(this, _children.Find(x));
486 const_iterator iter = _Traits::GetIterator(this, inner, _GetSize());
487
488 // _Traits::GetIterator may return a filtered iterator. We need to
489 // check that that iterator actually corresponds to the desired item.
490 // This ensures that we return end() in the case where the element being
491 // searched for is present in the children but filtered out by the
492 // view's predicate.
493 return _Traits::GetBase(iter) == inner ? iter : end();
494 }
495
497 const_iterator find(const value_type& x) const {
498 const_iterator i = find(key(x));
499 return (i != end() && *i == x) ? i : end();
500 }
501
503 key_type key(const const_iterator& x) const {
504 return key(*x);
505 }
506
508 key_type key(const value_type& x) const {
509 return _children.FindKey(Adapter::Convert(x));
510 }
511
513 std::vector<value_type> values() const {
514 return std::vector<value_type>(begin(), end());
515 }
516
518 template <typename V>
519 V values_as() const {
520 V x;
521 std::copy(begin(), end(), std::inserter(x, x.begin()));
522 return x;
523 }
524
526 std::vector<key_type> keys() const {
527 std::vector<key_type> result;
528 result.reserve(size());
529 for (const_iterator i = begin(), n = end(); i != n; ++i) {
530 result.push_back(key(i));
531 }
532 return result;
533 }
534
536 template <typename V>
537 V keys_as() const {
538 std::vector<key_type> k = keys();
539 return V(k.begin(), k.end());
540 }
541
543 template <typename Dict>
544 Dict items_as() const {
545 Dict result;
546 for (const_iterator i = begin(), n = end(); i != n; ++i) {
547 result.insert(std::make_pair(key(i), *i));
548 }
549 return result;
550 }
551
553 bool has(const key_type& x) const {
554 return (_children.Find(x) != _GetSize());
555 }
556
559 bool has(const value_type& x) const {
560 return has(key(Adapter::Convert(x)));
561 }
562
564 size_type count(const key_type& x) const {
565 return has(x);
566 }
567
570 value_type get(const key_type& x) const {
571 size_t index = _children.Find(x);
572 if (index == _GetSize()) {
573 return value_type();
574 }
575 return _Get(index);
576 }
577
580 value_type get(const key_type& x, const value_type& fallback) const {
581 size_t index = _children.Find(x);
582 if (index == _GetSize()) {
583 return fallback;
584 }
585 return _Get(index);
586 }
587
590 value_type operator[](const key_type& x) const {
591 return get(x);
592 }
593
596 bool operator==(const This& other) const {
597 return _children.IsEqualTo(other._children);
598 }
599
603 bool operator!=(const This& other) const {
604 return !_children.IsEqualTo(other._children);
605 }
606
607 // Return true if this object is valid
608 bool IsValid() const {
609 return _children.IsValid();
610 }
611
612 // Return the Sd_Children object that this view is holding.
613 ChildrenType &GetChildren() {
614 return _children;
615 }
616
617 // Return this view's predicate.
618 const Predicate& GetPredicate() const {
619 return _predicate;
620 }
621
622private:
623 // Return the value that corresponds to the provided index.
624 value_type _Get(size_type index) const {
625 return Adapter::Convert(_children.GetChild(index));
626 }
627
628 // Return the number of elements
629 size_t _GetSize() const {
630 return _children.GetSize();
631 }
632
633private:
634 template <class V, class P, class A> friend class SdfChildrenView;
635 ChildrenType _children;
636 Predicate _predicate;
637};
638
641template <class _View, class _Adapter>
643{
644 typedef _View OriginalView;
645 typedef SdfChildrenView<typename _View::ChildPolicy,
646 typename _View::Predicate,
647 _Adapter> AdaptedView;
648
649 static AdaptedView Create(const OriginalView& view)
650 {
651 return AdaptedView(view);
652 }
653};
654
655// Allow TfIteration over children views.
656template <typename C, typename P, typename A>
657struct Tf_ShouldIterateOverCopy<SdfChildrenView<C, P, A> > : std::true_type
658{
659};
660template <typename C, typename P, typename A>
661struct Tf_IteratorInterface<SdfChildrenView<C, P, A>, false> {
662 typedef SdfChildrenView<C, P, A> Type;
663 typedef typename Type::const_iterator IteratorType;
664 static IteratorType Begin(Type const &c) { return c.begin(); }
665 static IteratorType End(Type const &c) { return c.end(); }
666};
667template <typename C, typename P, typename A>
668struct Tf_IteratorInterface<SdfChildrenView<C, P, A>, true> {
669 typedef SdfChildrenView<C, P, A> Type;
670 typedef typename Type::const_reverse_iterator IteratorType;
671 static IteratorType Begin(Type const &c) { return c.rbegin(); }
672 static IteratorType End(Type const &c) { return c.rend(); }
673};
674
675PXR_NAMESPACE_CLOSE_SCOPE
676
677#endif // PXR_USD_SDF_CHILDREN_VIEW_H
A simple iterator adapter for STL containers.
Provides a view onto an object's children.
Definition: childrenView.h:222
std::vector< value_type > values() const
Returns the elements, in order.
Definition: childrenView.h:513
const_reverse_iterator rend() const
Returns an const_reverse_iterator pointing to the end of the reversed vector.
Definition: childrenView.h:452
std::vector< key_type > keys() const
Returns the keys for all elements, in order.
Definition: childrenView.h:526
bool has(const key_type &x) const
Returns true if an element with key x is in the container.
Definition: childrenView.h:553
key_type key(const const_iterator &x) const
Returns the key for an element.
Definition: childrenView.h:503
value_type front() const
Returns the first element.
Definition: childrenView.h:474
value_type get(const key_type &x, const value_type &fallback) const
Returns the element with key x or the fallback if no such element exists.
Definition: childrenView.h:580
const_iterator begin() const
Returns an const_iterator pointing to the beginning of the vector.
Definition: childrenView.h:433
value_type get(const key_type &x) const
Returns the element with key x or a default constructed value if no such element exists.
Definition: childrenView.h:570
value_type operator[](const key_type &x) const
Returns the element with key x or a default constructed value if no such element exists.
Definition: childrenView.h:590
size_type size() const
Returns the size of the vector.
Definition: childrenView.h:457
bool empty() const
Returns true if the vector is empty.
Definition: childrenView.h:462
const_iterator find(const key_type &x) const
Finds the element with key x.
Definition: childrenView.h:484
value_type back() const
Returns the last element.
Definition: childrenView.h:479
V keys_as() const
Returns the keys for all elements, in order.
Definition: childrenView.h:537
Dict items_as() const
Returns the elements as a dictionary.
Definition: childrenView.h:544
value_type operator[](size_type n) const
Returns the n'th element.
Definition: childrenView.h:467
key_type key(const value_type &x) const
Returns the key for a value.
Definition: childrenView.h:508
V values_as() const
Returns the elements, in order.
Definition: childrenView.h:519
bool has(const value_type &x) const
Returns true if an element with the same key as x is in the container.
Definition: childrenView.h:559
bool operator==(const This &other) const
Compares children for equality.
Definition: childrenView.h:596
bool operator!=(const This &other) const
Compares children for inequality.
Definition: childrenView.h:603
const_iterator end() const
Returns an const_iterator pointing to the end of the vector.
Definition: childrenView.h:439
size_type count(const key_type &x) const
Returns the number of elements with key x in the container.
Definition: childrenView.h:564
const_iterator find(const value_type &x) const
Finds element x, if present in this view.
Definition: childrenView.h:497
const_reverse_iterator rbegin() const
Returns an const_reverse_iterator pointing to the beginning of the reversed vector.
Definition: childrenView.h:446
Special case adapter that does no conversions.
Definition: childrenView.h:58
Special case predicate that always passes.
Definition: childrenView.h:48
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:88
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:222
Helper class to convert a given view of type _View to an adapted view using _Adapter as the adapter c...
Definition: childrenView.h:643