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"
43PXR_NAMESPACE_OPEN_SCOPE
65 typedef typename Type::key_type key_type;
66 typedef typename Type::mapped_type mapped_type;
67 typedef typename Type::value_type value_type;
117template <
class T,
class _ValuePolicy = SdfIdentityMapEditProxyValuePolicy<T> >
121 typedef _ValuePolicy ValuePolicy;
123 typedef typename Type::key_type key_type;
124 typedef typename Type::mapped_type mapped_type;
125 typedef typename Type::value_type value_type;
147 typedef typename Type::iterator inner_iterator;
148 typedef typename Type::const_iterator const_inner_iterator;
152 _ValueProxy(
This* owner,
const Type* data, inner_iterator i) :
153 _owner(owner), _data(data), _pos(i)
159 _ValueProxy& operator=(
const U& other)
164 _owner->_Set(_data, _pos, other);
169 operator mapped_type()
const
175 mapped_type Get()
const
179 return mapped_type();
181 return _owner->_Get(_data, _pos);
192 explicit _PairProxy(
This* owner,
const Type* data, inner_iterator i) :
193 first(i->first), second(_ValueProxy(owner, data, i)) { }
195 const key_type first;
198 operator value_type()
const
205 return value_type(first, second.Get());
211 static _PairProxy Dereference(
This* owner,
212 const Type* data, inner_iterator i)
217 return _PairProxy(owner, data, i);
220 static const value_type& Dereference(
const This* owner,
222 const_inner_iterator i)
227 return owner->_Get(data, i);
231 template <
class Owner,
class I,
class R>
235 std::add_pointer_t<R> operator->() {
236 return std::addressof(_result);
239 friend class _Iterator;
240 explicit _PtrProxy(
const R& result) : _result(result) {}
244 using iterator_category = std::bidirectional_iterator_tag;
245 using value_type = R;
247 using pointer = std::conditional_t<std::is_lvalue_reference<R>::value,
248 std::add_pointer_t<R>, _PtrProxy>;
249 using difference_type = std::ptrdiff_t;
251 _Iterator() =
default;
253 _Iterator(Owner owner,
const Type* data, I i) :
254 _owner(owner), _data(data), _pos(i)
259 template <
class Owner2,
class I2,
class R2>
260 _Iterator(
const _Iterator<Owner2, I2, R2>& other) :
261 _owner(other._owner), _data(other._data), _pos(other._pos)
266 reference operator*()
const {
return dereference(); }
272 template <
typename PointerType=pointer,
273 typename std::enable_if_t<
274 std::is_pointer<PointerType>::value,
int> = 0>
275 pointer operator->()
const {
return std::addressof(dereference()); }
276 template <
typename PointerType=pointer,
277 typename std::enable_if_t<
278 !std::is_pointer<PointerType>::value,
int> = 0>
279 pointer operator->()
const {
return pointer(dereference()); }
282 const I& base()
const
287 _Iterator& operator++() {
292 _Iterator& operator--() {
297 _Iterator operator++(
int) {
298 _Iterator result(*
this);
303 _Iterator operator--(
int) {
304 _Iterator result(*
this);
309 template <
class Owner2,
class I2,
class R2>
310 bool operator==(
const _Iterator<Owner2, I2, R2>& other)
const {
314 template <
class Owner2,
class I2,
class R2>
315 bool operator!=(
const _Iterator<Owner2, I2, R2>& other)
const {
316 return !equal(other);
320 R dereference()
const
322 return Traits::Dereference(_owner, _data, _pos);
325 template <
class Owner2,
class I2,
class R2>
326 bool equal(
const _Iterator<Owner2, I2, R2>& other)
const
328 if (_owner == other._owner && _pos == other._pos) {
333 return atEnd() && other.atEnd();
347 return !_owner || _pos == _owner->_ConstData()->end();
351 Owner _owner =
nullptr;
352 const Type* _data =
nullptr;
355 template <
class Owner2,
class I2,
class R2>
friend class _Iterator;
359 typedef _ValueProxy reference;
360 typedef const value_type& const_reference;
361 typedef size_t size_type;
362 typedef ptrdiff_t difference_type;
363 typedef _Iterator<This*, inner_iterator, _PairProxy> iterator;
364 typedef _Iterator<
const This*, const_inner_iterator,
365 const value_type&> const_iterator;
366 typedef Tf_ProxyReferenceReverseIterator<iterator> reverse_iterator;
367 typedef Tf_ProxyReferenceReverseIterator<const_iterator> const_reverse_iterator;
370 _editor(Sdf_CreateMapEditor<T>(owner, field))
382 if (other._Validate()) {
383 _Copy(*other._ConstData());
388 template <
class U,
class UVP>
391 if (other._Validate()) {
392 _Copy(Type(other._ConstData()->begin(), other._ConstData()->end()));
397 This& operator=(
const Type& data)
404 operator Type()
const
406 return _Validate() ? *_ConstData() : Type();
411 return _Validate() ? iterator(
this, _Data(), _Data()->begin()) :
416 return _Validate() ? iterator(
this, _Data(), _Data()->end()) :
419 const_iterator begin()
const
422 const_iterator(
this, _ConstData(), _ConstData()->begin()) :
425 const_iterator end()
const
428 const_iterator(
this, _ConstData(), _ConstData()->end()) :
432 reverse_iterator rbegin()
434 return reverse_iterator(end());
436 reverse_iterator rend()
438 return reverse_iterator(begin());
440 const_reverse_iterator rbegin()
const
442 return const_reverse_iterator(end());
444 const_reverse_iterator rend()
const
446 return const_reverse_iterator(begin());
449 size_type size()
const
451 return _Validate() ? _ConstData()->size() : 0;
454 size_type max_size()
const
456 return _Validate() ? _ConstData()->max_size() : 0;
461 return _Validate() ? _ConstData()->empty() :
true;
464 std::pair<iterator, bool> insert(
const value_type& value)
466 return _Insert(value);
469 iterator insert(iterator pos,
const value_type& value)
471 return _Insert(value).first;
474 template <
class InputIterator>
475 void insert(InputIterator first, InputIterator last)
479 for (; first != last; ++first) {
480 const value_type& v =
481 ValuePolicy::CanonicalizePair(_Owner(), *first);
483 if (_ValidateInsert(v)) {
490 void erase(iterator pos)
492 if (_Validate() && _ValidateErase(pos->first)) {
497 size_type erase(
const key_type& key)
500 const key_type& k = ValuePolicy::CanonicalizeKey(_Owner(), key);
501 if (_ValidateErase(k)) {
502 return _editor->Erase(k) ? 1 : 0;
508 void erase(iterator first, iterator last)
512 while (first != last) {
513 const key_type& key = first->first;
515 if (_ValidateErase(key)) {
527 iterator find(
const key_type& key)
531 iterator(
this, _Data(),
532 _Data()->find(ValuePolicy::CanonicalizeKey(_Owner(), key))) :
536 const_iterator find(
const key_type& key)
const
540 const_iterator(
this, _ConstData(),
542 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
546 size_type count(
const key_type& key)
const
551 ValuePolicy::CanonicalizeKey(_Owner(), key)) :
555 iterator lower_bound(
const key_type& key)
559 iterator(
this, _Data(),
560 _Data()->lower_bound(
561 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
565 const_iterator lower_bound(
const key_type& key)
const
569 const_iterator(
this, _ConstData(),
570 _ConstData()->lower_bound(
571 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
575 iterator upper_bound(
const key_type& key)
579 iterator(
this, _Data(),
580 _Data()->upper_bound(
581 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
585 const_iterator upper_bound(
const key_type& key)
const
589 const_iterator(
this, _ConstData(),
590 _ConstData()->upper_bound(
591 ValuePolicy::CanonicalizeKey(_Owner(), key))) :
595 std::pair<iterator, iterator> equal_range(
const key_type& key)
598 std::pair<inner_iterator, inner_iterator> result =
599 _Data()->equal_range(
600 ValuePolicy::CanonicalizeKey(_Owner(), key));
601 return std::make_pair(iterator(
this, _Data(), result.first),
602 iterator(
this, _Data(), result.second));
605 return std::make_pair(iterator(), iterator());
609 std::pair<const_iterator,const_iterator>
610 equal_range(
const key_type& key)
const
613 std::pair<const_inner_iterator, const_inner_iterator> result =
614 _ConstData()->equal_range(
615 ValuePolicy::CanonicalizeKey(_Owner(), key));
616 return std::make_pair(
617 const_iterator(
this, _ConstData(), result.first),
618 const_iterator(
this, _ConstData(), result.second));
621 return std::make_pair(const_iterator(), const_iterator());
625 reference operator[](
const key_type& key)
627 auto iter = _Insert(value_type(key, mapped_type())).first;
628 bool failed = iter == iterator();
629 return reference(failed ?
nullptr :
this,
630 failed ?
nullptr : _Data(),
634 bool operator==(
const Type& other)
const
636 return _Validate() ? _CompareEqual(other) : false;
639 bool operator!=(
const Type& other)
const
641 return !(*
this == other);
654 bool operator<(
const Type& other)
const
656 return _Validate() ? _Compare(other) < 0 :
false;
659 bool operator>(
const Type& other)
const
661 return _Validate() ? _Compare(other) > 0 :
false;
664 bool operator>=(
const Type& other)
const
666 return !(*
this < other);
669 bool operator<=(
const Type& other)
const
671 return !(*
this > other);
694 template <
class U,
class UVP>
697 return _Validate() && other._Validate() ?
698 _CompareEqual(*other._ConstData()) : false;
701 template <
class U,
class UVP>
704 return !(*
this == other);
707 template <
class U,
class UVP>
710 return _Validate() && other._Validate() ?
711 _Compare(*other._ConstData()) < 0 :
false;
714 template <
class U,
class UVP>
717 return _Validate() && other._Validate() ?
718 _Compare(*other._ConstData()) <= 0 :
false;
721 template <
class U,
class UVP>
724 return !(*
this <= other);
727 template <
class U,
class UVP>
730 return !(*
this < other);
737 return _editor && _editor->IsExpired();
742 explicit operator bool()
const
759 bool _Validate()
const
772 return _editor ? _editor->GetData() : NULL;
775 const Type* _ConstData()
const
777 return _editor ? _editor->GetData() : NULL;
780 SdfSpecHandle _Owner()
const
782 return _editor ? _editor->GetOwner() : SdfSpecHandle();
785 std::string _Location()
const
787 return _editor ? _editor->GetLocation() : std::string();
790 bool _CompareEqual(
const Type& other)
const
792 if (_ConstData()->size() < other.size()) {
795 if (_ConstData()->size() > other.size()) {
800 const Type& x = ValuePolicy::CanonicalizeType(_Owner(), other);
801 std::pair<const_inner_iterator, const_inner_iterator> result =
802 std::mismatch(_ConstData()->begin(), _ConstData()->end(),
804 return result.first == _ConstData()->end();
807 int _Compare(
const Type& other)
const
809 if (_ConstData()->size() < other.size()) {
812 if (_ConstData()->size() > other.size()) {
817 const Type& x = ValuePolicy::CanonicalizeType(_Owner(), other);
818 std::pair<const_inner_iterator, const_inner_iterator> result =
819 std::mismatch(_ConstData()->begin(), _ConstData()->end(),
821 if (*result.first < *result.second) {
824 else if (*result.first > *result.second) {
833 bool _CompareEqual(
const D& other)
const
836 return _CompareEqual(Type(other.begin(), other.end()));
840 int _Compare(
const D& other)
const
843 return _Compare(Type(other.begin(), other.end()));
846 mapped_type _Get(
const Type* data,
const inner_iterator& i)
849 if (data == _ConstData()) {
855 return _ConstData()->find(i->first)->second;
858 return mapped_type();
861 const value_type& _Get(
const Type* data,
862 const const_inner_iterator& i)
const
866 return (data == _ConstData()) ? *i : *_ConstData()->find(i->first);
869 void _Copy(
const Type& other)
879 const value_type canonicalValue =
880 ValuePolicy::CanonicalizePair(_Owner(), *it);
881 if (!canonicalOther.insert(canonicalValue).second) {
890 if (_ValidateCopy(canonicalOther)) {
891 _editor->Copy(canonicalOther);
896 bool _ValidateCopy(
const Type& other)
898 SdfSpecHandle owner = _Owner();
899 if (owner && !owner->PermissionToEdit()) {
901 _Location().c_str());
910 if (!_ValidateInsert(*it)) {
919 void _Set(
const Type* data,
const inner_iterator& i,
const U& value)
922 const mapped_type& x =
923 ValuePolicy::CanonicalizeValue(_Owner(), value);
924 if (_ValidateSet(i->first, x)) {
925 _editor->Set(i->first, x);
930 bool _ValidateSet(
const key_type& key,
const mapped_type& value)
932 SdfSpecHandle owner = _Owner();
933 if (owner && !owner->PermissionToEdit()) {
935 _Location().c_str());
939 if (
SdfAllowed allowed = _editor->IsValidValue(value)) {
945 allowed.GetWhyNot().c_str());
952 std::pair<iterator, bool> _Insert(
const value_type& value)
955 const value_type& v = ValuePolicy::CanonicalizePair(_Owner(), value);
956 if (_ValidateInsert(v)) {
957 std::pair<inner_iterator, bool> status = _editor->Insert(v);
958 return std::make_pair(iterator(
this, _Data(), status.first),
962 return std::make_pair(iterator(),
false);
965 return std::make_pair(iterator(),
false);
968 bool _ValidateInsert(
const value_type& value)
970 SdfSpecHandle owner = _Owner();
971 if (owner && !owner->PermissionToEdit()) {
973 _Location().c_str());
977 if (
SdfAllowed allowed = _editor->IsValidKey(value.first)) {
983 allowed.GetWhyNot().c_str());
987 if (
SdfAllowed allowed = _editor->IsValidValue(value.second)) {
993 allowed.GetWhyNot().c_str());
1000 void _Erase(
const key_type& key)
1002 if (_Validate() && _ValidateErase(key)) {
1003 _editor->Erase(key);
1007 bool _ValidateErase(
const key_type& key)
1009 SdfSpecHandle owner = _Owner();
1010 if (owner && !owner->PermissionToEdit()) {
1012 _Location().c_str());
1020 template <
class ProxyT>
friend class SdfPyWrapMapEditProxy;
1022 std::shared_ptr<Sdf_MapEditor<T> > _editor;
1026template <
class T,
class _ValuePolicy>
1028 static Vt_DefaultValueHolder Invoke() =
delete;
1031PXR_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.
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::enable_if<!std::is_enum< T >::value, std::string >::type TfStringify(const T &v)
Convert an arbitrary type into a string.