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 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/api.h"
31 #include "pxr/usd/sdf/changeBlock.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 <boost/iterator/iterator_facade.hpp>
37 #include <boost/iterator/reverse_iterator.hpp>
38 #include <boost/operators.hpp>
39 #include <iterator>
40 #include <map>
41 #include <utility>
42 
43 PXR_NAMESPACE_OPEN_SCOPE
44 
45 template <class _View>
46 class SdfChildrenProxy : boost::equality_comparable<SdfChildrenProxy<_View> > {
47 public:
48  typedef _View View;
49  typedef typename View::Adapter Adapter;
50  typedef typename View::ChildPolicy ChildPolicy;
51  typedef typename View::key_type key_type;
52  typedef typename View::value_type mapped_type;
53  typedef std::vector<mapped_type> mapped_vector_type;
54  typedef std::pair<const key_type, mapped_type> value_type;
55  typedef std::map<key_type, mapped_type> map_type;
56  typedef typename View::size_type size_type;
57  typedef SdfChildrenProxy<View> This;
58 
59 private:
60  typedef typename View::const_iterator _inner_iterator;
61 
62  class _ValueProxy {
63  public:
64  _ValueProxy() : _owner(NULL) { }
65  _ValueProxy(This* owner, _inner_iterator i) : _owner(owner), _pos(i)
66  {
67  // Do nothing
68  }
69 
70  operator mapped_type() const
71  {
72  return *_pos;
73  }
74 
75  template <class U>
76  _ValueProxy& operator=(const U& x)
77  {
78  _owner->_Set(*_pos, x);
79  return *this;
80  }
81 
82  bool operator==(const mapped_type& other) const
83  {
84  return *_pos == other;
85  }
86 
87  private:
88  This* _owner;
89  _inner_iterator _pos;
90  };
91 
92  class _PairProxy {
93  public:
94  explicit _PairProxy(This* owner, _inner_iterator i) :
95  first(owner->_view.key(i)), second(owner, i) { }
96 
97  const key_type first;
98  _ValueProxy second;
99 
100  operator value_type() const
101  {
102  return value_type(first, second);
103  }
104  };
105  friend class _PairProxy;
106 
107  class _Traits {
108  public:
109  static value_type Dereference(const This* owner, _inner_iterator i)
110  {
111  return value_type(owner->_view.key(i), *i);
112  }
113 
114  static _PairProxy Dereference(This* owner, _inner_iterator i)
115  {
116  return _PairProxy(owner, i);
117  }
118  };
119 
120  template <class _Owner, class _Iter, class _Value>
121  class _Iterator :
122  public boost::iterator_facade<
123  _Iterator<_Owner, _Iter, _Value>,
124  _Value,
125  std::bidirectional_iterator_tag,
126  _Value> {
127  public:
128  _Iterator() { }
129  _Iterator(_Owner owner, _inner_iterator i) : _owner(owner), _pos(i) { }
130  template <class O2, class I2, class V2>
131  _Iterator(const _Iterator<O2, I2, V2>& other) :
132  _owner(other._owner), _pos(other._pos) { }
133 
134  private:
135  friend class boost::iterator_core_access;
136 
137  _Value dereference() const
138  {
139  return _Traits::Dereference(_owner, _pos);
140  }
141 
142  template <class O2, class I2, class V2>
143  bool equal(const _Iterator<O2, I2, V2>& other) const
144  {
145  return _pos == other._pos;
146  }
147 
148  void increment() {
149  ++_pos;
150  }
151 
152  void decrement() {
153  --_pos;
154  }
155 
156  private:
157  _Owner _owner;
158  _inner_iterator _pos;
159 
160  template <class O2, class I2, class V2>
161  friend class _Iterator;
162  };
163 
164 public:
165  typedef _ValueProxy reference;
166  typedef _Iterator<This*, _inner_iterator, _PairProxy> iterator;
167  typedef boost::reverse_iterator<iterator> reverse_iterator;
168  typedef _Iterator<const This*, _inner_iterator, value_type> const_iterator;
169  typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
170 
171  static const int CanSet = 1;
172  static const int CanInsert = 2;
173  static const int CanErase = 4;
174 
175  SdfChildrenProxy(const View& view, const std::string& type,
176  int permission = CanSet | CanInsert | CanErase) :
177  _view(view), _type(type), _permission(permission)
178  {
179  // Do nothing
180  }
181 
182  template <class U>
183  SdfChildrenProxy(const SdfChildrenProxy<U>& other) :
184  _view(other._view), _type(other._type), _permission(other._permission)
185  {
186  // Do nothing
187  }
188 
189  This& operator=(const This& other)
190  {
191  if (other._Validate()) {
192  _Copy(other._view.values());
193  }
194  return *this;
195  }
196 
197  template <class U>
198  This& operator=(const SdfChildrenProxy<U>& other)
199  {
200  if (other._Validate()) {
201  _Copy(other._view.values());
202  }
203  return *this;
204  }
205 
206  This& operator=(const mapped_vector_type& values)
207  {
208  _Copy(values);
209  return *this;
210  }
211 
212  operator mapped_vector_type() const
213  {
214  return _Validate() ? _view.values() : mapped_vector_type();
215  }
216 
217  map_type items() const
218  {
219  return _Validate() ? _view.template items_as<map_type>() :map_type();
220  }
221 
222  iterator begin()
223  {
224  return iterator(_GetThis(), _view.begin());
225  }
226  iterator end()
227  {
228  return iterator(_GetThis(), _view.end());
229  }
230  const_iterator begin() const
231  {
232  return const_iterator(_GetThis(), _view.begin());
233  }
234  const_iterator end() const
235  {
236  return const_iterator(_GetThis(), _view.end());
237  }
238 
239  reverse_iterator rbegin()
240  {
241  return reverse_iterator(end());
242  }
243  reverse_iterator rend()
244  {
245  return reverse_iterator(begin());
246  }
247  const_reverse_iterator rbegin() const
248  {
249  return reverse_iterator(end());
250  }
251  const_reverse_iterator rend() const
252  {
253  return reverse_iterator(begin());
254  }
255 
256  size_type size() const
257  {
258  return _Validate() ? _view.size() : 0;
259  }
260 
261  size_type max_size() const
262  {
263  return _view.max_size();
264  }
265 
266  bool empty() const
267  {
268  return _Validate() ? _view.empty() : true;
269  }
270 
271  std::pair<iterator, bool> insert(const mapped_type& value)
272  {
273  if (_Validate(CanInsert)) {
274  iterator i = find(_view.key(value));
275  if (i == end()) {
276  if (_PrimInsert(value, size())) {
277  return std::make_pair(find(_view.key(value)), true);
278  }
279  else {
280  return std::make_pair(end(), false);
281  }
282  }
283  else {
284  return std::make_pair(i, false);
285  }
286  }
287  else {
288  return std::make_pair(iterator(), false);
289  }
290  }
291 
292  iterator insert(iterator pos, const mapped_type& value)
293  {
294  return insert(value).first;
295  }
296 
297  template <class InputIterator>
298  void insert(InputIterator first, InputIterator last)
299  {
300  if (_Validate(CanInsert)) {
301  SdfChangeBlock block;
302  for (; first != last; ++first) {
303  _PrimInsert(*first, size());
304  }
305  }
306  }
307 
308  void erase(iterator pos)
309  {
310  _Erase(pos->first);
311  }
312 
313  size_type erase(const key_type& key)
314  {
315  return _Erase(key) ? 1 : 0;
316  }
317 
318  void erase(iterator first, iterator last)
319  {
320  if (_Validate(CanErase)) {
321  SdfChangeBlock block;
322  while (first != last) {
323  const key_type& key = first->first;
324  ++first;
325  _PrimErase(key);
326  }
327  }
328  }
329 
330  void clear()
331  {
332  _Copy(mapped_vector_type());
333  }
334 
335  iterator find(const key_type& key)
336  {
337  return _Validate() ? iterator(this, _view.find(key)) : iterator();
338  }
339 
340  const_iterator find(const key_type& key) const
341  {
342  return _Validate() ? const_iterator(this, _view.find(key)) :
343  const_iterator();
344  }
345 
346  size_type count(const key_type& key) const
347  {
348  return _Validate() ? _view.count(key) : 0;
349  }
350 
351  bool operator==(const This& other) const
352  {
353  return _view == other._view;
354  }
355 
358  explicit operator bool() const
359  {
360  return _view.IsValid();
361  }
362 
363 private:
364  const std::string& _GetType() const
365  {
366  return _type;
367  }
368 
369  int _GetPermission() const
370  {
371  return _permission;
372  }
373 
374  This* _GetThis()
375  {
376  return _Validate() ? this : NULL;
377  }
378 
379  const This* _GetThis() const
380  {
381  return _Validate() ? this : NULL;
382  }
383 
384  bool _Validate() const
385  {
386  if (_view.IsValid()) {
387  return true;
388  }
389  else {
390  TF_CODING_ERROR("Accessing expired %s", _type.c_str());
391  return false;
392  }
393  }
394 
395  bool _Validate(int permission)
396  {
397  if (!_Validate()) {
398  return false;
399  }
400  if ((_permission & permission) == permission) {
401  return true;
402  }
403  const char* op = "edit";
404  if (~_permission & permission & CanSet) {
405  op = "replace";
406  }
407  else if (~_permission & permission & CanInsert) {
408  op = "insert";
409  }
410  else if (~_permission & permission & CanErase) {
411  op = "remove";
412  }
413  TF_CODING_ERROR("Cannot %s %s", op, _type.c_str());
414  return false;
415  }
416 
417  bool _Copy(const mapped_vector_type& values)
418  {
419  return _Validate(CanSet) ? _PrimCopy(values) : false;
420  }
421 
422  bool _Insert(const mapped_type& value, size_t index)
423  {
424  return _Validate(CanInsert) ? _PrimInsert(value, index) : false;
425  }
426 
427  bool _Erase(const key_type& key)
428  {
429  return _Validate(CanErase) ? _PrimErase(key) : false;
430  }
431 
432  bool _PrimCopy(const mapped_vector_type& values)
433  {
434  typedef std::vector<typename ChildPolicy::ValueType>
435  ChildrenValueVector;
436 
437  ChildrenValueVector v;
438  for (size_t i = 0; i < values.size(); ++i)
439  v.push_back(Adapter::Convert(values[i]));
440 
441  return _view.GetChildren().Copy(v, _type);
442  }
443 
444  bool _PrimInsert(const mapped_type& value, size_t index)
445  {
446  return _view.GetChildren().Insert(
447  Adapter::Convert(value), index, _type);
448  }
449 
450  bool _PrimErase(const key_type& key)
451  {
452  return _view.GetChildren().Erase(key, _type);
453  }
454 
455 private:
456  View _view;
457  std::string _type;
458  int _permission;
459 
460  template <class V> friend class SdfChildrenProxy;
461  template <class V> friend class SdfPyChildrenProxy;
462 };
463 
464 // Allow TfIteration over children proxies.
465 template <typename _View>
466 struct Tf_ShouldIterateOverCopy<SdfChildrenProxy<_View> > : boost::true_type
467 {
468 };
469 
470 // Cannot get from a VtValue except as the correct type.
471 template <class _View>
472 struct Vt_DefaultValueFactory<SdfChildrenProxy<_View> > {
473  static Vt_DefaultValueHolder Invoke() = delete;
474 };
475 
476 PXR_NAMESPACE_CLOSE_SCOPE
477 
478 #endif // PXR_USD_SDF_CHILDREN_PROXY_H
A simple iterator adapter for STL containers.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
Low-level utilities for informing users of various internal and external diagnostic conditions...
DANGER DANGER DANGER
Definition: changeBlock.h:72
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.