All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
array.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_BASE_VT_ARRAY_H
25 #define PXR_BASE_VT_ARRAY_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/base/vt/api.h"
31 #include "pxr/base/vt/hash.h"
32 #include "pxr/base/vt/operators.h"
33 #include "pxr/base/vt/streamOut.h"
34 #include "pxr/base/vt/traits.h"
35 #include "pxr/base/vt/types.h"
36 
37 #include "pxr/base/arch/functionLite.h"
38 #include "pxr/base/arch/pragmas.h"
39 #include "pxr/base/tf/diagnostic.h"
40 #include "pxr/base/tf/mallocTag.h"
41 
42 #include <boost/functional/hash.hpp>
43 #include <boost/iterator_adaptors.hpp>
44 #include <boost/iterator/reverse_iterator.hpp>
45 
46 #include <algorithm>
47 #include <atomic>
48 #include <cstddef>
49 #include <cstdlib>
50 #include <memory>
51 #include <type_traits>
52 
53 PXR_NAMESPACE_OPEN_SCOPE
54 
55 // Helper class for clients that create VtArrays referring to foreign-owned
56 // data.
57 class Vt_ArrayForeignDataSource
58 {
59 public:
60  explicit Vt_ArrayForeignDataSource(
61  void (*detachedFn)(Vt_ArrayForeignDataSource *self) = nullptr,
62  size_t initRefCount = 0)
63  : _refCount(initRefCount)
64  , _detachedFn(detachedFn) {}
65 
66 private:
67  template <class T> friend class VtArray;
68  // Invoked when no more arrays share this data source.
69  void _ArraysDetached() { if (_detachedFn) { _detachedFn(this); } }
70 protected:
71  std::atomic<size_t> _refCount;
72  void (*_detachedFn)(Vt_ArrayForeignDataSource *self);
73 };
74 
75 // Private base class helper for VtArray implementation.
76 class Vt_ArrayBase
77 {
78 public:
79  Vt_ArrayBase() : _shapeData { 0 }, _foreignSource(nullptr) {}
80 
81  Vt_ArrayBase(Vt_ArrayForeignDataSource *foreignSrc)
82  : _shapeData { 0 }, _foreignSource(foreignSrc) {}
83 
84  Vt_ArrayBase(Vt_ArrayBase const &other) = default;
85  Vt_ArrayBase(Vt_ArrayBase &&other) : Vt_ArrayBase(other) {
86  other._shapeData.clear();
87  other._foreignSource = nullptr;
88  }
89 
90  Vt_ArrayBase &operator=(Vt_ArrayBase const &other) = default;
91  Vt_ArrayBase &operator=(Vt_ArrayBase &&other) {
92  if (this == &other)
93  return *this;
94  *this = other;
95  other._shapeData.clear();
96  other._foreignSource = nullptr;
97  return *this;
98  }
99 
100 protected:
101  // Control block header for native data representation. Houses refcount and
102  // capacity. For arrays with native data, this structure always lives
103  // immediately preceding the start of the array's _data in memory. See
104  // _GetControlBlock() for details.
105  struct _ControlBlock {
106  _ControlBlock() : nativeRefCount(0), capacity(0) {}
107  _ControlBlock(size_t initCount, size_t initCap)
108  : nativeRefCount(initCount), capacity(initCap) {}
109  mutable std::atomic<size_t> nativeRefCount;
110  size_t capacity;
111  };
112 
113  _ControlBlock &_GetControlBlock(void *nativeData) {
114  TF_DEV_AXIOM(!_foreignSource);
115  return *(reinterpret_cast<_ControlBlock *>(nativeData) - 1);
116  }
117 
118  _ControlBlock const &_GetControlBlock(void *nativeData) const {
119  TF_DEV_AXIOM(!_foreignSource);
120  return *(reinterpret_cast<_ControlBlock *>(nativeData) - 1);
121  }
122 
123  // Mutable ref count, as is standard.
124  std::atomic<size_t> &_GetNativeRefCount(void *nativeData) const {
125  return _GetControlBlock(nativeData).nativeRefCount;
126  }
127 
128  size_t &_GetCapacity(void *nativeData) {
129  return _GetControlBlock(nativeData).capacity;
130  }
131  size_t const &_GetCapacity(void *nativeData) const {
132  return _GetControlBlock(nativeData).capacity;
133  }
134 
135  VT_API void _DetachCopyHook(char const *funcName) const;
136 
137  Vt_ShapeData _shapeData;
138  Vt_ArrayForeignDataSource *_foreignSource;
139 };
140 
193 template<typename ELEM>
194 class VtArray : public Vt_ArrayBase {
195  public:
196 
198  typedef ELEM ElementType;
199  typedef ELEM value_type;
200 
201  template <typename Value>
202  class PointerIterator
203  : public boost::iterator_adaptor<PointerIterator<Value>, Value *> {
204  public:
205  PointerIterator() :
206  PointerIterator::iterator_adaptor_(0) {}
207  explicit PointerIterator(Value *p) :
208  PointerIterator::iterator_adaptor_(p) {}
209  template <typename OtherValue>
210  PointerIterator(PointerIterator<OtherValue> const &other,
211  typename boost::enable_if_convertible
212  <OtherValue*, Value*>::type* = 0) :
213  PointerIterator::iterator_adaptor_(other.base()) {}
214  private:
215  friend class boost::iterator_core_access;
216  };
217 
220 
222  typedef PointerIterator<ElementType> iterator;
224  typedef PointerIterator<const ElementType> const_iterator;
226  typedef boost::reverse_iterator<iterator> reverse_iterator;
228  typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
229 
231  typedef typename PointerIterator<ElementType>::reference
234  typedef typename PointerIterator<const ElementType>::reference
237  typedef typename PointerIterator<ElementType>::pointer pointer;
239  typedef typename PointerIterator<const ElementType>::pointer const_pointer;
240 
242 
244  VtArray() : _data(nullptr) {}
245 
258  template <typename LegacyInputIterator>
259  VtArray(LegacyInputIterator first, LegacyInputIterator last,
260  typename std::enable_if<
261  !std::is_integral<LegacyInputIterator>::value,
262  void>::type* = nullptr)
263  : VtArray() {
264  assign(first, last);
265  }
266 
268  VtArray(Vt_ArrayForeignDataSource *foreignSrc,
269  ElementType *data, size_t size, bool addRef = true)
270  : Vt_ArrayBase(foreignSrc)
271  , _data(data) {
272  if (addRef) {
273  foreignSrc->_refCount.fetch_add(1, std::memory_order_relaxed);
274  }
275  _shapeData.totalSize = size;
276  }
277 
279  VtArray(VtArray const &other) : Vt_ArrayBase(other)
280  , _data(other._data) {
281  if (!_data)
282  return;
283 
284  if (ARCH_LIKELY(!_foreignSource)) {
285  _GetNativeRefCount(_data).fetch_add(1, std::memory_order_relaxed);
286  }
287  else {
288  _foreignSource->_refCount.fetch_add(1, std::memory_order_relaxed);
289  }
290  }
291 
294  VtArray(VtArray &&other) : Vt_ArrayBase(std::move(other))
295  , _data(other._data) {
296  other._data = nullptr;
297  }
298 
300  VtArray(std::initializer_list<ELEM> initializerList)
301  : VtArray() {
302  assign(initializerList);
303  }
304 
306  explicit VtArray(size_t n)
307  : VtArray() {
308  assign(n, value_type());
309  }
310 
312  explicit VtArray(size_t n, value_type const &value)
313  : VtArray() {
314  assign(n, value);
315  }
316 
319  VtArray &operator=(VtArray const &other) {
320  // This might look recursive but it's really invoking move-assign, since
321  // we create a temporary copy (an rvalue).
322  if (this != &other)
323  *this = VtArray(other);
324  return *this;
325  }
326 
330  if (this == &other)
331  return *this;
332  _DecRef();
333  static_cast<Vt_ArrayBase &>(*this) = std::move(other);
334  _data = other._data;
335  other._data = nullptr;
336  return *this;
337  }
338 
340  VtArray &operator=(std::initializer_list<ELEM> initializerList) {
341  this->assign(initializerList.begin(), initializerList.end());
342  return *this;
343  }
344 
345  ~VtArray() { _DecRef(); }
346 
349 
352  iterator begin() { return iterator(data()); }
355  iterator end() { return iterator(data() + size()); }
356 
358  const_iterator begin() const { return const_iterator(data()); }
360  const_iterator end() const { return const_iterator(data() + size()); }
361 
363  const_iterator cbegin() const { return begin(); }
365  const_iterator cend() const { return end(); }
366 
373 
376  return const_reverse_iterator(end());
377  }
380  return const_reverse_iterator(begin());
381  }
382 
384  const_reverse_iterator crbegin() const { return rbegin(); }
386  const_reverse_iterator crend() const { return rend(); }
387 
390  pointer data() { _DetachIfNotUnique(); return _data; }
392  const_pointer data() const { return _data; }
394  const_pointer cdata() const { return _data; }
395 
398  void push_back(ElementType const &elem) {
399  // If this is a non-pxr array with rank > 1, disallow push_back.
400  if (ARCH_UNLIKELY(_shapeData.otherDims[0])) {
401  TF_CODING_ERROR("Array rank %u != 1", _shapeData.GetRank());
402  return;
403  }
404  // If we don't own the data, or if we need more space, realloc.
405  size_t curSize = size();
406  if (ARCH_UNLIKELY(
407  _foreignSource || !_IsUnique() || curSize == capacity())) {
408  value_type *newData = _AllocateCopy(
409  _data, _CapacityForSize(curSize + 1), curSize);
410  _DecRef();
411  _data = newData;
412  }
413  // Copy the value.
414  ::new (static_cast<void*>(_data + curSize)) value_type(elem);
415  // Adjust size.
416  ++_shapeData.totalSize;
417  }
418 
421  void pop_back() {
422  // If this is a presto array with rank > 1, disallow push_back.
423  if (ARCH_UNLIKELY(_shapeData.otherDims[0])) {
424  TF_CODING_ERROR("Array rank %u != 1", _shapeData.GetRank());
425  return;
426  }
427  _DetachIfNotUnique();
428  // Invoke the destructor.
429  (_data + size() - 1)->~value_type();
430  // Adjust size.
431  --_shapeData.totalSize;
432  }
433 
435  size_t size() const { return _shapeData.totalSize; }
436 
441  size_t capacity() const {
442  if (!_data) {
443  return 0;
444  }
445  // We do not allow mutation to foreign source data, so always report
446  // foreign sourced arrays as at capacity.
447  return ARCH_UNLIKELY(_foreignSource) ? size() : _GetCapacity(_data);
448  }
449 
451  bool empty() const { return size() == 0; }
452 
456  void reserve(size_t num) {
457  if (num <= capacity())
458  return;
459 
460  value_type *newData =
461  _data ? _AllocateCopy(_data, num, size()) : _AllocateNew(num);
462 
463  _DecRef();
464  _data = newData;
465  }
466 
470  reference front() { return *begin(); }
473  const_reference front() const { return *begin(); }
474 
478  reference back() { return *rbegin(); }
481  const_reference back() const { return *rbegin(); }
482 
488  void resize(size_t newSize) {
489  struct _Filler {
490  inline void operator()(pointer b, pointer e) const {
491  std::uninitialized_fill(b, e, value_type());
492  }
493  };
494  return resize(newSize, _Filler());
495  }
496 
501  template <class FillElemsFn>
502  void resize(size_t newSize, FillElemsFn &&fillElems) {
503  const size_t oldSize = size();
504  if (oldSize == newSize) {
505  return;
506  }
507  if (newSize == 0) {
508  clear();
509  return;
510  }
511 
512  const bool growing = newSize > oldSize;
513  value_type *newData = _data;
514 
515  if (!_data) {
516  // Allocate newSize elements and initialize.
517  newData = _AllocateNew(newSize);
518  std::forward<FillElemsFn>(fillElems)(newData, newData + newSize);
519  }
520  else if (_IsUnique()) {
521  if (growing) {
522  if (newSize > _GetCapacity(_data)) {
523  newData = _AllocateCopy(_data, newSize, oldSize);
524  }
525  // fill with newly added elements from oldSize to newSize.
526  std::forward<FillElemsFn>(fillElems)(newData + oldSize,
527  newData + newSize);
528  }
529  else {
530  // destroy removed elements
531  for (auto *cur = newData + newSize,
532  *end = newData + oldSize; cur != end; ++cur) {
533  cur->~value_type();
534  }
535  }
536  }
537  else {
538  newData =
539  _AllocateCopy(_data, newSize, growing ? oldSize : newSize);
540  if (growing) {
541  // fill with newly added elements from oldSize to newSize.
542  std::forward<FillElemsFn>(fillElems)(newData + oldSize,
543  newData + newSize);
544  }
545  }
546 
547  // If we created new data, clean up the old and move over to the new.
548  if (newData != _data) {
549  _DecRef();
550  _data = newData;
551  }
552  // Adjust size.
553  _shapeData.totalSize = newSize;
554  }
555 
557  void clear() {
558  if (!_data)
559  return;
560  if (_IsUnique()) {
561  // Clear out elements, run dtors, keep capacity.
562  for (value_type *p = _data, *e = _data + size(); p != e; ++p) {
563  p->~value_type();
564  }
565  }
566  else {
567  // Detach to empty.
568  _DecRef();
569  }
570  _shapeData.totalSize = 0;
571  }
572 
579  template <class ForwardIter>
580  typename std::enable_if<!std::is_integral<ForwardIter>::value>::type
581  assign(ForwardIter first, ForwardIter last) {
582  struct _Copier {
583  void operator()(pointer b, pointer e) const {
584  std::uninitialized_copy(first, last, b);
585  }
586  ForwardIter const &first, &last;
587  };
588  clear();
589  resize(std::distance(first, last), _Copier { first, last });
590  }
591 
598  void assign(size_t n, const value_type &fill) {
599  struct _Filler {
600  void operator()(pointer b, pointer e) const {
601  std::uninitialized_fill(b, e, fill);
602  }
603  const value_type &fill;
604  };
605  clear();
606  resize(n, _Filler { fill });
607  }
608 
614  void assign(std::initializer_list<ELEM> initializerList) {
615  assign(initializerList.begin(), initializerList.end());
616  }
617 
619  void swap(VtArray &other) {
620  std::swap(_data, other._data);
621  std::swap(_shapeData, other._shapeData);
622  std::swap(_foreignSource, other._foreignSource);
623  }
624 
626 
628  ElementType &operator[](size_t index) {
629  return data()[index];
630  }
631 
633  ElementType const &operator[](size_t index) const {
634  return data()[index];
635  }
636 
639  bool IsIdentical(VtArray const & other) const {
640  return
641  _data == other._data &&
642  _shapeData == other._shapeData &&
643  _foreignSource == other._foreignSource;
644  }
645 
647  bool operator == (VtArray const & other) const {
648  return IsIdentical(other) ||
649  (*_GetShapeData() == *other._GetShapeData() &&
650  std::equal(cbegin(), cend(), other.cbegin()));
651  }
652 
654  bool operator != (VtArray const &other) const {
655  return !(*this == other);
656  }
657 
658 ARCH_PRAGMA_PUSH
659 ARCH_PRAGMA_FORCING_TO_BOOL
660 ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
661 ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
662  VTOPERATOR_CPPARRAY(+)
663  VTOPERATOR_CPPARRAY(-)
664  VTOPERATOR_CPPARRAY(*)
665  VTOPERATOR_CPPARRAY(/)
666  VTOPERATOR_CPPARRAY(%)
667  VTOPERATOR_CPPARRAY_UNARY(-)
668 ARCH_PRAGMA_POP
669 
670  public:
671  // XXX -- Public so VtValue::_ArrayHelper<T,U>::GetShapeData() has access.
672  Vt_ShapeData const *_GetShapeData() const {
673  return &_shapeData;
674  }
675  Vt_ShapeData *_GetShapeData() {
676  return &_shapeData;
677  }
678 
679  private:
680  class _Streamer : public VtStreamOutIterator {
681  public:
682  _Streamer(const_pointer data) : _p(data) { }
683  virtual ~_Streamer() { }
684  virtual void Next(std::ostream &out)
685  {
686  VtStreamOut(*_p++, out);
687  }
688 
689  private:
690  const_pointer _p;
691  };
692 
694  friend std::ostream &operator <<(std::ostream &out, const VtArray &self) {
695  VtArray::_Streamer streamer(self.cdata());
696  VtStreamOutArray(&streamer, self.size(), self._GetShapeData(), out);
697  return out;
698  }
699 
701  friend void swap(VtArray &lhs, VtArray &rhs) {
702  lhs.swap(rhs);
703  }
704 
705  void _DetachIfNotUnique() {
706  if (_IsUnique())
707  return;
708  // Copy to local.
709  _DetachCopyHook(__ARCH_PRETTY_FUNCTION__);
710  auto *newData = _AllocateCopy(_data, size(), size());
711  _DecRef();
712  _data = newData;
713  }
714 
715  inline bool _IsUnique() const {
716  return !_data ||
717  (ARCH_LIKELY(!_foreignSource) && _GetNativeRefCount(_data) == 1);
718  }
719 
720  inline size_t _CapacityForSize(size_t sz) const {
721  // Currently just successive powers of two.
722  size_t cap = 1;
723  while (cap < sz) {
724  cap += cap;
725  }
726  return cap;
727  }
728 
729  value_type *_AllocateNew(size_t capacity) {
730  TfAutoMallocTag2 tag("VtArray::_AllocateNew", __ARCH_PRETTY_FUNCTION__);
731  // Need space for the control block and capacity elements.
732  void *data = malloc(
733  sizeof(_ControlBlock) + capacity * sizeof(value_type));
734  // Placement-new a control block.
735  ::new (data) _ControlBlock(/*count=*/1, capacity);
736  // Data starts after the block.
737  return reinterpret_cast<value_type *>(
738  static_cast<_ControlBlock *>(data) + 1);
739  }
740 
741  value_type *_AllocateCopy(value_type *src, size_t newCapacity,
742  size_t numToCopy) {
743  // Allocate and copy elements.
744  value_type *newData = _AllocateNew(newCapacity);
745  std::uninitialized_copy(src, src + numToCopy, newData);
746  return newData;
747  }
748 
749  void _DecRef() {
750  if (!_data)
751  return;
752  if (ARCH_LIKELY(!_foreignSource)) {
753  // Drop the refcount. If we take it to zero, destroy the data.
754  if (_GetNativeRefCount(_data).fetch_sub(
755  1, std::memory_order_release) == 1) {
756  std::atomic_thread_fence(std::memory_order_acquire);
757  for (value_type *p = _data, *e = _data + _shapeData.totalSize;
758  p != e; ++p) {
759  p->~value_type();
760  }
761  free(std::addressof(_GetControlBlock(_data)));
762  }
763  }
764  else {
765  // Drop the refcount in the foreign source. If we take it to zero,
766  // invoke the function pointer to alert the foreign source.
767  if (_foreignSource->_refCount.fetch_sub(
768  1, std::memory_order_release) == 1) {
769  std::atomic_thread_fence(std::memory_order_acquire);
770  _foreignSource->_ArraysDetached();
771  }
772  }
773  _foreignSource = nullptr;
774  _data = nullptr;
775  }
776 
777  value_type *_data;
778 };
779 
780 template <class ELEM>
781 typename std::enable_if<VtIsHashable<ELEM>(), size_t>::type
782 hash_value(VtArray<ELEM> const &array) {
783  size_t h = array.size();
784  for (auto const &x: array) {
785  boost::hash_combine(h, x);
786  }
787  return h;
788 }
789 
790 // Specialize traits so others can figure out that VtArray is an array.
791 template <typename T>
792 struct VtIsArray< VtArray <T> > : public std::true_type {};
793 
794 // free functions for operators combining scalar and array types
795 ARCH_PRAGMA_PUSH
796 ARCH_PRAGMA_FORCING_TO_BOOL
797 ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
798 ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
799 VTOPERATOR_CPPSCALAR(+)
800 VTOPERATOR_CPPSCALAR(-)
801 VTOPERATOR_CPPSCALAR(*)
802 VTOPERATOR_CPPSCALAR_DOUBLE(*)
803 VTOPERATOR_CPPSCALAR(/)
804 VTOPERATOR_CPPSCALAR_DOUBLE(/)
805 VTOPERATOR_CPPSCALAR(%)
806 ARCH_PRAGMA_POP
807 
808 PXR_NAMESPACE_CLOSE_SCOPE
809 
810 #endif // PXR_BASE_VT_ARRAY_H
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:222
bool operator!=(VtArray const &other) const
Tests two arrays for inequality.
Definition: array.h:654
void resize(size_t newSize, FillElemsFn &&fillElems)
Resize this array.
Definition: array.h:502
ElementType & operator[](size_t index)
Allows usage of [i].
Definition: array.h:628
void reserve(size_t num)
Ensure enough memory is allocated to hold num elements.
Definition: array.h:456
const_iterator end() const
Return a const iterator to the end of the array.
Definition: array.h:360
PointerIterator< const ElementType > const_iterator
Const iterator type.
Definition: array.h:224
friend std::ostream & operator<<(std::ostream &out, const VtArray &self)
Outputs a comma-separated list of the values in the array.
Definition: array.h:694
const_reverse_iterator rend() const
Return a const reverse iterator to the start of the array.
Definition: array.h:379
const_reference back() const
Return a const reference to the last element in this array.
Definition: array.h:481
VtArray(Vt_ArrayForeignDataSource *foreignSrc, ElementType *data, size_t size, bool addRef=true)
Create an array with foreign source.
Definition: array.h:268
VtArray & operator=(VtArray &&other)
Move assign from other.
Definition: array.h:329
const_reverse_iterator crend() const
Return a const reverse iterator to the start of the array.
Definition: array.h:386
VtArray & operator=(std::initializer_list< ELEM > initializerList)
Replace current array contents with those in initializerList.
Definition: array.h:340
reverse_iterator rend()
Return a reverse iterator to the start of the array.
Definition: array.h:372
iterator begin()
Return a non-const iterator to the start of the array.
Definition: array.h:352
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
PointerIterator< const ElementType >::pointer const_pointer
Const pointer type.
Definition: array.h:239
VtArray(LegacyInputIterator first, LegacyInputIterator last, typename std::enable_if< !std::is_integral< LegacyInputIterator >::value, void >::type *=nullptr)
Create an array from a pair of iterators.
Definition: array.h:259
const_reference front() const
Return a const reference to the first element in this array.
Definition: array.h:473
VtArray()
Create an empty array.
Definition: array.h:244
Scoped (i.e.
Definition: mallocTag.h:349
const_iterator cend() const
Return a const iterator to the end of the array.
Definition: array.h:365
VtArray & operator=(VtArray const &other)
Copy assign from other.
Definition: array.h:319
const_iterator begin() const
Return a const iterator to the start of the array.
Definition: array.h:358
void resize(size_t newSize)
Resize this array.
Definition: array.h:488
VtArray(size_t n, value_type const &value)
Create an array filled with n copies of value.
Definition: array.h:312
boost::reverse_iterator< iterator > reverse_iterator
Reverse iterator type.
Definition: array.h:226
iterator end()
Returns a non-const iterator to the end of the array.
Definition: array.h:355
bool operator==(VtArray const &other) const
Tests two arrays for equality. See also IsIdentical().
Definition: array.h:647
const_pointer cdata() const
Return a const pointer to the data held by this array.
Definition: array.h:394
void pop_back()
Remove the last element of an array.
Definition: array.h:421
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
const_pointer data() const
Return a const pointer to this array&#39;s data.
Definition: array.h:392
PointerIterator< const ElementType >::reference const_reference
Const reference type.
Definition: array.h:235
PointerIterator< ElementType >::reference reference
Reference type.
Definition: array.h:232
std::enable_if<!std::is_integral< ForwardIter >::value >::type assign(ForwardIter first, ForwardIter last)
Assign array contents.
Definition: array.h:581
const_iterator cbegin() const
Return a const iterator to the start of the array.
Definition: array.h:363
pointer data()
Return a non-const pointer to this array&#39;s data.
Definition: array.h:390
PointerIterator< ElementType > iterator
Iterator type.
Definition: array.h:222
size_t size() const
Return the total number of elements in this array.
Definition: array.h:435
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:194
reference back()
Return a reference to the last element in this array.
Definition: array.h:478
friend void swap(VtArray &lhs, VtArray &rhs)
Swap array contents.
Definition: array.h:701
reverse_iterator rbegin()
Return a non-const reverse iterator to the end of the array.
Definition: array.h:369
PointerIterator< ElementType >::pointer pointer
Pointer type.
Definition: array.h:237
bool IsIdentical(VtArray const &other) const
Tests if two arrays are identical, i.e.
Definition: array.h:639
Array concept. By default, types are not arrays.
Definition: traits.h:41
VtArray(VtArray &&other)
Move from other.
Definition: array.h:294
void swap(VtArray &other)
Swap the contents of this array with other.
Definition: array.h:619
VtArray(size_t n)
Create an array filled with n value-initialized elements.
Definition: array.h:306
reference front()
Return a non-const reference to the first element in this array.
Definition: array.h:470
boost::reverse_iterator< const_iterator > const_reverse_iterator
Reverse const iterator type.
Definition: array.h:228
Basic type for a vector of 2 float components.
Definition: vec2f.h:63
VtArray(std::initializer_list< ELEM > initializerList)
Initialize array from the contents of a initializerList.
Definition: array.h:300
size_t capacity() const
Return the number of items this container can grow to hold without triggering a (re)allocation.
Definition: array.h:441
void assign(size_t n, const value_type &fill)
Assign array contents.
Definition: array.h:598
const_reverse_iterator rbegin() const
Return a const reverse iterator to the end of the array.
Definition: array.h:375
ELEM ElementType
Type this array holds.
Definition: array.h:198
bool empty() const
Return true if this array contains no elements, false otherwise.
Definition: array.h:451
VtArray(VtArray const &other)
Copy other. The new array shares underlying data with other.
Definition: array.h:279
void clear()
Equivalent to resize(0).
Definition: array.h:557
const_reverse_iterator crbegin() const
Return a const reverse iterator to the end of the array.
Definition: array.h:384
void assign(std::initializer_list< ELEM > initializerList)
Assign array contents via intializer list Equivalent to:
Definition: array.h:614
void push_back(ElementType const &elem)
Append an element to array.
Definition: array.h:398
ElementType const & operator[](size_t index) const
Allows usage of [i].
Definition: array.h:633