7#ifndef PXR_USD_SDF_LIST_PROXY_H
8#define PXR_USD_SDF_LIST_PROXY_H
14#include "pxr/usd/sdf/listEditor.h"
15#include "pxr/usd/sdf/listOp.h"
16#include "pxr/usd/sdf/path.h"
26PXR_NAMESPACE_OPEN_SCOPE
36template <
class _TypePolicy>
39 typedef _TypePolicy TypePolicy;
41 typedef typename TypePolicy::value_type value_type;
42 typedef std::vector<value_type> value_vector_type;
52 explicit _ItemProxy(
This* owner,
size_t index) :
53 _owner(owner), _index(index)
58 _ItemProxy& operator=(
const _ItemProxy& x) {
59 _owner->_Edit(_index, 1, value_vector_type(1, x));
63 _ItemProxy& operator=(
const value_type& x) {
64 _owner->_Edit(_index, 1, value_vector_type(1, x));
68 operator value_type()
const {
69 return _owner->_Get(_index);
75 return _owner->_Get(_index) == x;
82 bool operator<(
const value_type& x)
const {
83 return _owner->_Get(_index) < x;
86 bool operator>(
const value_type& x)
const {
87 return x < value_type(*
this);
95 return !(x < value_type(*
this));
102 friend class _ItemProxy;
106 typedef _ItemProxy result_type;
108 result_type operator()(This* owner,
size_t index)
const {
109 return _ItemProxy(owner, index);
112 class _ConstGetHelper {
114 typedef value_type result_type;
116 result_type operator()(
const This* owner,
size_t index)
const {
117 return owner->_Get(index);
120 friend class _GetHelper;
121 friend class _ConstGetHelper;
123 template <
class Owner,
class GetItem>
127 std::add_pointer_t<typename GetItem::result_type> operator->() {
128 return std::addressof(_result);
131 friend class _Iterator;
134 std::add_lvalue_reference_t<
135 typename GetItem::result_type>
136 > result) : _result(result) {}
137 typename GetItem::result_type _result;
140 using This = _Iterator<Owner, GetItem>;
141 using iterator_category = std::random_access_iterator_tag;
142 using value_type = std::remove_cv_t<
143 std::remove_reference_t<
144 typename GetItem::result_type
147 using reference =
typename GetItem::result_type;
148 using pointer = _PtrProxy;
149 using difference_type = std::ptrdiff_t;
151 static_assert(!std::is_lvalue_reference<reference>::value,
152 "reference is an lvalue_reference and usage of "
153 "this class unnecessarily instantiates a _PtrProxy.");
155 _Iterator() =
default;
157 _Iterator(Owner owner,
size_t index) : _owner(owner), _index(index)
162 reference operator*()
const {
return dereference(); }
163 pointer operator->()
const {
return pointer(dereference()); }
164 reference operator[](
const difference_type index)
const {
165 This advanced(*
this);
166 advanced.advance(index);
167 return advanced.dereference();
170 difference_type operator-(
const This& other)
const {
171 return -distance_to(other);
184 This operator++(
int) {
190 This operator--(
int) {
196 This operator+(
const difference_type increment)
const {
198 result.advance(increment);
202 This operator-(
const difference_type decrement)
const {
204 result.advance(-decrement);
208 This& operator+=(
const difference_type increment) {
213 This& operator-=(
const difference_type decrement) {
223 return !equal(other);
226 bool operator<(
const This& other)
const {
228 return _index < other._index;
233 return _index <= other._index;
236 bool operator>(
const This& other)
const {
238 return _index > other._index;
243 return _index >= other._index;
248 reference dereference()
const {
249 return _getItem(_owner, _index);
252 bool equal(
const This& other)
const {
253 if (_owner != other._owner) {
255 "different proxies!");
258 return _index == other._index;
269 void advance(difference_type n) {
273 difference_type distance_to(
const This& other)
const {
274 return other._index - _index;
279 Owner _owner =
nullptr;
284 typedef _ItemProxy reference;
285 typedef _Iterator<This*, _GetHelper> iterator;
286 typedef _Iterator<const This*, _ConstGetHelper> const_iterator;
287 typedef Tf_ProxyReferenceReverseIterator<iterator> reverse_iterator;
288 typedef Tf_ProxyReferenceReverseIterator<const_iterator> const_reverse_iterator;
300 SdfListProxy(
const std::shared_ptr<Sdf_ListEditor<TypePolicy> >& editor,
309 return iterator(_GetThis(), 0);
313 return iterator(_GetThis(), _GetSize());
318 return reverse_iterator(
end());
322 return reverse_iterator(
begin());
327 return const_iterator(_GetThis(), 0);
330 const_iterator
end()
const {
331 return const_iterator(_GetThis(), _GetSize());
336 return const_reverse_iterator(
end());
340 const_reverse_iterator
rend()
const {
341 return const_reverse_iterator(
begin());
346 return _Validate() ? _GetSize() : 0;
356 return reference(_GetThis(), n);
366 return reference(_GetThis(), 0);
371 return reference(_GetThis(), _GetSize() - 1);
381 return _Get(_GetSize() - 1);
386 _Edit(_GetSize(), 0, value_vector_type(1, elem));
391 _Edit(_GetSize() - 1, 1, value_vector_type());
395 iterator
insert(iterator pos,
const value_type& x) {
396 _Edit(pos - iterator(
this, 0), 0, value_vector_type(1, x));
402 template <
class InputIterator>
403 void insert(iterator pos, InputIterator f, InputIterator l) {
404 _Edit(pos - iterator(
this, 0), 0, value_vector_type(f, l));
409 _Edit(pos - iterator(
this, 0), 1, value_vector_type());
413 void erase(iterator f, iterator l) {
414 _Edit(f - iterator(
this, 0), l - f, value_vector_type());
419 _Edit(0, _GetSize(), value_vector_type());
426 void resize(
size_t n,
const value_type& t = value_type()) {
427 size_t s = _GetSize();
429 _Edit(s, 0, value_vector_type(n - s, t));
432 _Edit(n, s - n, value_vector_type());
437 operator value_vector_type()
const {
438 return _listEditor ? _listEditor->GetVector(_op) : value_vector_type();
445 _Edit(0, _GetSize(),
static_cast<value_vector_type
>(other));
451 _Edit(0, _GetSize(), other);
458 _Edit(0, _GetSize(), value_vector_type(v.begin(), v.end()));
465 return value_vector_type(*
this) == value_vector_type(y);
471 return !(*
this == y);
477 return value_vector_type(*
this) < value_vector_type(y);
483 return value_vector_type(*
this) <= value_vector_type(y);
489 return !(*
this <= y);
500 return value_vector_type(*
this) == y;
510 return !(*
this == y);
520 return value_vector_type(*
this) < y;
525 return x < value_vector_type(y);
530 return value_vector_type(*
this) > y;
535 return x > value_vector_type(y);
545 return x <= value_vector_type(y);
555 return x >= value_vector_type(y);
560 explicit operator bool()
const
562 return _listEditor && _listEditor->IsValid() && _IsRelevant();
570 return _listEditor ? _listEditor->GetLayer() : SdfLayerHandle();
576 return _listEditor ? _listEditor->GetPath() :
SdfPath();
582 return _listEditor && _listEditor->IsExpired();
585 size_t Count(
const value_type& value)
const
587 return (_Validate() ? _listEditor->Count(_op, value) : 0);
592 size_t Find(
const value_type& value)
const
594 return (_Validate() ? _listEditor->Find(_op, value) :
invalidIndex);
597 void Insert(
int index,
const value_type& value)
600 index =
static_cast<int>(_GetSize());
602 _Edit(index, 0, value_vector_type(1, value));
605 void Remove(
const value_type& value)
607 size_t index =
Find(value);
614 _Edit(_GetSize(), 0, value_vector_type());
618 void Replace(
const value_type& oldValue,
const value_type& newValue)
620 size_t index =
Find(oldValue);
621 if (index !=
size_t(-1)) {
622 _Edit(index, 1, value_vector_type(1, newValue));
627 _Edit(_GetSize(), 0, value_vector_type());
631 void Erase(
size_t index)
633 _Edit(index, 1, value_vector_type());
639 if (_Validate() && list._Validate()) {
640 _listEditor->ApplyList(_op, *list._listEditor);
648 _listEditor->ApplyEditsToList(vec);
666 _listEditor->ModifyItemEdits(std::forward<CB>(callback));
684 bool _Validate()
const
699 return _Validate() ? this : NULL;
702 const This* _GetThis()
const
704 return _Validate() ? this : NULL;
707 bool _IsRelevant()
const
709 if (_listEditor->IsExplicit()) {
710 return _op == SdfListOpTypeExplicit;
712 else if (_listEditor->IsOrderedOnly()) {
713 return _op == SdfListOpTypeOrdered;
716 return _op != SdfListOpTypeExplicit;
720 size_t _GetSize()
const
722 return _listEditor ? _listEditor->GetSize(_op) : 0;
725 value_type _Get(
size_t n)
const
727 return _Validate() ? _listEditor->Get(_op, n) : value_type();
730 void _Edit(
size_t index,
size_t n,
const value_vector_type& elems)
735 if (n == 0 && elems.empty()) {
736 SdfAllowed canEdit = _listEditor->PermissionToEdit(_op);
745 _listEditor->ReplaceEdits(_op, index, n, elems);
753 std::shared_ptr<Sdf_ListEditor<TypePolicy> > _listEditor;
756 template <
class>
friend class SdfPyWrapListProxy;
761struct Tf_ShouldIterateOverCopy<
SdfListProxy<T> > : std::true_type
765PXR_NAMESPACE_CLOSE_SCOPE
Low-level utilities for informing users of various internal and external diagnostic conditions.
A simple iterator adapter for STL containers.
Indicates if an operation is allowed and, if not, why not.
SDF_API const std::string & GetWhyNot() const
Returns the reason why the operation is not allowed.
Represents a single list of list editing operations.
void pop_back()
Remove the last element from this sequence.
value_type operator[](size_t n) const
Return a copy of the item at index n.
const_reverse_iterator rend() const
Return a const reverse iterator past the start item of the sequence.
void push_back(const value_type &elem)
Append elem to this sequence.
friend bool operator<=(const value_vector_type &x, const SdfListProxy &y)
Less-than or equal to comparison.
void ApplyList(const SdfListProxy &list)
Applies the edits in the given list to this one.
value_type front() const
Return a copy of the item at the front of the sequence.
bool operator<=(const value_vector_type &y) const
Less-than or equal to comparison.
friend bool operator<(const value_vector_type &x, const SdfListProxy &y)
Less-than comparison.
void ApplyEditsToList(value_vector_type *vec)
Apply the edits in this list to the given vec.
size_t size() const
Return the size of the sequence.
const_iterator begin() const
Return a const iterator to the start of the sequence.
void resize(size_t n, const value_type &t=value_type())
Resize the contents of the sequence.
void insert(iterator pos, InputIterator f, InputIterator l)
Insert copies of the elements in [f, l) into this sequence starting at position pos.
size_t Find(const value_type &value) const
Returns the index of value in the list of operations.
bool operator>(const SdfListProxy< T2 > &y) const
Greater-than comparison.
bool operator<=(const SdfListProxy< T2 > &y) const
Less-than-or-equal comparison.
bool operator<(const SdfListProxy< T2 > &y) const
Less-than comparison.
SdfListProxy(const std::shared_ptr< Sdf_ListEditor< TypePolicy > > &editor, SdfListOpType op)
Create a new proxy wrapping the list operation vector specified by op in the underlying listEditor.
bool operator!=(const SdfListProxy< T2 > &y) const
Inequality comparison.
bool empty() const
Return true if size() == 0.
friend bool operator!=(const value_vector_type &x, const SdfListProxy &y)
Inequality comparision.
reverse_iterator rend()
Return a reverse iterator past the start item of the sequence.
reference front()
Return a reference to the item at the front of the sequence.
SdfLayerHandle GetLayer() const
Returns the layer that this list editor belongs to.
bool operator>=(const SdfListProxy< T2 > &y) const
Greater-than-or-equal comparison.
value_type back() const
Return a copy of the item at the back of the sequence.
friend bool operator>(const value_vector_type &x, const SdfListProxy &y)
Greater-than comparison.
static const size_t invalidIndex
Returned from Find when a value could not be located in the list of operations.
bool operator>(const value_vector_type &y) const
Greater-than comparison.
reference operator[](size_t n)
Return a reference to the item at index n.
SdfListProxy(SdfListOpType op)
Creates a default list proxy object for list operation vector specified op.
This & operator=(const std::vector< Y > &v)
Replace all elements in this sequence with the given vector.
void ModifyItemEdits(CB callback)
Modify all edits in this list.
void erase(iterator f, iterator l)
Erase all the elements in the range [f, l).
SdfPath GetPath() const
Returns the path to this list editor's value.
friend bool operator==(const value_vector_type &x, const SdfListProxy &y)
Equality comparision.
bool operator<(const value_vector_type &y) const
Less-than comparison.
bool operator==(const value_vector_type &y) const
Equality comparison.
iterator insert(iterator pos, const value_type &x)
Insert x into this sequence at position pos.
bool IsExpired() const
Returns true if the list editor is expired.
bool operator!=(const value_vector_type &y) const
Inequality comparison.
bool operator>=(const value_vector_type &y) const
Greater-than or equal to comparison.
void clear()
Clear the contents of the sequence.
iterator end()
Return an iterator to the end of the sequence.
const_iterator end() const
Return a const iterator to the end of the sequence.
void erase(iterator pos)
Erase the element at pos.
reverse_iterator rbegin()
Return a reverse iterator to the last item of the sequence.
iterator begin()
Return an iterator to the start of the sequence.
This & operator=(const SdfListProxy< T2 > &other)
Replace all elements in this sequence with the elements in the other sequence.
const_reverse_iterator rbegin() const
Return a const reverse iterator to the last item of the sequence.
reference back()
Return a reference to the item at the back of the sequence.
This & operator=(const value_vector_type &other)
Replace all elements in this sequence with the given vector.
bool operator==(const SdfListProxy< T2 > &y) const
Equality comparison.
friend bool operator>=(const value_vector_type &x, const SdfListProxy &y)
Greater-than or equal to comparison.
A path value used to locate objects in layers or scenegraphs.
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.