24 #ifndef PXR_USD_SDF_MAP_EDIT_PROXY_H 25 #define PXR_USD_SDF_MAP_EDIT_PROXY_H 31 #include "pxr/usd/sdf/changeBlock.h" 33 #include "pxr/usd/sdf/mapEditor.h" 36 #include "pxr/base/vt/value.h" 39 #include <boost/iterator/iterator_facade.hpp> 40 #include <boost/iterator/reverse_iterator.hpp> 41 #include <boost/operators.hpp> 45 PXR_NAMESPACE_OPEN_SCOPE
67 typedef typename Type::key_type key_type;
68 typedef typename Type::mapped_type mapped_type;
69 typedef typename Type::value_type value_type;
119 template <
class T,
class _ValuePolicy = SdfIdentityMapEditProxyValuePolicy<T> >
121 boost::totally_ordered<SdfMapEditProxy<T, _ValuePolicy>, T> {
124 typedef _ValuePolicy ValuePolicy;
126 typedef typename Type::key_type key_type;
127 typedef typename Type::mapped_type mapped_type;
128 typedef typename Type::value_type value_type;
150 typedef typename Type::iterator inner_iterator;
151 typedef typename Type::const_iterator const_inner_iterator;
155 _ValueProxy(
This* owner,
const Type* data, inner_iterator i) :
156 _owner(owner), _data(data), _pos(i)
162 _ValueProxy& operator=(
const U& other)
167 _owner->_Set(_data, _pos, other);
172 operator mapped_type()
const 178 mapped_type Get()
const 182 return mapped_type();
184 return _owner->_Get(_data, _pos);
195 explicit _PairProxy(
This* owner,
const Type* data, inner_iterator i) :
196 first(i->first), second(_ValueProxy(owner, data, i)) { }
198 const key_type first;
201 operator value_type()
const 208 return value_type(first, second.Get());
214 static _PairProxy Dereference(
This* owner,
215 const Type* data, inner_iterator i)
220 return _PairProxy(owner, data, i);
223 static const value_type& Dereference(
const This* owner,
225 const_inner_iterator i)
230 return owner->_Get(data, i);
234 template <
class Owner,
class I,
class R>
236 public boost::iterator_facade<_Iterator<Owner, I, R>, R,
237 std::bidirectional_iterator_tag, R> {
240 _owner(NULL), _data(NULL) { }
242 _Iterator(Owner owner,
const Type* data, I i) :
243 _owner(owner), _data(data), _pos(i)
248 template <
class Owner2,
class I2,
class R2>
249 _Iterator(
const _Iterator<Owner2, I2, R2>& other) :
250 _owner(other._owner), _data(other._data), _pos(other._pos)
255 const I& base()
const 261 R dereference()
const 263 return Traits::Dereference(_owner, _data, _pos);
266 template <
class Owner2,
class I2,
class R2>
267 bool equal(
const _Iterator<Owner2, I2, R2>& other)
const 269 if (_owner == other._owner && _pos == other._pos) {
274 return atEnd() && other.atEnd();
288 return !_owner || _pos == _owner->_ConstData()->end();
296 friend class boost::iterator_core_access;
297 template <
class Owner2,
class I2,
class R2>
friend class _Iterator;
301 typedef _ValueProxy reference;
302 typedef const value_type& const_reference;
303 typedef size_t size_type;
304 typedef ptrdiff_t difference_type;
305 typedef _Iterator<This*, inner_iterator, _PairProxy> iterator;
306 typedef _Iterator<
const This*, const_inner_iterator,
307 const value_type&> const_iterator;
308 typedef boost::reverse_iterator<iterator> reverse_iterator;
309 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
312 _editor(Sdf_CreateMapEditor<T>(owner, field))
324 if (other._Validate()) {
325 _Copy(*other._ConstData());
330 template <
class U,
class UVP>
333 if (other._Validate()) {
334 _Copy(Type(other._ConstData()->begin(), other._ConstData()->end()));
339 This& operator=(
const Type& data)
346 operator Type()
const 348 return _Validate() ? *_ConstData() : Type();
353 return _Validate() ? iterator(
this, _Data(), _Data()->begin()) :
358 return _Validate() ? iterator(
this, _Data(), _Data()->end()) :
361 const_iterator begin()
const 364 const_iterator(
this, _ConstData(), _ConstData()->begin()) :
367 const_iterator end()
const 370 const_iterator(
this, _ConstData(), _ConstData()->end()) :
374 reverse_iterator rbegin()
376 return reverse_iterator(end());
378 reverse_iterator rend()
380 return reverse_iterator(begin());
382 const_reverse_iterator rbegin()
const 384 return const_reverse_iterator(end());
386 const_reverse_iterator rend()
const 388 return const_reverse_iterator(begin());
391 size_type size()
const 393 return _Validate() ? _ConstData()->size() : 0;
396 size_type max_size()
const 398 return _Validate() ? _ConstData()->max_size() : 0;
403 return _Validate() ? _ConstData()->empty() :
true;
406 std::pair<iterator, bool> insert(
const value_type& value)
408 return _Insert(value);
411 iterator insert(iterator pos,
const value_type& value)
413 return _Insert(value).first;
416 template <
class InputIterator>
417 void insert(InputIterator first, InputIterator last)
421 for (; first != last; ++first) {
422 const value_type& v =
423 ValuePolicy::CanonicalizePair(_Owner(), *first);
425 if (_ValidateInsert(v)) {
432 void erase(iterator pos)
434 if (_Validate() && _ValidateErase(pos->first)) {
439 size_type erase(
const key_type& key)
442 const key_type& k = ValuePolicy::CanonicalizeKey(_Owner(), key);
443 if (_ValidateErase(k)) {
444 return _editor->Erase(k) ? 1 : 0;
450 void erase(iterator first, iterator last)
454 while (first != last) {
455 const key_type& key = first->first;
457 if (_ValidateErase(key)) {
469 iterator find(
const key_type& key)
473 iterator(
this, _Data(),
474 _Data()->find(ValuePolicy::CanonicalizeKey(_Owner(), key))) :
478 const_iterator find(
const key_type& key)
const 482 const_iterator(
this, _ConstData(),
484 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
488 size_type count(
const key_type& key)
const 493 ValuePolicy::CanonicalizeKey(_Owner(), key)) :
497 iterator lower_bound(
const key_type& key)
501 iterator(
this, _Data(),
502 _Data()->lower_bound(
503 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
507 const_iterator lower_bound(
const key_type& key)
const 511 const_iterator(
this, _ConstData(),
512 _ConstData()->lower_bound(
513 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
517 iterator upper_bound(
const key_type& key)
521 iterator(
this, _Data(),
522 _Data()->upper_bound(
523 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
527 const_iterator upper_bound(
const key_type& key)
const 531 const_iterator(
this, _ConstData(),
532 _ConstData()->upper_bound(
533 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
537 std::pair<iterator, iterator> equal_range(
const key_type& key)
540 std::pair<inner_iterator, inner_iterator> result =
541 _Data()->equal_range(
542 ValuePolicy::CanonicalizeKey(_Owner(), key));
543 return std::make_pair(iterator(
this, _Data(), result.first),
544 iterator(
this, _Data(), result.second));
547 return std::make_pair(iterator(), iterator());
551 std::pair<const_iterator,const_iterator>
552 equal_range(
const key_type& key)
const 555 std::pair<const_inner_iterator, const_inner_iterator> result =
556 _ConstData()->equal_range(
557 ValuePolicy::CanonicalizeKey(_Owner(), key));
558 return std::make_pair(
559 const_iterator(
this, _ConstData(), result.first),
560 const_iterator(
this, _ConstData(), result.second));
563 return std::make_pair(const_iterator(), const_iterator());
567 reference operator[](
const key_type& key)
569 auto iter = _Insert(value_type(key, mapped_type())).first;
570 bool failed = iter == iterator();
571 return reference(failed ?
nullptr :
this,
572 failed ?
nullptr : _Data(),
578 return _Validate() ? _CompareEqual(other) : false;
581 bool operator<(
const Type& other)
const 583 return _Validate() ? _Compare(other) < 0 :
false;
586 bool operator>(
const Type& other)
const 588 return _Validate() ? _Compare(other) > 0 :
false;
591 template <
class U,
class UVP>
594 return _Validate() && other._Validate() ?
595 _CompareEqual(*other._ConstData()) :
false;
598 template <
class U,
class UVP>
601 return !(*
this == other);
604 template <
class U,
class UVP>
607 return _Validate() && other._Validate() ?
608 _Compare(*other._ConstData()) < 0 :
false;
611 template <
class U,
class UVP>
614 return _Validate() && other._Validate() ?
615 _Compare(*other._ConstData()) <= 0 :
false;
618 template <
class U,
class UVP>
621 return !(*
this <= other);
624 template <
class U,
class UVP>
627 return !(*
this < other);
634 return _editor && _editor->IsExpired();
639 explicit operator bool()
const 656 bool _Validate()
const 669 return _editor ? _editor->GetData() : NULL;
672 const Type* _ConstData()
const 674 return _editor ? _editor->GetData() : NULL;
677 SdfSpecHandle _Owner()
const 679 return _editor ? _editor->GetOwner() : SdfSpecHandle();
682 std::string _Location()
const 684 return _editor ? _editor->GetLocation() : std::string();
687 bool _CompareEqual(
const Type& other)
const 689 if (_ConstData()->size() < other.size()) {
692 if (_ConstData()->size() > other.size()) {
697 const Type& x = ValuePolicy::CanonicalizeType(_Owner(), other);
698 std::pair<const_inner_iterator, const_inner_iterator> result =
699 std::mismatch(_ConstData()->begin(), _ConstData()->end(),
701 return result.first == _ConstData()->end();
704 int _Compare(
const Type& other)
const 706 if (_ConstData()->size() < other.size()) {
709 if (_ConstData()->size() > other.size()) {
714 const Type& x = ValuePolicy::CanonicalizeType(_Owner(), other);
715 std::pair<const_inner_iterator, const_inner_iterator> result =
716 std::mismatch(_ConstData()->begin(), _ConstData()->end(),
718 if (*result.first < *result.second) {
721 else if (*result.first > *result.second) {
730 bool _CompareEqual(
const D& other)
const 733 return _CompareEqual(Type(other.begin(), other.end()));
737 int _Compare(
const D& other)
const 740 return _Compare(Type(other.begin(), other.end()));
743 mapped_type _Get(
const Type* data,
const inner_iterator& i)
746 if (data == _ConstData()) {
752 return _ConstData()->find(i->first)->second;
755 return mapped_type();
758 const value_type& _Get(
const Type* data,
759 const const_inner_iterator& i)
const 763 return (data == _ConstData()) ? *i : *_ConstData()->find(i->first);
766 void _Copy(
const Type& other)
776 const value_type canonicalValue =
777 ValuePolicy::CanonicalizePair(_Owner(), *it);
778 if (!canonicalOther.insert(canonicalValue).second) {
787 if (_ValidateCopy(canonicalOther)) {
788 _editor->Copy(canonicalOther);
793 bool _ValidateCopy(
const Type& other)
795 SdfSpecHandle owner = _Owner();
796 if (owner && !owner->PermissionToEdit()) {
798 _Location().c_str());
807 if (!_ValidateInsert(*it)) {
816 void _Set(
const Type* data,
const inner_iterator& i,
const U& value)
819 const mapped_type& x =
820 ValuePolicy::CanonicalizeValue(_Owner(), value);
821 if (_ValidateSet(i->first, x)) {
822 _editor->Set(i->first, x);
827 bool _ValidateSet(
const key_type& key,
const mapped_type& value)
829 SdfSpecHandle owner = _Owner();
830 if (owner && !owner->PermissionToEdit()) {
832 _Location().c_str());
836 if (
SdfAllowed allowed = _editor->IsValidValue(value)) {
842 allowed.GetWhyNot().c_str());
849 std::pair<iterator, bool> _Insert(
const value_type& value)
852 const value_type& v = ValuePolicy::CanonicalizePair(_Owner(), value);
853 if (_ValidateInsert(v)) {
854 std::pair<inner_iterator, bool> status = _editor->Insert(v);
855 return std::make_pair(iterator(
this, _Data(), status.first),
859 return std::make_pair(iterator(),
false);
862 return std::make_pair(iterator(),
false);
865 bool _ValidateInsert(
const value_type& value)
867 SdfSpecHandle owner = _Owner();
868 if (owner && !owner->PermissionToEdit()) {
870 _Location().c_str());
874 if (
SdfAllowed allowed = _editor->IsValidKey(value.first)) {
880 allowed.GetWhyNot().c_str());
884 if (
SdfAllowed allowed = _editor->IsValidValue(value.second)) {
890 allowed.GetWhyNot().c_str());
897 void _Erase(
const key_type& key)
899 if (_Validate() && _ValidateErase(key)) {
904 bool _ValidateErase(
const key_type& key)
906 SdfSpecHandle owner = _Owner();
907 if (owner && !owner->PermissionToEdit()) {
909 _Location().c_str());
917 template <
class ProxyT>
friend class SdfPyWrapMapEditProxy;
919 std::shared_ptr<Sdf_MapEditor<T> > _editor;
923 template <
class T,
class _ValuePolicy>
925 static Vt_DefaultValueHolder Invoke() =
delete;
928 PXR_NAMESPACE_CLOSE_SCOPE
930 #endif // PXR_USD_SDF_MAP_EDIT_PROXY_H static const value_type & CanonicalizePair(const SdfSpecHandle &, const value_type &x)
Canonicalize a key/value pair.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Base class for all Sdf spec classes.
Low-level utilities for informing users of various internal and external diagnostic conditions.
static const key_type & CanonicalizeKey(const SdfSpecHandle &, const key_type &x)
Canonicalize a key.
static const mapped_type & CanonicalizeValue(const SdfSpecHandle &, const mapped_type &x)
Canonicalize a value.
Token for efficient comparison, assignment, and hashing of known strings.
Indicates if an operation is allowed and, if not, why not.
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
bool IsExpired() const
Returns true if the value is expired.
A proxy for editing map-like values.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
A value policy for SdfMapEditProxy that does nothing.
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
static const Type & CanonicalizeType(const SdfSpecHandle &, const Type &x)
Canonicalize an entire Type object.
std::enable_if<!std::is_enum< T >::value, std::string >::type TfStringify(const T &v)
Convert an arbitrary type into a string.