array.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // This code is in the public domain -- Ignacio Castaño <[email protected]>
  2. #ifndef NV_CORE_ARRAY_H
  3. #define NV_CORE_ARRAY_H
  4. /*
  5. This array class requires the elements to be relocable; it uses memmove and realloc. Ideally I should be
  6. using swap, but I honestly don't care. The only thing that you should be aware of is that internal pointers
  7. are not supported.
  8. Note also that push_back and resize does not support inserting arguments elements that are in the same
  9. container. This is forbidden to prevent an extra copy.
  10. */
  11. #include "memory.h"
  12. #include "debug.h"
  13. #include "foreach.h" // pseudoindex
  14. namespace nv
  15. {
  16. class Stream;
  17. /**
  18. * Replacement for std::vector that is easier to debug and provides
  19. * some nice foreach enumerators.
  20. */
  21. template<typename T>
  22. class NVCORE_CLASS Array {
  23. public:
  24. typedef uint size_type;
  25. // Default constructor.
  26. NV_FORCEINLINE Array() : m_buffer(NULL), m_capacity(0), m_size(0) {}
  27. // Copy constructor.
  28. NV_FORCEINLINE Array(const Array & a) : m_buffer(NULL), m_capacity(0), m_size(0) {
  29. copy(a.m_buffer, a.m_size);
  30. }
  31. // Constructor that initializes the vector with the given elements.
  32. NV_FORCEINLINE Array(const T * ptr, uint num) : m_buffer(NULL), m_capacity(0), m_size(0) {
  33. copy(ptr, num);
  34. }
  35. // Allocate array.
  36. NV_FORCEINLINE explicit Array(uint capacity) : m_buffer(NULL), m_capacity(0), m_size(0) {
  37. setArrayCapacity(capacity);
  38. }
  39. // Destructor.
  40. NV_FORCEINLINE ~Array() {
  41. clear();
  42. free<T>(m_buffer);
  43. }
  44. /// Const element access.
  45. NV_FORCEINLINE const T & operator[]( uint index ) const
  46. {
  47. nvDebugCheck(index < m_size);
  48. return m_buffer[index];
  49. }
  50. NV_FORCEINLINE const T & at( uint index ) const
  51. {
  52. nvDebugCheck(index < m_size);
  53. return m_buffer[index];
  54. }
  55. /// Element access.
  56. NV_FORCEINLINE T & operator[] ( uint index )
  57. {
  58. nvDebugCheck(index < m_size);
  59. return m_buffer[index];
  60. }
  61. NV_FORCEINLINE T & at( uint index )
  62. {
  63. nvDebugCheck(index < m_size);
  64. return m_buffer[index];
  65. }
  66. /// Get vector size.
  67. NV_FORCEINLINE uint size() const { return m_size; }
  68. /// Get vector size.
  69. NV_FORCEINLINE uint count() const { return m_size; }
  70. /// Get vector capacity.
  71. NV_FORCEINLINE uint capacity() const { return m_capacity; }
  72. /// Get const vector pointer.
  73. NV_FORCEINLINE const T * buffer() const { return m_buffer; }
  74. /// Get vector pointer.
  75. NV_FORCEINLINE T * buffer() { return m_buffer; }
  76. /// Provide begin/end pointers for C++11 range-based for loops.
  77. NV_FORCEINLINE T * begin() { return m_buffer; }
  78. NV_FORCEINLINE T * end() { return m_buffer + m_size; }
  79. NV_FORCEINLINE const T * begin() const { return m_buffer; }
  80. NV_FORCEINLINE const T * end() const { return m_buffer + m_size; }
  81. /// Is vector empty.
  82. NV_FORCEINLINE bool isEmpty() const { return m_size == 0; }
  83. /// Is a null vector.
  84. NV_FORCEINLINE bool isNull() const { return m_buffer == NULL; }
  85. T & append();
  86. void push_back( const T & val );
  87. void pushBack( const T & val );
  88. Array<T> & append( const T & val );
  89. Array<T> & operator<< ( T & t );
  90. void pop_back();
  91. void popBack(uint count = 1);
  92. void popFront(uint count = 1);
  93. const T & back() const;
  94. T & back();
  95. const T & front() const;
  96. T & front();
  97. bool contains(const T & e) const;
  98. bool find(const T & element, uint * indexPtr) const;
  99. bool find(const T & element, uint begin, uint end, uint * indexPtr) const;
  100. void removeAt(uint index);
  101. bool remove(const T & element);
  102. void insertAt(uint index, const T & val = T());
  103. void append(const Array<T> & other);
  104. void append(const T other[], uint count);
  105. void replaceWithLast(uint index);
  106. void resize(uint new_size);
  107. void resize(uint new_size, const T & elem);
  108. void fill(const T & elem);
  109. void clear();
  110. void shrink();
  111. void reserve(uint desired_size);
  112. void copy(const T * data, uint count);
  113. Array<T> & operator=( const Array<T> & a );
  114. T * release();
  115. // Array enumerator.
  116. typedef uint PseudoIndex;
  117. NV_FORCEINLINE PseudoIndex start() const { return 0; }
  118. NV_FORCEINLINE bool isDone(const PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); return i == this->m_size; }
  119. NV_FORCEINLINE void advance(PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); i++; }
  120. #if NV_CC_MSVC
  121. NV_FORCEINLINE T & operator[]( const PseudoIndexWrapper & i ) {
  122. return m_buffer[i(this)];
  123. }
  124. NV_FORCEINLINE const T & operator[]( const PseudoIndexWrapper & i ) const {
  125. return m_buffer[i(this)];
  126. }
  127. #endif
  128. // Friends.
  129. template <typename Typ>
  130. friend Stream & operator<< ( Stream & s, Array<Typ> & p );
  131. template <typename Typ>
  132. friend void swap(Array<Typ> & a, Array<Typ> & b);
  133. protected:
  134. void setArraySize(uint new_size);
  135. void setArrayCapacity(uint new_capacity);
  136. T * m_buffer;
  137. uint m_capacity;
  138. uint m_size;
  139. };
  140. } // nv namespace
  141. #endif // NV_CORE_ARRAY_H