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 
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 
228 template<typename ELEM>
229 class VtArray : public Vt_ArrayBase {
230  public:
231 
233  typedef ELEM ElementType;
234  typedef ELEM value_type;
235 
236  template <typename Value>
237  class PointerIterator
238  : public boost::iterator_adaptor<PointerIterator<Value>, Value *> {
239  public:
240  PointerIterator() :
241  PointerIterator::iterator_adaptor_(0) {}
242  explicit PointerIterator(Value *p) :
243  PointerIterator::iterator_adaptor_(p) {}
244  template <typename OtherValue>
245  PointerIterator(PointerIterator<OtherValue> const &other,
246  typename boost::enable_if_convertible
247  <OtherValue*, Value*>::type* = 0) :
248  PointerIterator::iterator_adaptor_(other.base()) {}
249  private:
250  friend class boost::iterator_core_access;
251  };
252 
255 
257  typedef PointerIterator<ElementType> iterator;
259  typedef PointerIterator<const ElementType> const_iterator;
261  typedef boost::reverse_iterator<iterator> reverse_iterator;
263  typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
264 
266  typedef typename PointerIterator<ElementType>::reference
269  typedef typename PointerIterator<const ElementType>::reference
272  typedef typename PointerIterator<ElementType>::pointer pointer;
274  typedef typename PointerIterator<const ElementType>::pointer const_pointer;
275 
277 
279  VtArray() : _data(nullptr) {}
280 
293  template <typename LegacyInputIterator>
294  VtArray(LegacyInputIterator first, LegacyInputIterator last,
295  typename std::enable_if<
296  !std::is_integral<LegacyInputIterator>::value,
297  void>::type* = nullptr)
298  : VtArray() {
299  assign(first, last);
300  }
301 
303  VtArray(Vt_ArrayForeignDataSource *foreignSrc,
304  ElementType *data, size_t size, bool addRef = true)
305  : Vt_ArrayBase(foreignSrc)
306  , _data(data) {
307  if (addRef) {
308  foreignSrc->_refCount.fetch_add(1, std::memory_order_relaxed);
309  }
310  _shapeData.totalSize = size;
311  }
312 
314  VtArray(VtArray const &other) : Vt_ArrayBase(other)
315  , _data(other._data) {
316  if (!_data)
317  return;
318 
319  if (ARCH_LIKELY(!_foreignSource)) {
320  _GetNativeRefCount(_data).fetch_add(1, std::memory_order_relaxed);
321  }
322  else {
323  _foreignSource->_refCount.fetch_add(1, std::memory_order_relaxed);
324  }
325  }
326 
329  VtArray(VtArray &&other) : Vt_ArrayBase(std::move(other))
330  , _data(other._data) {
331  other._data = nullptr;
332  }
333 
335  VtArray(std::initializer_list<ELEM> initializerList)
336  : VtArray() {
337  assign(initializerList);
338  }
339 
341  explicit VtArray(size_t n)
342  : VtArray() {
343  assign(n, value_type());
344  }
345 
347  explicit VtArray(size_t n, value_type const &value)
348  : VtArray() {
349  assign(n, value);
350  }
351 
354  VtArray &operator=(VtArray const &other) {
355  // This might look recursive but it's really invoking move-assign, since
356  // we create a temporary copy (an rvalue).
357  if (this != &other)
358  *this = VtArray(other);
359  return *this;
360  }
361 
365  if (this == &other)
366  return *this;
367  _DecRef();
368  static_cast<Vt_ArrayBase &>(*this) = std::move(other);
369  _data = other._data;
370  other._data = nullptr;
371  return *this;
372  }
373 
375  VtArray &operator=(std::initializer_list<ELEM> initializerList) {
376  this->assign(initializerList.begin(), initializerList.end());
377  return *this;
378  }
379 
380  ~VtArray() { _DecRef(); }
381 
390  VtArray const &AsConst() const noexcept {
391  return *this;
392  }
393 
396 
399  iterator begin() { return iterator(data()); }
402  iterator end() { return iterator(data() + size()); }
403 
405  const_iterator begin() const { return const_iterator(data()); }
407  const_iterator end() const { return const_iterator(data() + size()); }
408 
410  const_iterator cbegin() const { return begin(); }
412  const_iterator cend() const { return end(); }
413 
420 
423  return const_reverse_iterator(end());
424  }
427  return const_reverse_iterator(begin());
428  }
429 
431  const_reverse_iterator crbegin() const { return rbegin(); }
433  const_reverse_iterator crend() const { return rend(); }
434 
437  pointer data() { _DetachIfNotUnique(); return _data; }
439  const_pointer data() const { return _data; }
441  const_pointer cdata() const { return _data; }
442 
448  template <typename... Args>
449  void emplace_back(Args&&... args) {
450  // If this is a non-pxr array with rank > 1, disallow push_back.
451  if (ARCH_UNLIKELY(_shapeData.otherDims[0])) {
452  TF_CODING_ERROR("Array rank %u != 1", _shapeData.GetRank());
453  return;
454  }
455  // If we don't own the data, or if we need more space, realloc.
456  size_t curSize = size();
457  if (ARCH_UNLIKELY(
458  _foreignSource || !_IsUnique() || curSize == capacity())) {
459  value_type *newData = _AllocateCopy(
460  _data, _CapacityForSize(curSize + 1), curSize);
461  _DecRef();
462  _data = newData;
463  }
464  // Copy the value.
465  ::new (static_cast<void*>(_data + curSize)) value_type(
466  std::forward<Args>(args)...);
467  // Adjust size.
468  ++_shapeData.totalSize;
469  }
470 
476  void push_back(ElementType const& element) {
477  emplace_back(element);
478  }
479 
485  void push_back(ElementType&& element) {
486  emplace_back(std::move(element));
487  }
488 
491  void pop_back() {
492  // If this is a presto array with rank > 1, disallow push_back.
493  if (ARCH_UNLIKELY(_shapeData.otherDims[0])) {
494  TF_CODING_ERROR("Array rank %u != 1", _shapeData.GetRank());
495  return;
496  }
497  _DetachIfNotUnique();
498  // Invoke the destructor.
499  (_data + size() - 1)->~value_type();
500  // Adjust size.
501  --_shapeData.totalSize;
502  }
503 
505  size_t size() const { return _shapeData.totalSize; }
506 
511  size_t capacity() const {
512  if (!_data) {
513  return 0;
514  }
515  // We do not allow mutation to foreign source data, so always report
516  // foreign sourced arrays as at capacity.
517  return ARCH_UNLIKELY(_foreignSource) ? size() : _GetCapacity(_data);
518  }
519 
521  bool empty() const { return size() == 0; }
522 
526  void reserve(size_t num) {
527  if (num <= capacity())
528  return;
529 
530  value_type *newData =
531  _data ? _AllocateCopy(_data, num, size()) : _AllocateNew(num);
532 
533  _DecRef();
534  _data = newData;
535  }
536 
540  reference front() { return *begin(); }
543  const_reference front() const { return *begin(); }
546  const_reference cfront() const { return *begin(); }
547 
551  reference back() { return *rbegin(); }
554  const_reference back() const { return *rbegin(); }
557  const_reference cback() const { return *rbegin(); }
558 
564  void resize(size_t newSize) {
565  struct _Filler {
566  inline void operator()(pointer b, pointer e) const {
567  std::uninitialized_fill(b, e, value_type());
568  }
569  };
570  return resize(newSize, _Filler());
571  }
572 
577  template <class FillElemsFn>
578  void resize(size_t newSize, FillElemsFn &&fillElems) {
579  const size_t oldSize = size();
580  if (oldSize == newSize) {
581  return;
582  }
583  if (newSize == 0) {
584  clear();
585  return;
586  }
587 
588  const bool growing = newSize > oldSize;
589  value_type *newData = _data;
590 
591  if (!_data) {
592  // Allocate newSize elements and initialize.
593  newData = _AllocateNew(newSize);
594  std::forward<FillElemsFn>(fillElems)(newData, newData + newSize);
595  }
596  else if (_IsUnique()) {
597  if (growing) {
598  if (newSize > _GetCapacity(_data)) {
599  newData = _AllocateCopy(_data, newSize, oldSize);
600  }
601  // fill with newly added elements from oldSize to newSize.
602  std::forward<FillElemsFn>(fillElems)(newData + oldSize,
603  newData + newSize);
604  }
605  else {
606  // destroy removed elements
607  for (auto *cur = newData + newSize,
608  *end = newData + oldSize; cur != end; ++cur) {
609  cur->~value_type();
610  }
611  }
612  }
613  else {
614  newData =
615  _AllocateCopy(_data, newSize, growing ? oldSize : newSize);
616  if (growing) {
617  // fill with newly added elements from oldSize to newSize.
618  std::forward<FillElemsFn>(fillElems)(newData + oldSize,
619  newData + newSize);
620  }
621  }
622 
623  // If we created new data, clean up the old and move over to the new.
624  if (newData != _data) {
625  _DecRef();
626  _data = newData;
627  }
628  // Adjust size.
629  _shapeData.totalSize = newSize;
630  }
631 
633  void clear() {
634  if (!_data)
635  return;
636  if (_IsUnique()) {
637  // Clear out elements, run dtors, keep capacity.
638  for (value_type *p = _data, *e = _data + size(); p != e; ++p) {
639  p->~value_type();
640  }
641  }
642  else {
643  // Detach to empty.
644  _DecRef();
645  }
646  _shapeData.totalSize = 0;
647  }
648 
662  TF_DEV_AXIOM(pos != cend());
663  return erase(pos, pos+1);
664  }
665 
682  if (first == last){
683  return std::next(begin(), std::distance(cbegin(), last));
684  }
685  if ((first == cbegin()) && (last == cend())){
686  clear();
687  return end();
688  }
689  // Given the previous two conditions, we know that we are removing
690  // at least one element and the result array will contain at least one
691  // element.
692  value_type* removeStart = std::next(_data, std::distance(cbegin(), first));
693  value_type* removeEnd = std::next(_data, std::distance(cbegin(), last));
694  value_type* endIt = std::next(_data, size());
695  size_t newSize = size() - std::distance(first, last);
696  if (_IsUnique()){
697  // If the array is unique, we can simply move the tail elements
698  // and free to the end of the array.
699  value_type* deleteIt = std::move(removeEnd, endIt, removeStart);
700  for (; deleteIt != endIt; ++deleteIt) {
701  deleteIt->~value_type();
702  }
703  _shapeData.totalSize = newSize;
704  return iterator(removeStart);
705  } else{
706  // If the array is not unique, we want to avoid copying the
707  // elements in the range we are erasing. We allocate a
708  // new buffer and copy the head and tail ranges, omitting
709  // [first, last)
710  value_type* newData = _AllocateNew(newSize);
711  value_type* newMiddle = std::uninitialized_copy(
712  _data, removeStart, newData);
713  value_type* newEnd = std::uninitialized_copy(
714  removeEnd, endIt, newMiddle);
715  TF_DEV_AXIOM(newEnd == std::next(newData, newSize));
716  TF_DEV_AXIOM(std::distance(newData, newMiddle) ==
717  std::distance(_data, removeStart));
718  _DecRef();
719  _data = newData;
720  _shapeData.totalSize = newSize;
721  return iterator(newMiddle);
722  }
723  }
724 
731  template <class ForwardIter>
732  typename std::enable_if<!std::is_integral<ForwardIter>::value>::type
733  assign(ForwardIter first, ForwardIter last) {
734  struct _Copier {
735  void operator()(pointer b, pointer e) const {
736  std::uninitialized_copy(first, last, b);
737  }
738  ForwardIter const &first, &last;
739  };
740  clear();
741  resize(std::distance(first, last), _Copier { first, last });
742  }
743 
750  void assign(size_t n, const value_type &fill) {
751  struct _Filler {
752  void operator()(pointer b, pointer e) const {
753  std::uninitialized_fill(b, e, fill);
754  }
755  const value_type &fill;
756  };
757  clear();
758  resize(n, _Filler { fill });
759  }
760 
766  void assign(std::initializer_list<ELEM> initializerList) {
767  assign(initializerList.begin(), initializerList.end());
768  }
769 
771  void swap(VtArray &other) {
772  std::swap(_data, other._data);
773  std::swap(_shapeData, other._shapeData);
774  std::swap(_foreignSource, other._foreignSource);
775  }
776 
778 
780  ElementType &operator[](size_t index) {
781  return data()[index];
782  }
783 
785  ElementType const &operator[](size_t index) const {
786  return data()[index];
787  }
788 
791  bool IsIdentical(VtArray const & other) const {
792  return
793  _data == other._data &&
794  _shapeData == other._shapeData &&
795  _foreignSource == other._foreignSource;
796  }
797 
799  bool operator == (VtArray const & other) const {
800  return IsIdentical(other) ||
801  (*_GetShapeData() == *other._GetShapeData() &&
802  std::equal(cbegin(), cend(), other.cbegin()));
803  }
804 
806  bool operator != (VtArray const &other) const {
807  return !(*this == other);
808  }
809 
810 ARCH_PRAGMA_PUSH
811 ARCH_PRAGMA_FORCING_TO_BOOL
812 ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
813 ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
814  VTOPERATOR_CPPARRAY(+)
815  VTOPERATOR_CPPARRAY(-)
816  VTOPERATOR_CPPARRAY(*)
817  VTOPERATOR_CPPARRAY(/)
818  VTOPERATOR_CPPARRAY(%)
819  VTOPERATOR_CPPARRAY_UNARY(-)
820 ARCH_PRAGMA_POP
821 
822  public:
823  // XXX -- Public so VtValue::_ArrayHelper<T,U>::GetShapeData() has access.
824  Vt_ShapeData const *_GetShapeData() const {
825  return &_shapeData;
826  }
827  Vt_ShapeData *_GetShapeData() {
828  return &_shapeData;
829  }
830 
831  private:
832  class _Streamer : public VtStreamOutIterator {
833  public:
834  _Streamer(const_pointer data) : _p(data) { }
835  virtual ~_Streamer() { }
836  virtual void Next(std::ostream &out)
837  {
838  VtStreamOut(*_p++, out);
839  }
840 
841  private:
842  const_pointer _p;
843  };
844 
846  friend std::ostream &operator <<(std::ostream &out, const VtArray &self) {
847  VtArray::_Streamer streamer(self.cdata());
848  VtStreamOutArray(&streamer, self.size(), self._GetShapeData(), out);
849  return out;
850  }
851 
853  friend void swap(VtArray &lhs, VtArray &rhs) {
854  lhs.swap(rhs);
855  }
856 
857  void _DetachIfNotUnique() {
858  if (_IsUnique())
859  return;
860  // Copy to local.
861  _DetachCopyHook(__ARCH_PRETTY_FUNCTION__);
862  auto *newData = _AllocateCopy(_data, size(), size());
863  _DecRef();
864  _data = newData;
865  }
866 
867  inline bool _IsUnique() const {
868  return !_data ||
869  (ARCH_LIKELY(!_foreignSource) && _GetNativeRefCount(_data) == 1);
870  }
871 
872  inline size_t _CapacityForSize(size_t sz) const {
873  // Currently just successive powers of two.
874  size_t cap = 1;
875  while (cap < sz) {
876  cap += cap;
877  }
878  return cap;
879  }
880 
881  value_type *_AllocateNew(size_t capacity) {
882  TfAutoMallocTag2 tag("VtArray::_AllocateNew", __ARCH_PRETTY_FUNCTION__);
883  // Need space for the control block and capacity elements.
884  void *data = malloc(
885  sizeof(_ControlBlock) + capacity * sizeof(value_type));
886  // Placement-new a control block.
887  ::new (data) _ControlBlock(/*count=*/1, capacity);
888  // Data starts after the block.
889  return reinterpret_cast<value_type *>(
890  static_cast<_ControlBlock *>(data) + 1);
891  }
892 
893  value_type *_AllocateCopy(value_type *src, size_t newCapacity,
894  size_t numToCopy) {
895  // Allocate and copy elements.
896  value_type *newData = _AllocateNew(newCapacity);
897  std::uninitialized_copy(src, src + numToCopy, newData);
898  return newData;
899  }
900 
901  void _DecRef() {
902  if (!_data)
903  return;
904  if (ARCH_LIKELY(!_foreignSource)) {
905  // Drop the refcount. If we take it to zero, destroy the data.
906  if (_GetNativeRefCount(_data).fetch_sub(
907  1, std::memory_order_release) == 1) {
908  std::atomic_thread_fence(std::memory_order_acquire);
909  for (value_type *p = _data, *e = _data + _shapeData.totalSize;
910  p != e; ++p) {
911  p->~value_type();
912  }
913  free(std::addressof(_GetControlBlock(_data)));
914  }
915  }
916  else {
917  // Drop the refcount in the foreign source. If we take it to zero,
918  // invoke the function pointer to alert the foreign source.
919  if (_foreignSource->_refCount.fetch_sub(
920  1, std::memory_order_release) == 1) {
921  std::atomic_thread_fence(std::memory_order_acquire);
922  _foreignSource->_ArraysDetached();
923  }
924  }
925  _foreignSource = nullptr;
926  _data = nullptr;
927  }
928 
929  value_type *_data;
930 };
931 
932 template <class ELEM>
933 typename std::enable_if<VtIsHashable<ELEM>(), size_t>::type
934 hash_value(VtArray<ELEM> const &array) {
935  size_t h = array.size();
936  for (auto const &x: array) {
937  boost::hash_combine(h, x);
938  }
939  return h;
940 }
941 
942 // Specialize traits so others can figure out that VtArray is an array.
943 template <typename T>
944 struct VtIsArray< VtArray <T> > : public std::true_type {};
945 
946 // free functions for operators combining scalar and array types
947 ARCH_PRAGMA_PUSH
948 ARCH_PRAGMA_FORCING_TO_BOOL
949 ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
950 ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
951 VTOPERATOR_CPPSCALAR(+)
952 VTOPERATOR_CPPSCALAR(-)
953 VTOPERATOR_CPPSCALAR(*)
954 VTOPERATOR_CPPSCALAR_DOUBLE(*)
955 VTOPERATOR_CPPSCALAR(/)
956 VTOPERATOR_CPPSCALAR_DOUBLE(/)
957 VTOPERATOR_CPPSCALAR(%)
958 ARCH_PRAGMA_POP
959 
960 PXR_NAMESPACE_CLOSE_SCOPE
961 
962 #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
void resize(size_t newSize, FillElemsFn &&fillElems)
Resize this array.
Definition: array.h:578
ElementType & operator[](size_t index)
Allows usage of [i].
Definition: array.h:780
Pragmas for controlling compiler-specific behaviors.
void reserve(size_t num)
Ensure enough memory is allocated to hold num elements.
Definition: array.h:526
const_iterator begin() const
Return a const iterator to the start of the array.
Definition: array.h:405
PointerIterator< const ElementType > const_iterator
Const iterator type.
Definition: array.h:259
size_t capacity() const
Return the number of items this container can grow to hold without triggering a (re)allocation.
Definition: array.h:511
friend std::ostream & operator<<(std::ostream &out, const VtArray &self)
Outputs a comma-separated list of the values in the array.
Definition: array.h:846
const_reference cback() const
Return a const reference to the last element in this array.
Definition: array.h:557
VtArray(Vt_ArrayForeignDataSource *foreignSrc, ElementType *data, size_t size, bool addRef=true)
Create an array with foreign source.
Definition: array.h:303
VtArray & operator=(VtArray &&other)
Move assign from other.
Definition: array.h:364
VtArray & operator=(std::initializer_list< ELEM > initializerList)
Replace current array contents with those in initializerList.
Definition: array.h:375
reverse_iterator rend()
Return a reverse iterator to the start of the array.
Definition: array.h:419
size_t size() const
Return the total number of elements in this array.
Definition: array.h:505
Define preprocessor function name macros.
iterator begin()
Return a non-const iterator to the start of the array.
Definition: array.h:399
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
Basic type for a vector of 3 float components.
Definition: vec3f.h:63
const_reference cfront() const
Return a const reference to the first element in this array.
Definition: array.h:546
PointerIterator< const ElementType >::pointer const_pointer
Const pointer type.
Definition: array.h:274
Low-level utilities for informing users of various internal and external diagnostic conditions.
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:294
VtArray()
Create an empty array.
Definition: array.h:279
Scoped (i.e.
Definition: mallocTag.h:349
const_iterator end() const
Return a const iterator to the end of the array.
Definition: array.h:407
VtArray & operator=(VtArray const &other)
Copy assign from other.
Definition: array.h:354
void resize(size_t newSize)
Resize this array.
Definition: array.h:564
VtArray(size_t n, value_type const &value)
Create an array filled with n copies of value.
Definition: array.h:347
boost::reverse_iterator< iterator > reverse_iterator
Reverse iterator type.
Definition: array.h:261
iterator end()
Returns a non-const iterator to the end of the array.
Definition: array.h:402
bool IsIdentical(VtArray const &other) const
Tests if two arrays are identical, i.e.
Definition: array.h:791
void push_back(ElementType const &element)
Appends an element at the end of the array.
Definition: array.h:476
const_iterator cend() const
Return a const iterator to the end of the array.
Definition: array.h:412
void pop_back()
Remove the last element of an array.
Definition: array.h:491
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
const_reverse_iterator crend() const
Return a const reverse iterator to the start of the array.
Definition: array.h:433
const_reverse_iterator crbegin() const
Return a const reverse iterator to the end of the array.
Definition: array.h:431
const_iterator cbegin() const
Return a const iterator to the start of the array.
Definition: array.h:410
PointerIterator< const ElementType >::reference const_reference
Const reference type.
Definition: array.h:270
PointerIterator< ElementType >::reference reference
Reference type.
Definition: array.h:267
std::enable_if<!std::is_integral< ForwardIter >::value >::type assign(ForwardIter first, ForwardIter last)
Assign array contents.
Definition: array.h:733
void push_back(ElementType &&element)
Appends an element at the end of the array.
Definition: array.h:485
pointer data()
Return a non-const pointer to this array's data.
Definition: array.h:437
PointerIterator< ElementType > iterator
Iterator type.
Definition: array.h:257
VtArray const & AsConst() const noexcept
Return *this as a const reference.
Definition: array.h:390
const_reverse_iterator rbegin() const
Return a const reverse iterator to the end of the array.
Definition: array.h:422
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:229
reference back()
Return a reference to the last element in this array.
Definition: array.h:551
friend void swap(VtArray &lhs, VtArray &rhs)
Swap array contents.
Definition: array.h:853
reverse_iterator rbegin()
Return a non-const reverse iterator to the end of the array.
Definition: array.h:416
PointerIterator< ElementType >::pointer pointer
Pointer type.
Definition: array.h:272
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
Array concept. By default, types are not arrays.
Definition: traits.h:41
iterator erase(const_iterator pos)
Removes a single element at pos from the array.
Definition: array.h:661
VtArray(VtArray &&other)
Move from other.
Definition: array.h:329
void swap(VtArray &other)
Swap the contents of this array with other.
Definition: array.h:771
std::enable_if< std::is_same< Half, half >::value, size_t >::type hash_value(const Half &h)
Overload hash_value for half.
Definition: half.h:50
VtArray(size_t n)
Create an array filled with n value-initialized elements.
Definition: array.h:341
reference front()
Return a non-const reference to the first element in this array.
Definition: array.h:540
boost::reverse_iterator< const_iterator > const_reverse_iterator
Reverse const iterator type.
Definition: array.h:263
iterator erase(const_iterator first, const_iterator last)
Remove a range of elements [first, last) from the array.
Definition: array.h:681
const_reverse_iterator rend() const
Return a const reverse iterator to the start of the array.
Definition: array.h:426
bool empty() const
Return true if this array contains no elements, false otherwise.
Definition: array.h:521
VtArray(std::initializer_list< ELEM > initializerList)
Initialize array from the contents of a initializerList.
Definition: array.h:335
const_pointer cdata() const
Return a const pointer to the data held by this array.
Definition: array.h:441
const_reference front() const
Return a const reference to the first element in this array.
Definition: array.h:543
const_pointer data() const
Return a const pointer to this array's data.
Definition: array.h:439
void assign(size_t n, const value_type &fill)
Assign array contents.
Definition: array.h:750
ELEM ElementType
Type this array holds.
Definition: array.h:233
ElementType const & operator[](size_t index) const
Allows usage of [i].
Definition: array.h:785
const_reference back() const
Return a const reference to the last element in this array.
Definition: array.h:554
VtArray(VtArray const &other)
Copy other. The new array shares underlying data with other.
Definition: array.h:314
void emplace_back(Args &&... args)
Initializes a new element at the end of the array.
Definition: array.h:449
bool operator==(VtArray const &other) const
Tests two arrays for equality. See also IsIdentical().
Definition: array.h:799
void clear()
Equivalent to resize(0).
Definition: array.h:633
void assign(std::initializer_list< ELEM > initializerList)
Assign array contents via intializer list Equivalent to:
Definition: array.h:766
bool operator !=(VtArray const &other) const
Tests two arrays for inequality.
Definition: array.h:806