HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
childrenProxy.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_SDF_CHILDREN_PROXY_H
8 #define PXR_USD_SDF_CHILDREN_PROXY_H
9 
10 /// \file sdf/childrenProxy.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/usd/sdf/api.h"
15 #include "pxr/base/vt/value.h"
16 #include "pxr/base/tf/diagnostic.h"
17 #include "pxr/base/tf/iterator.h"
18 
19 #include <iterator>
20 #include <map>
21 #include <utility>
22 
24 
25 template <class _View>
27 public:
28  typedef _View View;
29  typedef typename View::Adapter Adapter;
30  typedef typename View::ChildPolicy ChildPolicy;
31  typedef typename View::key_type key_type;
32  typedef typename View::value_type mapped_type;
33  typedef std::vector<mapped_type> mapped_vector_type;
34  typedef std::pair<const key_type, mapped_type> value_type;
35  typedef std::map<key_type, mapped_type> map_type;
36  typedef typename View::size_type size_type;
38 
39 private:
40  typedef typename View::const_iterator _inner_iterator;
41 
42  class _ValueProxy {
43  public:
44  _ValueProxy() : _owner(NULL) { }
45  _ValueProxy(This* owner, _inner_iterator i) : _owner(owner), _pos(i)
46  {
47  // Do nothing
48  }
49 
50  operator mapped_type() const
51  {
52  return *_pos;
53  }
54 
55  bool operator==(const mapped_type& other) const
56  {
57  return *_pos == other;
58  }
59 
60  private:
61  This* _owner;
62  _inner_iterator _pos;
63  };
64 
65  class _PairProxy {
66  public:
67  explicit _PairProxy(This* owner, _inner_iterator i) :
68  first(owner->_view.key(i)), second(owner, i) { }
69 
70  const key_type first;
71  _ValueProxy second;
72 
73  operator value_type() const
74  {
75  return value_type(first, second);
76  }
77  };
78  friend class _PairProxy;
79 
80  class _Traits {
81  public:
82  static value_type Dereference(const This* owner, _inner_iterator i)
83  {
84  return value_type(owner->_view.key(i), *i);
85  }
86 
87  static _PairProxy Dereference(This* owner, _inner_iterator i)
88  {
89  return _PairProxy(owner, i);
90  }
91  };
92 
93  template <class _Owner, class _Iter, class _Value>
94  class _Iterator {
95  class _PtrProxy {
96  public:
97  _Value* operator->() { return &_value; }
98  private:
99  friend class _Iterator;
100  explicit _PtrProxy(const _Value& value) : _value(value) {}
101  _Value _value;
102  };
103  public:
104  static_assert(!std::is_reference<_Value>::value &&
106  "_Value cannot be a pointer or reference type.");
107  using iterator_category = std::bidirectional_iterator_tag;
108  using value_type = _Value;
109  using reference = _Value;
110  using pointer = _PtrProxy;
111  using difference_type = std::ptrdiff_t;
112 
113  _Iterator() = default;
114  _Iterator(_Owner owner, _inner_iterator i) : _owner(owner), _pos(i) { }
115  template <class O2, class I2, class V2>
116  _Iterator(const _Iterator<O2, I2, V2>& other) :
117  _owner(other._owner), _pos(other._pos) { }
118 
119  reference operator*() const { return dereference(); }
120  pointer operator->() const { return pointer(dereference()); }
121 
122  _Iterator& operator++() {
123  increment();
124  return *this;
125  }
126 
127  _Iterator& operator--() {
128  decrement();
129  return *this;
130  }
131 
132  _Iterator operator++(int) {
133  _Iterator result(*this);
134  increment();
135  return result;
136  }
137 
138  _Iterator operator--(int) {
139  _Iterator result(*this);
140  decrement();
141  return result;
142  }
143 
144  template <class O2, class I2, class V2>
145  bool operator==(const _Iterator<O2, I2, V2>& other) const {
146  return equal(other);
147  }
148 
149  template <class O2, class I2, class V2>
150  bool operator!=(const _Iterator<O2, I2, V2>& other) const {
151  return !equal(other);
152  }
153 
154  private:
155  _Value dereference() const
156  {
157  return _Traits::Dereference(_owner, _pos);
158  }
159 
160  template <class O2, class I2, class V2>
161  bool equal(const _Iterator<O2, I2, V2>& other) const
162  {
163  return _pos == other._pos;
164  }
165 
166  void increment() {
167  ++_pos;
168  }
169 
170  void decrement() {
171  --_pos;
172  }
173 
174  private:
175  _Owner _owner;
176  _inner_iterator _pos;
177 
178  template <class O2, class I2, class V2>
179  friend class _Iterator;
180  };
181 
182 public:
183  typedef _ValueProxy reference;
184  typedef _Iterator<This*, _inner_iterator, _PairProxy> iterator;
186  typedef _Iterator<const This*, _inner_iterator, value_type> const_iterator;
188 
189  static const int CanSet = 1;
190  static const int CanInsert = 2;
191  static const int CanErase = 4;
192 
193  SdfChildrenProxy(const View& view, const std::string& type,
194  int permission = CanSet | CanInsert | CanErase) :
195  _view(view), _type(type), _permission(permission)
196  {
197  // Do nothing
198  }
199 
200  template <class U>
202  _view(other._view), _type(other._type), _permission(other._permission)
203  {
204  // Do nothing
205  }
206 
207  This& operator=(const This& other)
208  {
209  if (other._Validate()) {
210  _Copy(other._view.values());
211  }
212  return *this;
213  }
214 
215  template <class U>
217  {
218  if (other._Validate()) {
219  _Copy(other._view.values());
220  }
221  return *this;
222  }
223 
225  {
226  _Copy(values);
227  return *this;
228  }
229 
230  operator mapped_vector_type() const
231  {
232  return _Validate() ? _view.values() : mapped_vector_type();
233  }
234 
235  map_type items() const
236  {
237  return _Validate() ? _view.template items_as<map_type>() :map_type();
238  }
239 
241  {
242  return iterator(_GetThis(), _view.begin());
243  }
245  {
246  return iterator(_GetThis(), _view.end());
247  }
249  {
250  return const_iterator(_GetThis(), _view.begin());
251  }
253  {
254  return const_iterator(_GetThis(), _view.end());
255  }
256 
258  {
259  return reverse_iterator(end());
260  }
262  {
263  return reverse_iterator(begin());
264  }
266  {
267  return reverse_iterator(end());
268  }
270  {
271  return reverse_iterator(begin());
272  }
273 
274  size_type size() const
275  {
276  return _Validate() ? _view.size() : 0;
277  }
278 
280  {
281  return _view.max_size();
282  }
283 
284  bool empty() const
285  {
286  return _Validate() ? _view.empty() : true;
287  }
288 
289  std::pair<iterator, bool> insert(const mapped_type& value)
290  {
291  if (_Validate(CanInsert)) {
292  iterator i = find(_view.key(value));
293  if (i == end()) {
294  if (_PrimInsert(value, size())) {
295  return std::make_pair(find(_view.key(value)), true);
296  }
297  else {
298  return std::make_pair(end(), false);
299  }
300  }
301  else {
302  return std::make_pair(i, false);
303  }
304  }
305  else {
306  return std::make_pair(iterator(), false);
307  }
308  }
309 
311  {
312  return insert(value).first;
313  }
314 
315  template <class InputIterator>
316  void insert(InputIterator first, InputIterator last)
317  {
318  if (_Validate(CanInsert)) {
319  SdfChangeBlock block;
320  for (; first != last; ++first) {
321  _PrimInsert(*first, size());
322  }
323  }
324  }
325 
326  void erase(iterator pos)
327  {
328  _Erase(pos->first);
329  }
330 
332  {
333  return _Erase(key) ? 1 : 0;
334  }
335 
337  {
338  if (_Validate(CanErase)) {
339  SdfChangeBlock block;
340  while (first != last) {
341  const key_type& key = first->first;
342  ++first;
343  _PrimErase(key);
344  }
345  }
346  }
347 
348  void clear()
349  {
350  _Copy(mapped_vector_type());
351  }
352 
353  iterator find(const key_type& key)
354  {
355  return _Validate() ? iterator(this, _view.find(key)) : iterator();
356  }
357 
358  const_iterator find(const key_type& key) const
359  {
360  return _Validate() ? const_iterator(this, _view.find(key)) :
361  const_iterator();
362  }
363 
364  size_type count(const key_type& key) const
365  {
366  return _Validate() ? _view.count(key) : 0;
367  }
368 
369  bool operator==(const This& other) const
370  {
371  return _view == other._view;
372  }
373 
374  bool operator!=(const This& other) const
375  {
376  return !(*this == other);
377  }
378 
379  /// Explicit bool conversion operator. The proxy object converts to
380  /// \c true if it is valid, \c false otherwise.
381  explicit operator bool() const
382  {
383  return _view.IsValid();
384  }
385 
386 private:
387  const std::string& _GetType() const
388  {
389  return _type;
390  }
391 
392  int _GetPermission() const
393  {
394  return _permission;
395  }
396 
397  This* _GetThis()
398  {
399  return _Validate() ? this : NULL;
400  }
401 
402  const This* _GetThis() const
403  {
404  return _Validate() ? this : NULL;
405  }
406 
407  bool _Validate() const
408  {
409  if (_view.IsValid()) {
410  return true;
411  }
412  else {
413  TF_CODING_ERROR("Accessing expired %s", _type.c_str());
414  return false;
415  }
416  }
417 
418  bool _Validate(int permission)
419  {
420  if (!_Validate()) {
421  return false;
422  }
423  if ((_permission & permission) == permission) {
424  return true;
425  }
426  const char* op = "edit";
427  if (~_permission & permission & CanSet) {
428  op = "replace";
429  }
430  else if (~_permission & permission & CanInsert) {
431  op = "insert";
432  }
433  else if (~_permission & permission & CanErase) {
434  op = "remove";
435  }
436  TF_CODING_ERROR("Cannot %s %s", op, _type.c_str());
437  return false;
438  }
439 
440  bool _Copy(const mapped_vector_type& values)
441  {
442  return _Validate(CanSet) ? _PrimCopy(values) : false;
443  }
444 
445  bool _Insert(const mapped_type& value, size_t index)
446  {
447  return _Validate(CanInsert) ? _PrimInsert(value, index) : false;
448  }
449 
450  bool _Erase(const key_type& key)
451  {
452  return _Validate(CanErase) ? _PrimErase(key) : false;
453  }
454 
455  bool _PrimCopy(const mapped_vector_type& values)
456  {
457  typedef std::vector<typename ChildPolicy::ValueType>
458  ChildrenValueVector;
459 
460  ChildrenValueVector v;
461  for (size_t i = 0; i < values.size(); ++i)
462  v.push_back(Adapter::Convert(values[i]));
463 
464  return _view.GetChildren().Copy(v, _type);
465  }
466 
467  bool _PrimInsert(const mapped_type& value, size_t index)
468  {
469  return _view.GetChildren().Insert(
470  Adapter::Convert(value), index, _type);
471  }
472 
473  bool _PrimErase(const key_type& key)
474  {
475  return _view.GetChildren().Erase(key, _type);
476  }
477 
478 private:
479  View _view;
480  std::string _type;
481  int _permission;
482 
483  template <class V> friend class SdfChildrenProxy;
484  template <class V> friend class SdfPyChildrenProxy;
485 };
486 
487 // Allow TfIteration over children proxies.
488 template <typename _View>
489 struct Tf_ShouldIterateOverCopy<SdfChildrenProxy<_View> > : std::true_type
490 {
491 };
492 
493 // Cannot get from a VtValue except as the correct type.
494 template <class _View>
496  static Vt_DefaultValueHolder Invoke() = delete;
497 };
498 
500 
501 #endif // PXR_USD_SDF_CHILDREN_PROXY_H
const_iterator end() const
GLint first
Definition: glcorearb.h:405
_Iterator< const This *, _inner_iterator, value_type > const_iterator
This & operator=(const This &other)
size_type erase(const key_type &key)
const_reverse_iterator rbegin() const
reverse_iterator rbegin()
SdfChildrenProxy(const SdfChildrenProxy< U > &other)
const GLdouble * v
Definition: glcorearb.h:837
GLsizei const GLfloat * value
Definition: glcorearb.h:824
This & operator=(const SdfChildrenProxy< U > &other)
View::key_type key_type
Definition: childrenProxy.h:31
#define TF_CODING_ERROR
bool operator==(const This &other) const
IMATH_HOSTDEVICE constexpr bool equal(T1 a, T2 b, T3 t) IMATH_NOEXCEPT
Definition: ImathFun.h:105
SdfChildrenProxy(const View &view, const std::string &type, int permission=CanSet|CanInsert|CanErase)
size_type max_size() const
**But if you need a result
Definition: thread.h:622
uint64 value_type
Definition: GA_PrimCompat.h:29
OutGridT const XformOp bool bool
View::size_type size_type
Definition: childrenProxy.h:36
bool empty() const
View::ChildPolicy ChildPolicy
Definition: childrenProxy.h:30
iterator begin()
std::map< key_type, mapped_type > map_type
Definition: childrenProxy.h:35
_ValueProxy reference
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
static const int CanErase
SdfChildrenProxy< View > This
Definition: childrenProxy.h:37
const_iterator begin() const
bool operator!=(const This &other) const
Tf_ProxyReferenceReverseIterator< iterator > reverse_iterator
std::pair< iterator, bool > insert(const mapped_type &value)
size_type size() const
iterator find(const key_type &key)
iterator insert(iterator pos, const mapped_type &value)
IMATH_HOSTDEVICE constexpr Color4< T > operator*(S a, const Color4< T > &v) IMATH_NOEXCEPT
Reverse multiplication: S * Color4.
Definition: ImathColor.h:732
friend class _PairProxy
Definition: childrenProxy.h:78
View::Adapter Adapter
Definition: childrenProxy.h:29
std::vector< mapped_type > mapped_vector_type
Definition: childrenProxy.h:33
View::value_type mapped_type
Definition: childrenProxy.h:32
void erase(iterator first, iterator last)
__hostdev__ uint64_t last(uint32_t i) const
Definition: NanoVDB.h:5976
_Iterator< This *, _inner_iterator, _PairProxy > iterator
void insert(InputIterator first, InputIterator last)
GLenum void ** pointer
Definition: glcorearb.h:810
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
Tf_ProxyReferenceReverseIterator< const_iterator > const_reverse_iterator
static const int CanSet
GLuint index
Definition: glcorearb.h:786
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
map_type items() const
size_type count(const key_type &key) const
This & operator=(const mapped_vector_type &values)
std::pair< const key_type, mapped_type > value_type
Definition: childrenProxy.h:34
reverse_iterator rend()
void erase(iterator pos)
static const int CanInsert
const_reverse_iterator rend() const
static Vt_DefaultValueHolder Invoke()
Definition: value.h:1512
const_iterator find(const key_type &key) const