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 Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_SDF_CHILDREN_PROXY_H
25 #define PXR_USD_SDF_CHILDREN_PROXY_H
26 
27 /// \file sdf/childrenProxy.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/api.h"
32 #include "pxr/base/vt/value.h"
33 #include "pxr/base/tf/diagnostic.h"
34 #include "pxr/base/tf/iterator.h"
35 
36 #include <iterator>
37 #include <map>
38 #include <utility>
39 
41 
42 template <class _View>
44 public:
45  typedef _View View;
46  typedef typename View::Adapter Adapter;
47  typedef typename View::ChildPolicy ChildPolicy;
48  typedef typename View::key_type key_type;
49  typedef typename View::value_type mapped_type;
50  typedef std::vector<mapped_type> mapped_vector_type;
51  typedef std::pair<const key_type, mapped_type> value_type;
52  typedef std::map<key_type, mapped_type> map_type;
53  typedef typename View::size_type size_type;
55 
56 private:
57  typedef typename View::const_iterator _inner_iterator;
58 
59  class _ValueProxy {
60  public:
61  _ValueProxy() : _owner(NULL) { }
62  _ValueProxy(This* owner, _inner_iterator i) : _owner(owner), _pos(i)
63  {
64  // Do nothing
65  }
66 
67  operator mapped_type() const
68  {
69  return *_pos;
70  }
71 
72  template <class U>
73  _ValueProxy& operator=(const U& x)
74  {
75  _owner->_Set(*_pos, x);
76  return *this;
77  }
78 
79  bool operator==(const mapped_type& other) const
80  {
81  return *_pos == other;
82  }
83 
84  private:
85  This* _owner;
86  _inner_iterator _pos;
87  };
88 
89  class _PairProxy {
90  public:
91  explicit _PairProxy(This* owner, _inner_iterator i) :
92  first(owner->_view.key(i)), second(owner, i) { }
93 
94  const key_type first;
95  _ValueProxy second;
96 
97  operator value_type() const
98  {
99  return value_type(first, second);
100  }
101  };
102  friend class _PairProxy;
103 
104  class _Traits {
105  public:
106  static value_type Dereference(const This* owner, _inner_iterator i)
107  {
108  return value_type(owner->_view.key(i), *i);
109  }
110 
111  static _PairProxy Dereference(This* owner, _inner_iterator i)
112  {
113  return _PairProxy(owner, i);
114  }
115  };
116 
117  template <class _Owner, class _Iter, class _Value>
118  class _Iterator {
119  class _PtrProxy {
120  public:
121  _Value* operator->() { return &_value; }
122  private:
123  friend class _Iterator;
124  explicit _PtrProxy(const _Value& value) : _value(value) {}
125  _Value _value;
126  };
127  public:
128  static_assert(!std::is_reference<_Value>::value &&
130  "_Value cannot be a pointer or reference type.");
131  using iterator_category = std::bidirectional_iterator_tag;
132  using value_type = _Value;
133  using reference = _Value;
134  using pointer = _PtrProxy;
135  using difference_type = std::ptrdiff_t;
136 
137  _Iterator() = default;
138  _Iterator(_Owner owner, _inner_iterator i) : _owner(owner), _pos(i) { }
139  template <class O2, class I2, class V2>
140  _Iterator(const _Iterator<O2, I2, V2>& other) :
141  _owner(other._owner), _pos(other._pos) { }
142 
143  reference operator*() const { return dereference(); }
144  pointer operator->() const { return pointer(dereference()); }
145 
146  _Iterator& operator++() {
147  increment();
148  return *this;
149  }
150 
151  _Iterator& operator--() {
152  decrement();
153  return *this;
154  }
155 
156  _Iterator operator++(int) {
157  _Iterator result(*this);
158  increment();
159  return result;
160  }
161 
162  _Iterator operator--(int) {
163  _Iterator result(*this);
164  decrement();
165  return result;
166  }
167 
168  template <class O2, class I2, class V2>
169  bool operator==(const _Iterator<O2, I2, V2>& other) const {
170  return equal(other);
171  }
172 
173  template <class O2, class I2, class V2>
174  bool operator!=(const _Iterator<O2, I2, V2>& other) const {
175  return !equal(other);
176  }
177 
178  private:
179  _Value dereference() const
180  {
181  return _Traits::Dereference(_owner, _pos);
182  }
183 
184  template <class O2, class I2, class V2>
185  bool equal(const _Iterator<O2, I2, V2>& other) const
186  {
187  return _pos == other._pos;
188  }
189 
190  void increment() {
191  ++_pos;
192  }
193 
194  void decrement() {
195  --_pos;
196  }
197 
198  private:
199  _Owner _owner;
200  _inner_iterator _pos;
201 
202  template <class O2, class I2, class V2>
203  friend class _Iterator;
204  };
205 
206 public:
207  typedef _ValueProxy reference;
208  typedef _Iterator<This*, _inner_iterator, _PairProxy> iterator;
210  typedef _Iterator<const This*, _inner_iterator, value_type> const_iterator;
212 
213  static const int CanSet = 1;
214  static const int CanInsert = 2;
215  static const int CanErase = 4;
216 
218  int permission = CanSet | CanInsert | CanErase) :
219  _view(view), _type(type), _permission(permission)
220  {
221  // Do nothing
222  }
223 
224  template <class U>
226  _view(other._view), _type(other._type), _permission(other._permission)
227  {
228  // Do nothing
229  }
230 
231  This& operator=(const This& other)
232  {
233  if (other._Validate()) {
234  _Copy(other._view.values());
235  }
236  return *this;
237  }
238 
239  template <class U>
241  {
242  if (other._Validate()) {
243  _Copy(other._view.values());
244  }
245  return *this;
246  }
247 
249  {
250  _Copy(values);
251  return *this;
252  }
253 
254  operator mapped_vector_type() const
255  {
256  return _Validate() ? _view.values() : mapped_vector_type();
257  }
258 
259  map_type items() const
260  {
261  return _Validate() ? _view.template items_as<map_type>() :map_type();
262  }
263 
265  {
266  return iterator(_GetThis(), _view.begin());
267  }
269  {
270  return iterator(_GetThis(), _view.end());
271  }
273  {
274  return const_iterator(_GetThis(), _view.begin());
275  }
277  {
278  return const_iterator(_GetThis(), _view.end());
279  }
280 
282  {
283  return reverse_iterator(end());
284  }
286  {
287  return reverse_iterator(begin());
288  }
290  {
291  return reverse_iterator(end());
292  }
294  {
295  return reverse_iterator(begin());
296  }
297 
298  size_type size() const
299  {
300  return _Validate() ? _view.size() : 0;
301  }
302 
304  {
305  return _view.max_size();
306  }
307 
308  bool empty() const
309  {
310  return _Validate() ? _view.empty() : true;
311  }
312 
313  std::pair<iterator, bool> insert(const mapped_type& value)
314  {
315  if (_Validate(CanInsert)) {
316  iterator i = find(_view.key(value));
317  if (i == end()) {
318  if (_PrimInsert(value, size())) {
319  return std::make_pair(find(_view.key(value)), true);
320  }
321  else {
322  return std::make_pair(end(), false);
323  }
324  }
325  else {
326  return std::make_pair(i, false);
327  }
328  }
329  else {
330  return std::make_pair(iterator(), false);
331  }
332  }
333 
335  {
336  return insert(value).first;
337  }
338 
339  template <class InputIterator>
340  void insert(InputIterator first, InputIterator last)
341  {
342  if (_Validate(CanInsert)) {
343  SdfChangeBlock block;
344  for (; first != last; ++first) {
345  _PrimInsert(*first, size());
346  }
347  }
348  }
349 
350  void erase(iterator pos)
351  {
352  _Erase(pos->first);
353  }
354 
356  {
357  return _Erase(key) ? 1 : 0;
358  }
359 
361  {
362  if (_Validate(CanErase)) {
363  SdfChangeBlock block;
364  while (first != last) {
365  const key_type& key = first->first;
366  ++first;
367  _PrimErase(key);
368  }
369  }
370  }
371 
372  void clear()
373  {
374  _Copy(mapped_vector_type());
375  }
376 
377  iterator find(const key_type& key)
378  {
379  return _Validate() ? iterator(this, _view.find(key)) : iterator();
380  }
381 
382  const_iterator find(const key_type& key) const
383  {
384  return _Validate() ? const_iterator(this, _view.find(key)) :
385  const_iterator();
386  }
387 
388  size_type count(const key_type& key) const
389  {
390  return _Validate() ? _view.count(key) : 0;
391  }
392 
393  bool operator==(const This& other) const
394  {
395  return _view == other._view;
396  }
397 
398  bool operator!=(const This& other) const
399  {
400  return !(*this == other);
401  }
402 
403  /// Explicit bool conversion operator. The proxy object converts to
404  /// \c true if it is valid, \c false otherwise.
405  explicit operator bool() const
406  {
407  return _view.IsValid();
408  }
409 
410 private:
411  const std::string& _GetType() const
412  {
413  return _type;
414  }
415 
416  int _GetPermission() const
417  {
418  return _permission;
419  }
420 
421  This* _GetThis()
422  {
423  return _Validate() ? this : NULL;
424  }
425 
426  const This* _GetThis() const
427  {
428  return _Validate() ? this : NULL;
429  }
430 
431  bool _Validate() const
432  {
433  if (_view.IsValid()) {
434  return true;
435  }
436  else {
437  TF_CODING_ERROR("Accessing expired %s", _type.c_str());
438  return false;
439  }
440  }
441 
442  bool _Validate(int permission)
443  {
444  if (!_Validate()) {
445  return false;
446  }
447  if ((_permission & permission) == permission) {
448  return true;
449  }
450  const char* op = "edit";
451  if (~_permission & permission & CanSet) {
452  op = "replace";
453  }
454  else if (~_permission & permission & CanInsert) {
455  op = "insert";
456  }
457  else if (~_permission & permission & CanErase) {
458  op = "remove";
459  }
460  TF_CODING_ERROR("Cannot %s %s", op, _type.c_str());
461  return false;
462  }
463 
464  bool _Copy(const mapped_vector_type& values)
465  {
466  return _Validate(CanSet) ? _PrimCopy(values) : false;
467  }
468 
469  bool _Insert(const mapped_type& value, size_t index)
470  {
471  return _Validate(CanInsert) ? _PrimInsert(value, index) : false;
472  }
473 
474  bool _Erase(const key_type& key)
475  {
476  return _Validate(CanErase) ? _PrimErase(key) : false;
477  }
478 
479  bool _PrimCopy(const mapped_vector_type& values)
480  {
481  typedef std::vector<typename ChildPolicy::ValueType>
482  ChildrenValueVector;
483 
484  ChildrenValueVector v;
485  for (size_t i = 0; i < values.size(); ++i)
486  v.push_back(Adapter::Convert(values[i]));
487 
488  return _view.GetChildren().Copy(v, _type);
489  }
490 
491  bool _PrimInsert(const mapped_type& value, size_t index)
492  {
493  return _view.GetChildren().Insert(
494  Adapter::Convert(value), index, _type);
495  }
496 
497  bool _PrimErase(const key_type& key)
498  {
499  return _view.GetChildren().Erase(key, _type);
500  }
501 
502 private:
503  View _view;
504  std::string _type;
505  int _permission;
506 
507  template <class V> friend class SdfChildrenProxy;
508  template <class V> friend class SdfPyChildrenProxy;
509 };
510 
511 // Allow TfIteration over children proxies.
512 template <typename _View>
513 struct Tf_ShouldIterateOverCopy<SdfChildrenProxy<_View> > : std::true_type
514 {
515 };
516 
517 // Cannot get from a VtValue except as the correct type.
518 template <class _View>
520  static Vt_DefaultValueHolder Invoke() = delete;
521 };
522 
524 
525 #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 GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
This & operator=(const SdfChildrenProxy< U > &other)
View::key_type key_type
Definition: childrenProxy.h:48
#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:613
uint64 value_type
Definition: GA_PrimCompat.h:29
View::size_type size_type
Definition: childrenProxy.h:53
bool empty() const
View::ChildPolicy ChildPolicy
Definition: childrenProxy.h:47
iterator begin()
std::map< key_type, mapped_type > map_type
Definition: childrenProxy.h:52
_ValueProxy reference
static const int CanErase
SdfChildrenProxy< View > This
Definition: childrenProxy.h:54
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
View::Adapter Adapter
Definition: childrenProxy.h:46
GLint GLenum GLint x
Definition: glcorearb.h:409
std::vector< mapped_type > mapped_vector_type
Definition: childrenProxy.h:50
View::value_type mapped_type
Definition: childrenProxy.h:49
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:1432
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:91
map_type items() const
Definition: core.h:982
size_type count(const key_type &key) const
Definition: core.h:1131
This & operator=(const mapped_vector_type &values)
std::pair< const key_type, mapped_type > value_type
Definition: childrenProxy.h:51
reverse_iterator rend()
void erase(iterator pos)
static const int CanInsert
const_reverse_iterator rend() const
type
Definition: core.h:1059
static Vt_DefaultValueHolder Invoke()
Definition: value.h:1529
const_iterator find(const key_type &key) const