24#ifndef PXR_USD_SDF_LIST_PROXY_H
25#define PXR_USD_SDF_LIST_PROXY_H
31#include "pxr/usd/sdf/listEditor.h"
32#include "pxr/usd/sdf/listOp.h"
33#include "pxr/usd/sdf/path.h"
38#include <boost/optional.hpp>
43PXR_NAMESPACE_OPEN_SCOPE
53template <
class _TypePolicy>
56 typedef _TypePolicy TypePolicy;
58 typedef typename TypePolicy::value_type value_type;
59 typedef std::vector<value_type> value_vector_type;
65 explicit _ItemProxy(
This* owner,
size_t index) :
66 _owner(owner), _index(index)
71 _ItemProxy& operator=(
const _ItemProxy& x) {
72 _owner->_Edit(_index, 1, value_vector_type(1, x));
76 _ItemProxy& operator=(
const value_type& x) {
77 _owner->_Edit(_index, 1, value_vector_type(1, x));
81 operator value_type()
const {
82 return _owner->_Get(_index);
88 return _owner->_Get(_index) == x;
95 bool operator<(
const value_type& x)
const {
96 return _owner->_Get(_index) < x;
99 bool operator>(
const value_type& x)
const {
100 return x < value_type(*
this);
108 return !(x < value_type(*
this));
115 friend class _ItemProxy;
119 typedef _ItemProxy result_type;
121 result_type operator()(
This* owner,
size_t index)
const {
122 return _ItemProxy(owner, index);
125 class _ConstGetHelper {
127 typedef value_type result_type;
129 result_type operator()(
const This* owner,
size_t index)
const {
130 return owner->_Get(index);
133 friend class _GetHelper;
134 friend class _ConstGetHelper;
136 template <
class Owner,
class GetItem>
140 std::add_pointer_t<typename GetItem::result_type> operator->() {
141 return std::addressof(_result);
144 friend class _Iterator;
147 std::add_lvalue_reference_t<
148 typename GetItem::result_type>
149 > result) : _result(result) {}
150 typename GetItem::result_type _result;
153 using This = _Iterator<Owner, GetItem>;
154 using iterator_category = std::random_access_iterator_tag;
155 using value_type = std::remove_cv_t<
156 std::remove_reference_t<
157 typename GetItem::result_type
160 using reference =
typename GetItem::result_type;
161 using pointer = _PtrProxy;
162 using difference_type = std::ptrdiff_t;
164 static_assert(!std::is_lvalue_reference<reference>::value,
165 "reference is an lvalue_reference and usage of "
166 "this class unnecessarily instantiates a _PtrProxy.");
168 _Iterator() =
default;
170 _Iterator(Owner owner,
size_t index) : _owner(owner), _index(index)
175 reference operator*()
const {
return dereference(); }
176 pointer operator->()
const {
return pointer(dereference()); }
177 reference operator[](
const difference_type index)
const {
178 This advanced(*
this);
179 advanced.advance(index);
180 return advanced.dereference();
183 difference_type operator-(
const This& other)
const {
184 return -distance_to(other);
197 This operator++(
int) {
203 This operator--(
int) {
209 This operator+(
const difference_type increment)
const {
211 result.advance(increment);
215 This operator-(
const difference_type decrement)
const {
217 result.advance(-decrement);
221 This& operator+=(
const difference_type increment) {
226 This& operator-=(
const difference_type decrement) {
236 return !equal(other);
241 return _index < other._index;
246 return _index <= other._index;
251 return _index > other._index;
256 return _index >= other._index;
261 reference dereference()
const {
262 return _getItem(_owner, _index);
265 bool equal(
const This& other)
const {
266 if (_owner != other._owner) {
268 "different proxies!");
271 return _index == other._index;
282 void advance(difference_type n) {
286 difference_type distance_to(
const This& other)
const {
287 return other._index - _index;
292 Owner _owner =
nullptr;
297 typedef _ItemProxy reference;
298 typedef _Iterator<This*, _GetHelper> iterator;
299 typedef _Iterator<const This*, _ConstGetHelper> const_iterator;
300 typedef Tf_ProxyReferenceReverseIterator<iterator> reverse_iterator;
301 typedef Tf_ProxyReferenceReverseIterator<const_iterator> const_reverse_iterator;
313 SdfListProxy(
const std::shared_ptr<Sdf_ListEditor<TypePolicy> >& editor,
322 return iterator(_GetThis(), 0);
326 return iterator(_GetThis(), _GetSize());
331 return reverse_iterator(
end());
335 return reverse_iterator(
begin());
340 return const_iterator(_GetThis(), 0);
343 const_iterator
end()
const {
344 return const_iterator(_GetThis(), _GetSize());
349 return const_reverse_iterator(
end());
353 const_reverse_iterator
rend()
const {
354 return const_reverse_iterator(
begin());
359 return _Validate() ? _GetSize() : 0;
369 return reference(_GetThis(), n);
379 return reference(_GetThis(), 0);
384 return reference(_GetThis(), _GetSize() - 1);
394 return _Get(_GetSize() - 1);
399 _Edit(_GetSize(), 0, value_vector_type(1, elem));
404 _Edit(_GetSize() - 1, 1, value_vector_type());
408 iterator
insert(iterator pos,
const value_type& x) {
409 _Edit(pos - iterator(
this, 0), 0, value_vector_type(1, x));
415 template <
class InputIterator>
416 void insert(iterator pos, InputIterator f, InputIterator l) {
417 _Edit(pos - iterator(
this, 0), 0, value_vector_type(f, l));
422 _Edit(pos - iterator(
this, 0), 1, value_vector_type());
426 void erase(iterator f, iterator l) {
427 _Edit(f - iterator(
this, 0), l - f, value_vector_type());
432 _Edit(0, _GetSize(), value_vector_type());
439 void resize(
size_t n,
const value_type& t = value_type()) {
440 size_t s = _GetSize();
442 _Edit(s, 0, value_vector_type(n - s, t));
445 _Edit(n, s - n, value_vector_type());
450 operator value_vector_type()
const {
451 return _listEditor ? _listEditor->GetVector(_op) : value_vector_type();
458 _Edit(0, _GetSize(),
static_cast<value_vector_type
>(other));
464 _Edit(0, _GetSize(), other);
471 _Edit(0, _GetSize(), value_vector_type(v.begin(), v.end()));
478 return value_vector_type(*
this) == value_vector_type(y);
484 return !(*
this == y);
490 return value_vector_type(*
this) < value_vector_type(y);
496 return value_vector_type(*
this) <= value_vector_type(y);
502 return !(*
this <= y);
513 return value_vector_type(*
this) == y;
523 return !(*
this == y);
533 return value_vector_type(*
this) < y;
538 return x < value_vector_type(y);
543 return value_vector_type(*
this) > y;
548 return x > value_vector_type(y);
558 return x <= value_vector_type(y);
568 return x >= value_vector_type(y);
573 explicit operator bool()
const
575 return _listEditor && _listEditor->IsValid() && _IsRelevant();
583 return _listEditor ? _listEditor->GetLayer() : SdfLayerHandle();
589 return _listEditor ? _listEditor->GetPath() :
SdfPath();
595 return _listEditor && _listEditor->IsExpired();
598 size_t Count(
const value_type& value)
const
600 return (_Validate() ? _listEditor->Count(_op, value) : 0);
603 size_t Find(
const value_type& value)
const
605 return (_Validate() ? _listEditor->Find(_op, value) :
size_t(-1));
608 void Insert(
int index,
const value_type& value)
611 index =
static_cast<int>(_GetSize());
613 _Edit(index, 0, value_vector_type(1, value));
616 void Remove(
const value_type& value)
618 size_t index = Find(value);
619 if (index !=
size_t(-1)) {
625 _Edit(_GetSize(), 0, value_vector_type());
629 void Replace(
const value_type& oldValue,
const value_type& newValue)
631 size_t index = Find(oldValue);
632 if (index !=
size_t(-1)) {
633 _Edit(index, 1, value_vector_type(1, newValue));
638 _Edit(_GetSize(), 0, value_vector_type());
642 void Erase(
size_t index)
644 _Edit(index, 1, value_vector_type());
650 if (_Validate() && list._Validate()) {
651 _listEditor->ApplyList(_op, *list._listEditor);
659 _listEditor->ApplyEditsToList(vec);
677 _listEditor->ModifyItemEdits(std::forward<CB>(callback));
695 bool _Validate()
const
710 return _Validate() ? this : NULL;
713 const This* _GetThis()
const
715 return _Validate() ? this : NULL;
718 bool _IsRelevant()
const
720 if (_listEditor->IsExplicit()) {
721 return _op == SdfListOpTypeExplicit;
723 else if (_listEditor->IsOrderedOnly()) {
724 return _op == SdfListOpTypeOrdered;
727 return _op != SdfListOpTypeExplicit;
731 size_t _GetSize()
const
733 return _listEditor ? _listEditor->GetSize(_op) : 0;
736 value_type _Get(
size_t n)
const
738 return _Validate() ? _listEditor->Get(_op, n) : value_type();
741 void _Edit(
size_t index,
size_t n,
const value_vector_type& elems)
746 if (n == 0 && elems.empty()) {
747 SdfAllowed canEdit = _listEditor->PermissionToEdit(_op);
756 _listEditor->ReplaceEdits(_op, index, n, elems);
764 std::shared_ptr<Sdf_ListEditor<TypePolicy> > _listEditor;
767 template <
class>
friend class SdfPyWrapListProxy;
772struct Tf_ShouldIterateOverCopy<
SdfListProxy<T> > : std::true_type
776PXR_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.
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.
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.