7#ifndef PXR_USD_SDF_MAP_EDIT_PROXY_H
8#define PXR_USD_SDF_MAP_EDIT_PROXY_H
14#include "pxr/usd/sdf/changeBlock.h"
16#include "pxr/usd/sdf/mapEditor.h"
19#include "pxr/base/vt/value.h"
26PXR_NAMESPACE_OPEN_SCOPE
48 typedef typename Type::key_type key_type;
49 typedef typename Type::mapped_type mapped_type;
50 typedef typename Type::value_type value_type;
100template <
class T,
class _ValuePolicy = SdfIdentityMapEditProxyValuePolicy<T> >
104 typedef _ValuePolicy ValuePolicy;
106 typedef typename Type::key_type key_type;
107 typedef typename Type::mapped_type mapped_type;
108 typedef typename Type::value_type value_type;
130 typedef typename Type::iterator inner_iterator;
131 typedef typename Type::const_iterator const_inner_iterator;
135 _ValueProxy(
This* owner,
const Type* data, inner_iterator i) :
136 _owner(owner), _data(data), _pos(i)
142 _ValueProxy& operator=(
const U& other)
147 _owner->_Set(_data, _pos, other);
152 operator mapped_type()
const
158 mapped_type Get()
const
162 return mapped_type();
164 return _owner->_Get(_data, _pos);
175 explicit _PairProxy(
This* owner,
const Type* data, inner_iterator i) :
176 first(i->first), second(_ValueProxy(owner, data, i)) { }
178 const key_type first;
181 operator value_type()
const
188 return value_type(first, second.Get());
194 static _PairProxy Dereference(
This* owner,
195 const Type* data, inner_iterator i)
200 return _PairProxy(owner, data, i);
203 static const value_type& Dereference(
const This* owner,
205 const_inner_iterator i)
210 return owner->_Get(data, i);
214 template <
class Owner,
class I,
class R>
218 std::add_pointer_t<R> operator->() {
219 return std::addressof(_result);
222 friend class _Iterator;
223 explicit _PtrProxy(
const R& result) : _result(result) {}
227 using iterator_category = std::bidirectional_iterator_tag;
228 using value_type = R;
230 using pointer = std::conditional_t<std::is_lvalue_reference<R>::value,
231 std::add_pointer_t<R>, _PtrProxy>;
232 using difference_type = std::ptrdiff_t;
234 _Iterator() =
default;
236 _Iterator(Owner owner,
const Type* data, I i) :
237 _owner(owner), _data(data), _pos(i)
242 template <
class Owner2,
class I2,
class R2>
243 _Iterator(
const _Iterator<Owner2, I2, R2>& other) :
244 _owner(other._owner), _data(other._data), _pos(other._pos)
249 reference operator*()
const {
return dereference(); }
255 template <
typename PointerType=pointer,
256 typename std::enable_if_t<
257 std::is_pointer<PointerType>::value,
int> = 0>
258 pointer operator->()
const {
return std::addressof(dereference()); }
259 template <
typename PointerType=pointer,
260 typename std::enable_if_t<
261 !std::is_pointer<PointerType>::value,
int> = 0>
262 pointer operator->()
const {
return pointer(dereference()); }
265 const I& base()
const
270 _Iterator& operator++() {
275 _Iterator& operator--() {
280 _Iterator operator++(
int) {
281 _Iterator result(*
this);
286 _Iterator operator--(
int) {
287 _Iterator result(*
this);
292 template <
class Owner2,
class I2,
class R2>
293 bool operator==(
const _Iterator<Owner2, I2, R2>& other)
const {
297 template <
class Owner2,
class I2,
class R2>
298 bool operator!=(
const _Iterator<Owner2, I2, R2>& other)
const {
299 return !equal(other);
303 R dereference()
const
305 return Traits::Dereference(_owner, _data, _pos);
308 template <
class Owner2,
class I2,
class R2>
309 bool equal(
const _Iterator<Owner2, I2, R2>& other)
const
311 if (_owner == other._owner && _pos == other._pos) {
316 return atEnd() && other.atEnd();
330 return !_owner || _pos == _owner->_ConstData()->end();
334 Owner _owner =
nullptr;
335 const Type* _data =
nullptr;
338 template <
class Owner2,
class I2,
class R2>
friend class _Iterator;
342 typedef _ValueProxy reference;
343 typedef const value_type& const_reference;
344 typedef size_t size_type;
345 typedef ptrdiff_t difference_type;
346 typedef _Iterator<This*, inner_iterator, _PairProxy> iterator;
347 typedef _Iterator<
const This*, const_inner_iterator,
348 const value_type&> const_iterator;
349 typedef Tf_ProxyReferenceReverseIterator<iterator> reverse_iterator;
350 typedef Tf_ProxyReferenceReverseIterator<const_iterator> const_reverse_iterator;
353 _editor(Sdf_CreateMapEditor<T>(owner, field))
365 if (other._Validate()) {
366 _Copy(*other._ConstData());
371 template <
class U,
class UVP>
374 if (other._Validate()) {
375 _Copy(Type(other._ConstData()->begin(), other._ConstData()->end()));
380 This& operator=(
const Type& data)
387 operator Type()
const
389 return _Validate() ? *_ConstData() : Type();
394 return _Validate() ? iterator(
this, _Data(), _Data()->begin()) :
399 return _Validate() ? iterator(
this, _Data(), _Data()->end()) :
402 const_iterator begin()
const
405 const_iterator(
this, _ConstData(), _ConstData()->begin()) :
408 const_iterator end()
const
411 const_iterator(
this, _ConstData(), _ConstData()->end()) :
415 reverse_iterator rbegin()
417 return reverse_iterator(end());
419 reverse_iterator rend()
421 return reverse_iterator(begin());
423 const_reverse_iterator rbegin()
const
425 return const_reverse_iterator(end());
427 const_reverse_iterator rend()
const
429 return const_reverse_iterator(begin());
432 size_type size()
const
434 return _Validate() ? _ConstData()->size() : 0;
437 size_type max_size()
const
439 return _Validate() ? _ConstData()->max_size() : 0;
444 return _Validate() ? _ConstData()->empty() :
true;
447 std::pair<iterator, bool> insert(
const value_type& value)
449 return _Insert(value);
452 iterator insert(iterator pos,
const value_type& value)
454 return _Insert(value).first;
457 template <
class InputIterator>
458 void insert(InputIterator first, InputIterator last)
462 for (; first != last; ++first) {
463 const value_type& v =
464 ValuePolicy::CanonicalizePair(_Owner(), *first);
466 if (_ValidateInsert(v)) {
473 void erase(iterator pos)
475 if (_Validate() && _ValidateErase(pos->first)) {
480 size_type erase(
const key_type& key)
483 const key_type& k = ValuePolicy::CanonicalizeKey(_Owner(), key);
484 if (_ValidateErase(k)) {
485 return _editor->Erase(k) ? 1 : 0;
491 void erase(iterator first, iterator last)
495 while (first != last) {
496 const key_type& key = first->first;
498 if (_ValidateErase(key)) {
510 iterator find(
const key_type& key)
514 iterator(
this, _Data(),
515 _Data()->find(ValuePolicy::CanonicalizeKey(_Owner(), key))) :
519 const_iterator find(
const key_type& key)
const
523 const_iterator(
this, _ConstData(),
525 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
529 size_type count(
const key_type& key)
const
534 ValuePolicy::CanonicalizeKey(_Owner(), key)) :
538 iterator lower_bound(
const key_type& key)
542 iterator(
this, _Data(),
543 _Data()->lower_bound(
544 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
548 const_iterator lower_bound(
const key_type& key)
const
552 const_iterator(
this, _ConstData(),
553 _ConstData()->lower_bound(
554 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
558 iterator upper_bound(
const key_type& key)
562 iterator(
this, _Data(),
563 _Data()->upper_bound(
564 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
568 const_iterator upper_bound(
const key_type& key)
const
572 const_iterator(
this, _ConstData(),
573 _ConstData()->upper_bound(
574 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
578 std::pair<iterator, iterator> equal_range(
const key_type& key)
581 std::pair<inner_iterator, inner_iterator> result =
582 _Data()->equal_range(
583 ValuePolicy::CanonicalizeKey(_Owner(), key));
584 return std::make_pair(iterator(
this, _Data(), result.first),
585 iterator(
this, _Data(), result.second));
588 return std::make_pair(iterator(), iterator());
592 std::pair<const_iterator,const_iterator>
593 equal_range(
const key_type& key)
const
596 std::pair<const_inner_iterator, const_inner_iterator> result =
597 _ConstData()->equal_range(
598 ValuePolicy::CanonicalizeKey(_Owner(), key));
599 return std::make_pair(
600 const_iterator(
this, _ConstData(), result.first),
601 const_iterator(
this, _ConstData(), result.second));
604 return std::make_pair(const_iterator(), const_iterator());
608 reference operator[](
const key_type& key)
610 auto iter = _Insert(value_type(key, mapped_type())).first;
611 bool failed = iter == iterator();
612 return reference(failed ?
nullptr :
this,
613 failed ?
nullptr : _Data(),
617 bool operator==(
const Type& other)
const
619 return _Validate() ? _CompareEqual(other) : false;
622 bool operator!=(
const Type& other)
const
624 return !(*
this == other);
641 return !_Validate() || _Compare(other) < 0;
644 bool operator>(
const Type& other)
const
646 return _Validate() ? _Compare(other) > 0 :
false;
649 bool operator>=(
const Type& other)
const
651 return !(*
this < other);
654 bool operator<=(
const Type& other)
const
656 return !(*
this > other);
681 template <
class U,
class UVP>
684 const bool isValid = _Validate();
685 const bool otherIsValid = other._Validate();
687 return isValid && otherIsValid ?
688 _CompareEqual(*other._ConstData()) : isValid == otherIsValid;
691 template <
class U,
class UVP>
694 return !(*
this == other);
697 template <
class U,
class UVP>
700 return _Validate() && other._Validate() ?
701 _Compare(*other._ConstData()) < 0 :
false;
704 template <
class U,
class UVP>
707 return _Validate() && other._Validate() ?
708 _Compare(*other._ConstData()) <= 0 :
false;
711 template <
class U,
class UVP>
714 return !(*
this <= other);
717 template <
class U,
class UVP>
720 return !(*
this < other);
727 return _editor && _editor->IsExpired();
732 explicit operator bool()
const
749 bool _Validate()
const
762 return _editor ? _editor->GetData() : NULL;
765 const Type* _ConstData()
const
767 return _editor ? _editor->GetData() : NULL;
770 SdfSpecHandle _Owner()
const
772 return _editor ? _editor->GetOwner() : SdfSpecHandle();
775 std::string _Location()
const
777 return _editor ? _editor->GetLocation() : std::string();
780 bool _CompareEqual(
const Type& other)
const
782 if (_ConstData()->size() < other.size()) {
785 if (_ConstData()->size() > other.size()) {
790 const Type& x = ValuePolicy::CanonicalizeType(_Owner(), other);
791 std::pair<const_inner_iterator, const_inner_iterator> result =
792 std::mismatch(_ConstData()->begin(), _ConstData()->end(),
794 return result.first == _ConstData()->end();
797 int _Compare(
const Type& other)
const
799 if (_ConstData()->size() < other.size()) {
802 if (_ConstData()->size() > other.size()) {
807 const Type& x = ValuePolicy::CanonicalizeType(_Owner(), other);
808 std::pair<const_inner_iterator, const_inner_iterator> result =
809 std::mismatch(_ConstData()->begin(), _ConstData()->end(),
811 if (*result.first < *result.second) {
814 else if (*result.first > *result.second) {
823 bool _CompareEqual(
const D& other)
const
826 return _CompareEqual(Type(other.begin(), other.end()));
830 int _Compare(
const D& other)
const
833 return _Compare(Type(other.begin(), other.end()));
836 mapped_type _Get(
const Type* data,
const inner_iterator& i)
839 if (data == _ConstData()) {
845 return _ConstData()->find(i->first)->second;
848 return mapped_type();
851 const value_type& _Get(
const Type* data,
852 const const_inner_iterator& i)
const
856 return (data == _ConstData()) ? *i : *_ConstData()->find(i->first);
859 void _Copy(
const Type& other)
869 const value_type canonicalValue =
870 ValuePolicy::CanonicalizePair(_Owner(), *it);
871 if (!canonicalOther.insert(canonicalValue).second) {
880 if (_ValidateCopy(canonicalOther)) {
881 _editor->Copy(canonicalOther);
886 bool _ValidateCopy(
const Type& other)
888 SdfSpecHandle owner = _Owner();
889 if (owner && !owner->PermissionToEdit()) {
891 _Location().c_str());
900 if (!_ValidateInsert(*it)) {
909 void _Set(
const Type* data,
const inner_iterator& i,
const U& value)
912 const mapped_type& x =
913 ValuePolicy::CanonicalizeValue(_Owner(), value);
914 if (_ValidateSet(i->first, x)) {
915 _editor->Set(i->first, x);
920 bool _ValidateSet(
const key_type& key,
const mapped_type& value)
922 SdfSpecHandle owner = _Owner();
923 if (owner && !owner->PermissionToEdit()) {
925 _Location().c_str());
929 if (
SdfAllowed allowed = _editor->IsValidValue(value)) {
935 allowed.GetWhyNot().c_str());
942 std::pair<iterator, bool> _Insert(
const value_type& value)
945 const value_type& v = ValuePolicy::CanonicalizePair(_Owner(), value);
946 if (_ValidateInsert(v)) {
947 std::pair<inner_iterator, bool> status = _editor->Insert(v);
948 return std::make_pair(iterator(
this, _Data(), status.first),
952 return std::make_pair(iterator(),
false);
955 return std::make_pair(iterator(),
false);
958 bool _ValidateInsert(
const value_type& value)
960 SdfSpecHandle owner = _Owner();
961 if (owner && !owner->PermissionToEdit()) {
963 _Location().c_str());
967 if (
SdfAllowed allowed = _editor->IsValidKey(value.first)) {
973 allowed.GetWhyNot().c_str());
977 if (
SdfAllowed allowed = _editor->IsValidValue(value.second)) {
983 allowed.GetWhyNot().c_str());
990 void _Erase(
const key_type& key)
992 if (_Validate() && _ValidateErase(key)) {
997 bool _ValidateErase(
const key_type& key)
999 SdfSpecHandle owner = _Owner();
1000 if (owner && !owner->PermissionToEdit()) {
1002 _Location().c_str());
1010 template <
class ProxyT>
friend class SdfPyWrapMapEditProxy;
1012 std::shared_ptr<Sdf_MapEditor<T> > _editor;
1016template <
class T,
class _ValuePolicy>
1018 static Vt_DefaultValueHolder Invoke() =
delete;
1021PXR_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.
A value policy for SdfMapEditProxy that does nothing.
static const value_type & CanonicalizePair(const SdfSpecHandle &, const value_type &x)
Canonicalize a key/value pair.
static const mapped_type & CanonicalizeValue(const SdfSpecHandle &, const mapped_type &x)
Canonicalize a value.
static const key_type & CanonicalizeKey(const SdfSpecHandle &, const key_type &x)
Canonicalize a key.
static const Type & CanonicalizeType(const SdfSpecHandle &, const Type &x)
Canonicalize an entire Type object.
A proxy for editing map-like values.
bool IsExpired() const
Returns true if the value is expired.
bool operator<(const Type &other) const
Invalid SdfMapEditProxy objects will compare less to an object of their map type.
bool operator==(const SdfMapEditProxy< U, UVP > &other) const
Comparison operator with another proxy Two invalid proxy objects will compare equal.
Base class for all Sdf spec classes.
Token for efficient comparison, assignment, and hashing of known strings.
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
std::string TfStringify(const T &v)
Convert an arbitrary type into a string.