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