Loading...
Searching...
No Matches
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