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/iterator/iterator_facade.hpp>
39 #include <boost/iterator/reverse_iterator.hpp>
40 #include <boost/operators.hpp>
41 #include <boost/optional.hpp>
42 #include <boost/type_traits/is_base_of.hpp>
43 #include <boost/type_traits/remove_cv.hpp>
44 #include <boost/type_traits/remove_reference.hpp>
46 PXR_NAMESPACE_OPEN_SCOPE
56 template <
class _TypePolicy>
58 boost::totally_ordered<SdfListProxy<_TypePolicy>,
59 std::vector<typename _TypePolicy::value_type> > {
61 typedef _TypePolicy TypePolicy;
63 typedef typename TypePolicy::value_type value_type;
64 typedef std::vector<value_type> value_vector_type;
68 class _ItemProxy : boost::totally_ordered<_ItemProxy> {
70 explicit _ItemProxy(
This* owner,
size_t index) :
71 _owner(owner), _index(index)
76 _ItemProxy&
operator=(
const _ItemProxy& x) {
77 _owner->_Edit(_index, 1, value_vector_type(1, x));
81 _ItemProxy&
operator=(
const value_type& x) {
82 _owner->_Edit(_index, 1, value_vector_type(1, x));
86 operator value_type()
const {
87 return _owner->_Get(_index);
91 return _owner->_Get(_index) == x;
94 bool operator<(
const value_type& x)
const {
95 return _owner->_Get(_index) < x;
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>
125 public boost::iterator_facade<
126 _Iterator<Owner, GetItem>,
127 typename boost::remove_cv<
128 typename boost::remove_reference<
129 typename GetItem::result_type
132 std::random_access_iterator_tag,
133 typename GetItem::result_type> {
135 typedef _Iterator<Owner, GetItem>
This;
137 boost::iterator_facade<
138 _Iterator<Owner, GetItem>,
139 typename boost::remove_cv<
140 typename boost::remove_reference<
141 typename GetItem::result_type
144 std::random_access_iterator_tag,
145 typename GetItem::result_type> Parent;
146 typedef typename Parent::reference reference;
147 typedef typename Parent::difference_type difference_type;
149 _Iterator() : _owner(NULL), _index(0)
154 _Iterator(Owner owner,
size_t index) : _owner(owner), _index(index)
160 friend class boost::iterator_core_access;
162 reference dereference()
const {
163 return _getItem(_owner, _index);
166 bool equal(
const This& other)
const {
167 if (_owner != other._owner) {
169 "different proxies!");
172 return _index == other._index;
183 void advance(difference_type n) {
187 difference_type distance_to(
const This& other)
const {
188 return other._index - _index;
198 typedef _ItemProxy reference;
199 typedef _Iterator<This*, _GetHelper> iterator;
200 typedef _Iterator<const This*, _ConstGetHelper> const_iterator;
201 typedef boost::reverse_iterator<iterator> reverse_iterator;
202 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
214 SdfListProxy(
const boost::shared_ptr<Sdf_ListEditor<TypePolicy> >& editor,
223 return iterator(_GetThis(), 0);
227 return iterator(_GetThis(), _GetSize());
232 return reverse_iterator(
end());
236 return reverse_iterator(
begin());
241 return const_iterator(_GetThis(), 0);
244 const_iterator
end()
const {
245 return const_iterator(_GetThis(), _GetSize());
250 return const_reverse_iterator(
end());
254 const_reverse_iterator
rend()
const {
255 return const_reverse_iterator(
begin());
260 return _Validate() ? _GetSize() : 0;
270 return reference(_GetThis(), n);
280 return reference(_GetThis(), 0);
285 return reference(_GetThis(), _GetSize() - 1);
295 return _Get(_GetSize() - 1);
300 _Edit(_GetSize(), 0, value_vector_type(1, elem));
305 _Edit(_GetSize() - 1, 1, value_vector_type());
309 iterator
insert(iterator pos,
const value_type& x) {
310 _Edit(pos - iterator(
this, 0), 0, value_vector_type(1, x));
316 template <
class InputIterator>
317 void insert(iterator pos, InputIterator f, InputIterator l) {
318 _Edit(pos - iterator(
this, 0), 0, value_vector_type(f, l));
323 _Edit(pos - iterator(
this, 0), 1, value_vector_type());
327 void erase(iterator f, iterator l) {
328 _Edit(f - iterator(
this, 0), l - f, value_vector_type());
333 _Edit(0, _GetSize(), value_vector_type());
340 void resize(
size_t n,
const value_type& t = value_type()) {
341 size_t s = _GetSize();
343 _Edit(s, 0, value_vector_type(n - s, t));
346 _Edit(n, s - n, value_vector_type());
351 operator value_vector_type()
const {
352 return _listEditor ? _listEditor->GetVector(_op) : value_vector_type();
359 _Edit(0, _GetSize(), static_cast<value_vector_type>(other));
365 _Edit(0, _GetSize(), other);
372 _Edit(0, _GetSize(), value_vector_type(v.begin(), v.end()));
379 return value_vector_type(*
this) == value_vector_type(y);
385 return !(*
this == y);
390 bool operator<(const SdfListProxy<T2>& y)
const {
391 return value_vector_type(*
this) < value_vector_type(y);
396 bool operator<=(const SdfListProxy<T2>& y)
const {
397 return value_vector_type(*
this) <= value_vector_type(y);
403 return !(*
this <= y);
414 return value_vector_type(*
this) == y;
419 return value_vector_type(*
this) < y;
424 return value_vector_type(*
this) > y;
429 explicit operator bool()
const
431 return _listEditor && _listEditor->IsValid() && _IsRelevant();
439 return _listEditor ? _listEditor->GetLayer() : SdfLayerHandle();
445 return _listEditor ? _listEditor->GetPath() :
SdfPath();
451 return _listEditor && _listEditor->IsExpired();
454 size_t Count(
const value_type& value)
const
456 return (_Validate() ? _listEditor->Count(_op, value) : 0);
459 size_t Find(
const value_type& value)
const
461 return (_Validate() ? _listEditor->Find(_op, value) : size_t(-1));
464 void Insert(
int index,
const value_type& value)
467 index =
static_cast<int>(_GetSize());
469 _Edit(index, 0, value_vector_type(1, value));
472 void Remove(
const value_type& value)
474 size_t index = Find(value);
475 if (index !=
size_t(-1)) {
481 _Edit(_GetSize(), 0, value_vector_type());
485 void Replace(
const value_type& oldValue,
const value_type& newValue)
487 size_t index = Find(oldValue);
488 if (index !=
size_t(-1)) {
489 _Edit(index, 1, value_vector_type(1, newValue));
494 _Edit(_GetSize(), 0, value_vector_type());
498 void Erase(
size_t index)
500 _Edit(index, 1, value_vector_type());
506 if (_Validate() && list._Validate()) {
507 _listEditor->ApplyList(_op, *list._listEditor);
515 _listEditor->ApplyEditsToList(vec);
533 bool _Validate()
const
548 return _Validate() ?
this : NULL;
551 const This* _GetThis()
const
553 return _Validate() ?
this : NULL;
556 bool _IsRelevant()
const
558 if (_listEditor->IsExplicit()) {
559 return _op == SdfListOpTypeExplicit;
561 else if (_listEditor->IsOrderedOnly()) {
562 return _op == SdfListOpTypeOrdered;
565 return _op != SdfListOpTypeExplicit;
569 size_t _GetSize()
const
571 return _listEditor ? _listEditor->GetSize(_op) : 0;
574 value_type _Get(
size_t n)
const
576 return _Validate() ? _listEditor->Get(_op, n) : value_type();
579 void _Edit(
size_t index,
size_t n,
const value_vector_type& elems)
584 if (n == 0 && elems.empty()) {
585 SdfAllowed canEdit = _listEditor->PermissionToEdit(_op);
594 _listEditor->ReplaceEdits(_op, index, n, elems);
602 boost::shared_ptr<Sdf_ListEditor<TypePolicy> > _listEditor;
605 template <
class>
friend class SdfPyWrapListProxy;
609 template <
typename T>
610 struct Tf_ShouldIterateOverCopy<
SdfListProxy<T> > : boost::true_type
614 PXR_NAMESPACE_CLOSE_SCOPE
616 #endif // PXR_USD_SDF_LIST_PROXY_H
reference operator[](size_t n)
Return a reference to the item at index n.
void clear()
Clear the contents of the sequence.
This & operator=(const value_vector_type &other)
Replace all elements in this sequence with the given vector.
value_type operator[](size_t n) const
Return a copy of the item at index n.
void resize(size_t n, const value_type &t=value_type())
Resize the contents of the sequence.
reference back()
Return a reference to the item at the back of the sequence.
This & operator=(const SdfListProxy< T2 > &other)
Replace all elements in this sequence with the elements in the other sequence.
void push_back(const value_type &elem)
Append elem to this sequence.
bool operator<(const SdfListProxy< T2 > &y) const
Less-than comparison.
A simple iterator adapter for STL containers.
reverse_iterator rbegin()
Return a reverse iterator to the last item of the sequence.
bool operator<(const value_vector_type &y) const
Less-than comparison.
This & operator=(const std::vector< Y > &v)
Replace all elements in this sequence with the given vector.
reference front()
Return a reference to the item at the front of the sequence.
bool operator>(const SdfListProxy< T2 > &y) const
Greater-than comparison.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Low-level utilities for informing users of various internal and external diagnostic conditions...
const_reverse_iterator rend() const
Return a const reverse iterator past the start item of the sequence.
void erase(iterator pos)
Erase the element at pos.
void pop_back()
Remove the last element from this sequence.
SDF_API const std::string & GetWhyNot() const
Returns the reason why the operation is not allowed.
iterator begin()
Return an iterator to the start of the sequence.
value_type front() const
Return a copy of the item at the front of the sequence.
Indicates if an operation is allowed and, if not, why not.
Represents a single list of list editing operations.
void ApplyList(const SdfListProxy &list)
Applies the edits in the given list to this one.
void insert(iterator pos, InputIterator f, InputIterator l)
Insert copies of the elements in [f, l) into this sequence starting at position pos.
const_iterator begin() const
Return a const iterator to the start of the sequence.
iterator end()
Return an iterator to the end of the sequence.
bool operator==(const SdfListProxy< T2 > &y) const
Equality comparison.
A path value used to locate objects in layers or scenegraphs.
bool operator!=(const SdfListProxy< T2 > &y) const
Inequality comparison.
const_iterator end() const
Return a const iterator to the end of the sequence.
iterator insert(iterator pos, const value_type &x)
Insert x into this sequence at position pos.
value_type back() const
Return a copy of the item at the back of the sequence.
bool operator==(const value_vector_type &y) const
Equality comparison.
bool empty() const
Return true if size() == 0.
bool operator>=(const SdfListProxy< T2 > &y) const
Greater-than-or-equal comparison.
SdfLayerHandle GetLayer() const
Returns the layer that this list editor belongs to.
void erase(iterator f, iterator l)
Erase all the elements in the range [f, l).
void ApplyEditsToList(value_vector_type *vec)
Apply the edits in this list to the given vec.
reverse_iterator rend()
Return a reverse iterator past the start item of the sequence.
bool operator>(const value_vector_type &y) const
Greater-than comparison.
bool IsExpired() const
Returns true if the list editor is expired.
SdfPath GetPath() const
Returns the path to this list editor's value.
size_t size() const
Return the size of the sequence.
SdfListProxy(const boost::shared_ptr< Sdf_ListEditor< TypePolicy > > &editor, SdfListOpType op)
Create a new proxy wrapping the list operation vector specified by op in the underlying listEditor...
SdfListProxy(SdfListOpType op)
Creates a default list proxy object for list operation vector specified op.
const_reverse_iterator rbegin() const
Return a const reverse iterator to the last item of the sequence.