| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // This code is in the public domain -- Ignacio Castaño <[email protected]>
- #ifndef NV_CORE_ARRAY_H
- #define NV_CORE_ARRAY_H
- /*
- This array class requires the elements to be relocable; it uses memmove and realloc. Ideally I should be
- using swap, but I honestly don't care. The only thing that you should be aware of is that internal pointers
- are not supported.
- Note also that push_back and resize does not support inserting arguments elements that are in the same
- container. This is forbidden to prevent an extra copy.
- */
- #include "memory.h"
- #include "debug.h"
- #include "foreach.h" // pseudoindex
- namespace nv
- {
- class Stream;
- /**
- * Replacement for std::vector that is easier to debug and provides
- * some nice foreach enumerators.
- */
- template<typename T>
- class NVCORE_CLASS Array {
- public:
- typedef uint size_type;
- // Default constructor.
- NV_FORCEINLINE Array() : m_buffer(NULL), m_capacity(0), m_size(0) {}
- // Copy constructor.
- NV_FORCEINLINE Array(const Array & a) : m_buffer(NULL), m_capacity(0), m_size(0) {
- copy(a.m_buffer, a.m_size);
- }
- // Constructor that initializes the vector with the given elements.
- NV_FORCEINLINE Array(const T * ptr, uint num) : m_buffer(NULL), m_capacity(0), m_size(0) {
- copy(ptr, num);
- }
- // Allocate array.
- NV_FORCEINLINE explicit Array(uint capacity) : m_buffer(NULL), m_capacity(0), m_size(0) {
- setArrayCapacity(capacity);
- }
- // Destructor.
- NV_FORCEINLINE ~Array() {
- clear();
- free<T>(m_buffer);
- }
- /// Const element access.
- NV_FORCEINLINE const T & operator[]( uint index ) const
- {
- nvDebugCheck(index < m_size);
- return m_buffer[index];
- }
- NV_FORCEINLINE const T & at( uint index ) const
- {
- nvDebugCheck(index < m_size);
- return m_buffer[index];
- }
- /// Element access.
- NV_FORCEINLINE T & operator[] ( uint index )
- {
- nvDebugCheck(index < m_size);
- return m_buffer[index];
- }
- NV_FORCEINLINE T & at( uint index )
- {
- nvDebugCheck(index < m_size);
- return m_buffer[index];
- }
- /// Get vector size.
- NV_FORCEINLINE uint size() const { return m_size; }
- /// Get vector size.
- NV_FORCEINLINE uint count() const { return m_size; }
- /// Get vector capacity.
- NV_FORCEINLINE uint capacity() const { return m_capacity; }
- /// Get const vector pointer.
- NV_FORCEINLINE const T * buffer() const { return m_buffer; }
- /// Get vector pointer.
- NV_FORCEINLINE T * buffer() { return m_buffer; }
- /// Provide begin/end pointers for C++11 range-based for loops.
- NV_FORCEINLINE T * begin() { return m_buffer; }
- NV_FORCEINLINE T * end() { return m_buffer + m_size; }
- NV_FORCEINLINE const T * begin() const { return m_buffer; }
- NV_FORCEINLINE const T * end() const { return m_buffer + m_size; }
- /// Is vector empty.
- NV_FORCEINLINE bool isEmpty() const { return m_size == 0; }
- /// Is a null vector.
- NV_FORCEINLINE bool isNull() const { return m_buffer == NULL; }
- T & append();
- void push_back( const T & val );
- void pushBack( const T & val );
- Array<T> & append( const T & val );
- Array<T> & operator<< ( T & t );
- void pop_back();
- void popBack(uint count = 1);
- void popFront(uint count = 1);
- const T & back() const;
- T & back();
- const T & front() const;
- T & front();
- bool contains(const T & e) const;
- bool find(const T & element, uint * indexPtr) const;
- bool find(const T & element, uint begin, uint end, uint * indexPtr) const;
- void removeAt(uint index);
- bool remove(const T & element);
- void insertAt(uint index, const T & val = T());
- void append(const Array<T> & other);
- void append(const T other[], uint count);
- void replaceWithLast(uint index);
- void resize(uint new_size);
- void resize(uint new_size, const T & elem);
- void fill(const T & elem);
- void clear();
- void shrink();
- void reserve(uint desired_size);
- void copy(const T * data, uint count);
- Array<T> & operator=( const Array<T> & a );
- T * release();
- // Array enumerator.
- typedef uint PseudoIndex;
- NV_FORCEINLINE PseudoIndex start() const { return 0; }
- NV_FORCEINLINE bool isDone(const PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); return i == this->m_size; }
- NV_FORCEINLINE void advance(PseudoIndex & i) const { nvDebugCheck(i <= this->m_size); i++; }
- #if NV_CC_MSVC
- NV_FORCEINLINE T & operator[]( const PseudoIndexWrapper & i ) {
- return m_buffer[i(this)];
- }
- NV_FORCEINLINE const T & operator[]( const PseudoIndexWrapper & i ) const {
- return m_buffer[i(this)];
- }
- #endif
- // Friends.
- template <typename Typ>
- friend Stream & operator<< ( Stream & s, Array<Typ> & p );
- template <typename Typ>
- friend void swap(Array<Typ> & a, Array<Typ> & b);
- protected:
- void setArraySize(uint new_size);
- void setArrayCapacity(uint new_capacity);
- T * m_buffer;
- uint m_capacity;
- uint m_size;
- };
- } // nv namespace
- #endif // NV_CORE_ARRAY_H
|