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 VT_ARRAY_H
25 #define 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 
52 PXR_NAMESPACE_OPEN_SCOPE
53 
54 // Helper class for clients that create VtArrays referring to foreign-owned
55 // data.
56 class Vt_ArrayForeignDataSource
57 {
58 public:
59  explicit Vt_ArrayForeignDataSource(
60  void (*detachedFn)(Vt_ArrayForeignDataSource *self) = nullptr,
61  size_t initRefCount = 0)
62  : _refCount(initRefCount)
63  , _detachedFn(detachedFn) {}
64 
65 private:
66  template <class T> friend class VtArray;
67  // Invoked when no more arrays share this data source.
68  void _ArraysDetached() { if (_detachedFn) { _detachedFn(this); } }
69 protected:
70  std::atomic<size_t> _refCount;
71  void (*_detachedFn)(Vt_ArrayForeignDataSource *self);
72 };
73 
74 // Private base class helper for VtArray implementation.
75 class Vt_ArrayBase
76 {
77 public:
78  Vt_ArrayBase() : _shapeData { 0 }, _foreignSource(nullptr) {}
79 
80  Vt_ArrayBase(Vt_ArrayForeignDataSource *foreignSrc)
81  : _shapeData { 0 }, _foreignSource(foreignSrc) {}
82 
83  Vt_ArrayBase(Vt_ArrayBase const &other) = default;
84  Vt_ArrayBase(Vt_ArrayBase &&other) : Vt_ArrayBase(other) {
85  other._shapeData.clear();
86  other._foreignSource = nullptr;
87  }
88 
89  Vt_ArrayBase &operator=(Vt_ArrayBase const &other) = default;
90  Vt_ArrayBase &operator=(Vt_ArrayBase &&other) {
91  if (this == &other)
92  return *this;
93  *this = other;
94  other._shapeData.clear();
95  other._foreignSource = nullptr;
96  return *this;
97  }
98 
99 protected:
100  // Control block header for native data representation. Houses refcount and
101  // capacity. For arrays with native data, this structure always lives
102  // immediately preceding the start of the array's _data in memory. See
103  // _GetControlBlock() for details.
104  struct _ControlBlock {
105  _ControlBlock() : nativeRefCount(0), capacity(0) {}
106  _ControlBlock(size_t initCount, size_t initCap)
107  : nativeRefCount(initCount), capacity(initCap) {}
108  mutable std::atomic<size_t> nativeRefCount;
109  size_t capacity;
110  };
111 
112  _ControlBlock &_GetControlBlock(void *nativeData) {
113  TF_DEV_AXIOM(!_foreignSource);
114  return *(reinterpret_cast<_ControlBlock *>(nativeData) - 1);
115  }
116 
117  _ControlBlock const &_GetControlBlock(void *nativeData) const {
118  TF_DEV_AXIOM(!_foreignSource);
119  return *(reinterpret_cast<_ControlBlock *>(nativeData) - 1);
120  }
121 
122  // Mutable ref count, as is standard.
123  std::atomic<size_t> &_GetNativeRefCount(void *nativeData) const {
124  return _GetControlBlock(nativeData).nativeRefCount;
125  }
126 
127  size_t &_GetCapacity(void *nativeData) {
128  return _GetControlBlock(nativeData).capacity;
129  }
130  size_t const &_GetCapacity(void *nativeData) const {
131  return _GetControlBlock(nativeData).capacity;
132  }
133 
134  VT_API void _DetachCopyHook(char const *funcName) const;
135 
136  Vt_ShapeData _shapeData;
137  Vt_ArrayForeignDataSource *_foreignSource;
138 };
139 
192 template<typename ELEM>
193 class VtArray : public Vt_ArrayBase {
194  public:
195 
197  typedef ELEM ElementType;
198  typedef ELEM value_type;
199 
200  template <typename Value>
201  class PointerIterator
202  : public boost::iterator_adaptor<PointerIterator<Value>, Value *> {
203  public:
204  PointerIterator() :
205  PointerIterator::iterator_adaptor_(0) {}
206  explicit PointerIterator(Value *p) :
207  PointerIterator::iterator_adaptor_(p) {}
208  template <typename OtherValue>
209  PointerIterator(PointerIterator<OtherValue> const &other,
210  typename boost::enable_if_convertible
211  <OtherValue*, Value*>::type* = 0) :
212  PointerIterator::iterator_adaptor_(other.base()) {}
213  private:
214  friend class boost::iterator_core_access;
215  };
216 
219 
221  typedef PointerIterator<ElementType> iterator;
223  typedef PointerIterator<const ElementType> const_iterator;
225  typedef boost::reverse_iterator<iterator> reverse_iterator;
227  typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
228 
230  typedef typename PointerIterator<ElementType>::reference
233  typedef typename PointerIterator<const ElementType>::reference
236  typedef typename PointerIterator<ElementType>::pointer pointer;
238  typedef typename PointerIterator<const ElementType>::pointer const_pointer;
239 
241 
243  VtArray() : _data(nullptr) {}
244 
257  template <typename LegacyInputIterator>
258  VtArray(LegacyInputIterator first, LegacyInputIterator last,
259  typename std::enable_if<
260  !std::is_integral<LegacyInputIterator>::value,
261  void>::type* = nullptr)
262  : VtArray() {
263  assign(first, last);
264  }
265 
267  VtArray(Vt_ArrayForeignDataSource *foreignSrc,
268  ElementType *data, size_t size, bool addRef = true)
269  : Vt_ArrayBase(foreignSrc)
270  , _data(data) {
271  if (addRef) {
272  foreignSrc->_refCount.fetch_add(1, std::memory_order_relaxed);
273  }
274  _shapeData.totalSize = size;
275  }
276 
278  VtArray(VtArray const &other) : Vt_ArrayBase(other)
279  , _data(other._data) {
280  if (!_data)
281  return;
282 
283  if (ARCH_LIKELY(!_foreignSource)) {
284  _GetNativeRefCount(_data).fetch_add(1, std::memory_order_relaxed);
285  }
286  else {
287  _foreignSource->_refCount.fetch_add(1, std::memory_order_relaxed);
288  }
289  }
290 
293  VtArray(VtArray &&other) : Vt_ArrayBase(std::move(other))
294  , _data(other._data) {
295  other._data = nullptr;
296  }
297 
299  VtArray(std::initializer_list<ELEM> initializerList)
300  : VtArray() {
301  assign(initializerList);
302  }
303 
306  VtArray &operator=(VtArray const &other) {
307  // This might look recursive but it's really invoking move-assign, since
308  // we create a temporary copy (an rvalue).
309  if (this != &other)
310  *this = VtArray(other);
311  return *this;
312  }
313 
317  if (this == &other)
318  return *this;
319  _DecRef();
320  static_cast<Vt_ArrayBase &>(*this) = std::move(other);
321  _data = other._data;
322  other._data = nullptr;
323  return *this;
324  }
325 
327  VtArray &operator=(std::initializer_list<ELEM> initializerList) {
328  this->assign(initializerList.begin(), initializerList.end());
329  return *this;
330  }
331 
333  explicit VtArray(size_t n, value_type const &value = value_type())
334  : VtArray() {
335  assign(n, value);
336  }
337 
338  ~VtArray() { _DecRef(); }
339 
342 
345  iterator begin() { return iterator(data()); }
348  iterator end() { return iterator(data() + size()); }
349 
351  const_iterator begin() const { return const_iterator(data()); }
353  const_iterator end() const { return const_iterator(data() + size()); }
354 
356  const_iterator cbegin() const { return begin(); }
358  const_iterator cend() const { return end(); }
359 
366 
369  return const_reverse_iterator(end());
370  }
373  return const_reverse_iterator(begin());
374  }
375 
377  const_reverse_iterator crbegin() const { return rbegin(); }
379  const_reverse_iterator crend() const { return rend(); }
380 
383  pointer data() { _DetachIfNotUnique(); return _data; }
385  const_pointer data() const { return _data; }
387  const_pointer cdata() const { return _data; }
388 
391  void push_back(ElementType const &elem) {
392  // If this is a non-pxr array with rank > 1, disallow push_back.
393  if (ARCH_UNLIKELY(_shapeData.otherDims[0])) {
394  TF_CODING_ERROR("Array rank %u != 1", _shapeData.GetRank());
395  return;
396  }
397  // If we don't own the data, or if we need more space, realloc.
398  size_t curSize = size();
399  if (ARCH_UNLIKELY(
400  _foreignSource || !_IsUnique() || curSize == capacity())) {
401  value_type *newData = _AllocateCopy(
402  _data, _CapacityForSize(curSize + 1), curSize);
403  _DecRef();
404  _data = newData;
405  }
406  // Copy the value.
407  ::new (static_cast<void*>(_data + curSize)) value_type(elem);
408  // Adjust size.
409  ++_shapeData.totalSize;
410  }
411 
414  void pop_back() {
415  // If this is a presto array with rank > 1, disallow push_back.
416  if (ARCH_UNLIKELY(_shapeData.otherDims[0])) {
417  TF_CODING_ERROR("Array rank %u != 1", _shapeData.GetRank());
418  return;
419  }
420  _DetachIfNotUnique();
421  // Invoke the destructor.
422  (_data + size() - 1)->~value_type();
423  // Adjust size.
424  --_shapeData.totalSize;
425  }
426 
428  size_t size() const { return _shapeData.totalSize; }
429 
434  size_t capacity() const {
435  if (!_data) {
436  return 0;
437  }
438  // We do not allow mutation to foreign source data, so always report
439  // foreign sourced arrays as at capacity.
440  return ARCH_UNLIKELY(_foreignSource) ? size() : _GetCapacity(_data);
441  }
442 
444  bool empty() const { return size() == 0; }
445 
449  void reserve(size_t num) {
450  if (num <= capacity())
451  return;
452 
453  value_type *newData =
454  _data ? _AllocateCopy(_data, num, size()) : _AllocateNew(num);
455 
456  _DecRef();
457  _data = newData;
458  }
459 
463  reference front() { return *begin(); }
466  const_reference front() const { return *begin(); }
467 
471  reference back() { return *rbegin(); }
474  const_reference back() const { return *rbegin(); }
475 
481  void resize(size_t newSize) {
482  const size_t oldSize = size();
483  if (oldSize == newSize) {
484  return;
485  }
486  if (newSize == 0) {
487  clear();
488  return;
489  }
490 
491  const bool growing = newSize > oldSize;
492  value_type *newData = _data;
493 
494  if (!_data) {
495  // Allocate newSize elements and initialize.
496  newData = _AllocateNew(newSize);
497  std::uninitialized_fill_n(newData, newSize, value_type());
498  }
499  else if (_IsUnique()) {
500  if (growing) {
501  if (newSize > _GetCapacity(_data)) {
502  newData = _AllocateCopy(_data, newSize, oldSize);
503  }
504  // fill with newly added elements from oldSize to newSize.
505  std::uninitialized_fill(
506  newData + oldSize, newData + newSize, value_type());
507  }
508  else {
509  // destroy removed elements
510  for (auto *cur = newData + newSize,
511  *end = newData + oldSize; cur != end; ++cur) {
512  cur->~value_type();
513  }
514  }
515  }
516  else {
517  newData =
518  _AllocateCopy(_data, newSize, growing ? oldSize : newSize);
519  if (growing) {
520  // fill with newly added elements from oldSize to newSize.
521  std::uninitialized_fill(
522  newData + oldSize, newData + newSize, value_type());
523  }
524  }
525 
526  // If we created new data, clean up the old and move over to the new.
527  if (newData != _data) {
528  _DecRef();
529  _data = newData;
530  }
531  // Adjust size.
532  _shapeData.totalSize = newSize;
533  }
534 
536  void clear() {
537  if (!_data)
538  return;
539  if (_IsUnique()) {
540  // Clear out elements, run dtors, keep capacity.
541  for (value_type *p = _data, *e = _data + size(); p != e; ++p) {
542  p->~value_type();
543  }
544  }
545  else {
546  // Detach to empty.
547  _DecRef();
548  }
549  _shapeData.totalSize = 0;
550  }
551 
558  template <class ForwardIter>
559  void assign(ForwardIter first, ForwardIter last) {
560  resize(std::distance(first, last));
561  std::copy(first, last, begin());
562  }
563 
570  void assign(size_t n, const value_type &fill) {
571  resize(n);
572  std::fill(begin(), end(), fill);
573  }
574 
580  void assign(std::initializer_list<ELEM> initializerList) {
581  assign(initializerList.begin(), initializerList.end());
582  }
583 
585  void swap(VtArray &other) {
586  std::swap(_data, other._data);
587  std::swap(_shapeData, other._shapeData);
588  std::swap(_foreignSource, other._foreignSource);
589  }
590 
592 
594  ElementType &operator[](size_t index) {
595  return data()[index];
596  }
597 
599  ElementType const &operator[](size_t index) const {
600  return data()[index];
601  }
602 
605  bool IsIdentical(VtArray const & other) const {
606  return
607  _data == other._data &&
608  _shapeData == other._shapeData &&
609  _foreignSource == other._foreignSource;
610  }
611 
613  bool operator == (VtArray const & other) const {
614  return IsIdentical(other) ||
615  (*_GetShapeData() == *other._GetShapeData() &&
616  std::equal(cbegin(), cend(), other.cbegin()));
617  }
618 
620  bool operator != (VtArray const &other) const {
621  return !(*this == other);
622  }
623 
624 ARCH_PRAGMA_PUSH
625 ARCH_PRAGMA_FORCING_TO_BOOL
626 ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
627 ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
628  VTOPERATOR_CPPARRAY(+)
629  VTOPERATOR_CPPARRAY(-)
630  VTOPERATOR_CPPARRAY(*)
631  VTOPERATOR_CPPARRAY(/)
632  VTOPERATOR_CPPARRAY(%)
633  VTOPERATOR_CPPARRAY_UNARY(-)
634 ARCH_PRAGMA_POP
635 
636  public:
637  // XXX -- Public so VtValue::_ArrayHelper<T,U>::GetShapeData() has access.
638  Vt_ShapeData const *_GetShapeData() const {
639  return &_shapeData;
640  }
641  Vt_ShapeData *_GetShapeData() {
642  return &_shapeData;
643  }
644 
645  private:
646  class _Streamer : public VtStreamOutIterator {
647  public:
648  _Streamer(const_pointer data) : _p(data) { }
649  virtual ~_Streamer() { }
650  virtual void Next(std::ostream &out)
651  {
652  VtStreamOut(*_p++, out);
653  }
654 
655  private:
656  const_pointer _p;
657  };
658 
660  friend std::ostream &operator <<(std::ostream &out, const VtArray &self) {
661  VtArray::_Streamer streamer(self.cdata());
662  VtStreamOutArray(&streamer, self.size(), self._GetShapeData(), out);
663  return out;
664  }
665 
667  friend void swap(VtArray &lhs, VtArray &rhs) {
668  lhs.swap(rhs);
669  }
670 
671  void _DetachIfNotUnique() {
672  if (_IsUnique())
673  return;
674  // Copy to local.
675  _DetachCopyHook(__ARCH_PRETTY_FUNCTION__);
676  auto *newData = _AllocateCopy(_data, size(), size());
677  _DecRef();
678  _data = newData;
679  }
680 
681  inline bool _IsUnique() const {
682  return !_data ||
683  (ARCH_LIKELY(!_foreignSource) && _GetNativeRefCount(_data) == 1);
684  }
685 
686  inline size_t _CapacityForSize(size_t sz) const {
687  // Currently just successive powers of two.
688  size_t cap = 1;
689  while (cap < sz) {
690  cap += cap;
691  }
692  return cap;
693  }
694 
695  value_type *_AllocateNew(size_t capacity) {
696  TfAutoMallocTag2 tag("VtArray::_AllocateNew", __ARCH_PRETTY_FUNCTION__);
697  // Need space for the control block and capacity elements.
698  void *data = malloc(
699  sizeof(_ControlBlock) + capacity * sizeof(value_type));
700  // Placement-new a control block.
701  ::new (data) _ControlBlock(/*count=*/1, capacity);
702  // Data starts after the block.
703  return reinterpret_cast<value_type *>(
704  static_cast<_ControlBlock *>(data) + 1);
705  }
706 
707  value_type *_AllocateCopy(value_type *src, size_t newCapacity,
708  size_t numToCopy) {
709  // Allocate and copy elements.
710  value_type *newData = _AllocateNew(newCapacity);
711  std::uninitialized_copy(src, src + numToCopy, newData);
712  return newData;
713  }
714 
715  void _DecRef() {
716  if (!_data)
717  return;
718  if (ARCH_LIKELY(!_foreignSource)) {
719  // Drop the refcount. If we take it to zero, destroy the data.
720  if (_GetNativeRefCount(_data).fetch_sub(
721  1, std::memory_order_release) == 1) {
722  std::atomic_thread_fence(std::memory_order_acquire);
723  for (value_type *p = _data, *e = _data + _shapeData.totalSize;
724  p != e; ++p) {
725  p->~value_type();
726  }
727  free(std::addressof(_GetControlBlock(_data)));
728  }
729  }
730  else {
731  // Drop the refcount in the foreign source. If we take it to zero,
732  // invoke the function pointer to alert the foreign source.
733  if (_foreignSource->_refCount.fetch_sub(
734  1, std::memory_order_release) == 1) {
735  std::atomic_thread_fence(std::memory_order_acquire);
736  _foreignSource->_ArraysDetached();
737  }
738  }
739  _foreignSource = nullptr;
740  _data = nullptr;
741  }
742 
743  value_type *_data;
744 };
745 
746 template <class ELEM>
747 typename std::enable_if<VtIsHashable<ELEM>(), size_t>::type
748 hash_value(VtArray<ELEM> const &array) {
749  size_t h = array.size();
750  for (auto const &x: array) {
751  boost::hash_combine(h, x);
752  }
753  return h;
754 }
755 
756 // Specialize traits so others can figure out that VtArray is an array.
757 template <typename T>
758 struct VtIsArray< VtArray <T> > : public std::true_type {};
759 
760 // free functions for operators combining scalar and array types
761 ARCH_PRAGMA_PUSH
762 ARCH_PRAGMA_FORCING_TO_BOOL
763 ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
764 ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
765 VTOPERATOR_CPPSCALAR(+)
766 VTOPERATOR_CPPSCALAR(-)
767 VTOPERATOR_CPPSCALAR(*)
768 VTOPERATOR_CPPSCALAR_DOUBLE(*)
769 VTOPERATOR_CPPSCALAR(/)
770 VTOPERATOR_CPPSCALAR_DOUBLE(/)
771 VTOPERATOR_CPPSCALAR(%)
772 ARCH_PRAGMA_POP
773 
774 PXR_NAMESPACE_CLOSE_SCOPE
775 
776 #endif // VT_ARRAY_H
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:227
bool operator!=(VtArray const &other) const
Tests two arrays for inequality.
Definition: array.h:620
ElementType & operator[](size_t index)
Allows usage of [i].
Definition: array.h:594
void reserve(size_t num)
Ensure enough memory is allocated to hold num elements.
Definition: array.h:449
const_iterator end() const
Return a const iterator to the end of the array.
Definition: array.h:353
PointerIterator< const ElementType > const_iterator
Const iterator type.
Definition: array.h:223
friend std::ostream & operator<<(std::ostream &out, const VtArray &self)
Outputs a comma-separated list of the values in the array.
Definition: array.h:660
const_reverse_iterator rend() const
Return a const reverse iterator to the start of the array.
Definition: array.h:372
const_reference back() const
Return a const reference to the last element in this array.
Definition: array.h:474
VtArray(Vt_ArrayForeignDataSource *foreignSrc, ElementType *data, size_t size, bool addRef=true)
Create an array with foreign source.
Definition: array.h:267
VtArray & operator=(VtArray &&other)
Move assign from other.
Definition: array.h:316
const_reverse_iterator crend() const
Return a const reverse iterator to the start of the array.
Definition: array.h:379
VtArray & operator=(std::initializer_list< ELEM > initializerList)
Replace current array contents with those in initializerList.
Definition: array.h:327
reverse_iterator rend()
Return a reverse iterator to the start of the array.
Definition: array.h:365
iterator begin()
Return a non-const iterator to the start of the array.
Definition: array.h:345
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:87
PointerIterator< const ElementType >::pointer const_pointer
Const pointer type.
Definition: array.h:238
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:258
const_reference front() const
Return a const reference to the first element in this array.
Definition: array.h:466
VtArray()
Create an empty array.
Definition: array.h:243
Scoped (i.e.
Definition: mallocTag.h:349
const_iterator cend() const
Return a const iterator to the end of the array.
Definition: array.h:358
VtArray & operator=(VtArray const &other)
Copy assign from other.
Definition: array.h:306
const_iterator begin() const
Return a const iterator to the start of the array.
Definition: array.h:351
void resize(size_t newSize)
Resize this array.
Definition: array.h:481
boost::reverse_iterator< iterator > reverse_iterator
Reverse iterator type.
Definition: array.h:225
iterator end()
Returns a non-const iterator to the end of the array.
Definition: array.h:348
bool operator==(VtArray const &other) const
Tests two arrays for equality. See also IsIdentical().
Definition: array.h:613
VtArray(size_t n, value_type const &value=value_type())
Create an array filled with n copies of value.
Definition: array.h:333
const_pointer cdata() const
Return a const pointer to the data held by this array.
Definition: array.h:387
void pop_back()
Remove the last element of an array.
Definition: array.h:414
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:385
PointerIterator< const ElementType >::reference const_reference
Const reference type.
Definition: array.h:234
PointerIterator< ElementType >::reference reference
Reference type.
Definition: array.h:231
const_iterator cbegin() const
Return a const iterator to the start of the array.
Definition: array.h:356
pointer data()
Return a non-const pointer to this array&#39;s data.
Definition: array.h:383
PointerIterator< ElementType > iterator
Iterator type.
Definition: array.h:221
size_t size() const
Return the total number of elements in this array.
Definition: array.h:428
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:193
reference back()
Return a reference to the last element in this array.
Definition: array.h:471
friend void swap(VtArray &lhs, VtArray &rhs)
Swap array contents.
Definition: array.h:667
reverse_iterator rbegin()
Return a non-const reverse iterator to the end of the array.
Definition: array.h:362
PointerIterator< ElementType >::pointer pointer
Pointer type.
Definition: array.h:236
bool IsIdentical(VtArray const &other) const
Tests if two arrays are identical, i.e.
Definition: array.h:605
Array concept. By default, types are not arrays.
Definition: traits.h:41
VtArray(VtArray &&other)
Move from other.
Definition: array.h:293
void swap(VtArray &other)
Swap the contents of this array with other.
Definition: array.h:585
reference front()
Return a non-const reference to the first element in this array.
Definition: array.h:463
boost::reverse_iterator< const_iterator > const_reverse_iterator
Reverse const iterator type.
Definition: array.h:227
VtArray(std::initializer_list< ELEM > initializerList)
Initialize array from the contents of a initializerList.
Definition: array.h:299
size_t capacity() const
Return the number of items this container can grow to hold without triggering a (re)allocation.
Definition: array.h:434
void assign(size_t n, const value_type &fill)
Assign array contents.
Definition: array.h:570
const_reverse_iterator rbegin() const
Return a const reverse iterator to the end of the array.
Definition: array.h:368
ELEM ElementType
Type this array holds.
Definition: array.h:197
bool empty() const
Return true if this array contains no elements, false otherwise.
Definition: array.h:444
VtArray(VtArray const &other)
Copy other. The new array shares underlying data with other.
Definition: array.h:278
void clear()
Equivalent to resize(0).
Definition: array.h:536
const_reverse_iterator crbegin() const
Return a const reverse iterator to the end of the array.
Definition: array.h:377
void assign(std::initializer_list< ELEM > initializerList)
Assign array contents via intializer list Equivalent to:
Definition: array.h:580
void push_back(ElementType const &elem)
Append an element to array.
Definition: array.h:391
ElementType const & operator[](size_t index) const
Allows usage of [i].
Definition: array.h:599
void assign(ForwardIter first, ForwardIter last)
Assign array contents.
Definition: array.h:559