Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
| Show All 28 Lines | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files | ||||
| GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. | GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. | ||||
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ||||
| */ | */ | ||||
| #include "gim_memory.h" | #include "gim_memory.h" | ||||
| #define GIM_ARRAY_GROW_INCREMENT 2 | #define GIM_ARRAY_GROW_INCREMENT 2 | ||||
| #define GIM_ARRAY_GROW_FACTOR 2 | #define GIM_ARRAY_GROW_FACTOR 2 | ||||
| //! Very simple array container with fast access and simd memory | //! Very simple array container with fast access and simd memory | ||||
| template<typename T> | template <typename T> | ||||
| class gim_array | class gim_array | ||||
| { | { | ||||
| public: | public: | ||||
| //! properties | //! properties | ||||
| //!@{ | //!@{ | ||||
| T *m_data; | T* m_data; | ||||
| GUINT m_size; | GUINT m_size; | ||||
| GUINT m_allocated_size; | GUINT m_allocated_size; | ||||
| //!@} | //!@} | ||||
| //! protected operations | //! protected operations | ||||
| //!@{ | //!@{ | ||||
| inline void destroyData() | inline void destroyData() | ||||
| { | { | ||||
| m_allocated_size = 0; | m_allocated_size = 0; | ||||
| if(m_data==NULL) return; | if (m_data == NULL) return; | ||||
| gim_free(m_data); | gim_free(m_data); | ||||
| m_data = NULL; | m_data = NULL; | ||||
| } | } | ||||
| inline bool resizeData(GUINT newsize) | inline bool resizeData(GUINT newsize) | ||||
| { | { | ||||
| if(newsize==0) | if (newsize == 0) | ||||
| { | { | ||||
| destroyData(); | destroyData(); | ||||
| return true; | return true; | ||||
| } | } | ||||
| if(m_size>0) | if (m_size > 0) | ||||
| { | { | ||||
| m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T)); | m_data = (T*)gim_realloc(m_data, m_size * sizeof(T), newsize * sizeof(T)); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| m_data = (T*)gim_alloc(newsize*sizeof(T)); | m_data = (T*)gim_alloc(newsize * sizeof(T)); | ||||
| } | } | ||||
| m_allocated_size = newsize; | m_allocated_size = newsize; | ||||
| return true; | return true; | ||||
| } | } | ||||
| inline bool growingCheck() | inline bool growingCheck() | ||||
| { | { | ||||
| if(m_allocated_size<=m_size) | if (m_allocated_size <= m_size) | ||||
| { | { | ||||
| GUINT requestsize = m_size; | GUINT requestsize = m_size; | ||||
| m_size = m_allocated_size; | m_size = m_allocated_size; | ||||
| if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false; | if (resizeData((requestsize + GIM_ARRAY_GROW_INCREMENT) * GIM_ARRAY_GROW_FACTOR) == false) return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| //!@} | //!@} | ||||
| //! public operations | //! public operations | ||||
| //!@{ | //!@{ | ||||
| inline bool reserve(GUINT size) | inline bool reserve(GUINT size) | ||||
| { | { | ||||
| if(m_allocated_size>=size) return false; | if (m_allocated_size >= size) return false; | ||||
| return resizeData(size); | return resizeData(size); | ||||
| } | } | ||||
| inline void clear_range(GUINT start_range) | inline void clear_range(GUINT start_range) | ||||
| { | { | ||||
| while(m_size>start_range) | while (m_size > start_range) | ||||
| { | { | ||||
| m_data[--m_size].~T(); | m_data[--m_size].~T(); | ||||
| } | } | ||||
| } | } | ||||
| inline void clear() | inline void clear() | ||||
| { | { | ||||
| if(m_size==0)return; | if (m_size == 0) return; | ||||
| clear_range(0); | clear_range(0); | ||||
| } | } | ||||
| inline void clear_memory() | inline void clear_memory() | ||||
| { | { | ||||
| clear(); | clear(); | ||||
| destroyData(); | destroyData(); | ||||
| } | } | ||||
| gim_array() | gim_array() | ||||
| { | { | ||||
| m_data = 0; | m_data = 0; | ||||
| m_size = 0; | m_size = 0; | ||||
| m_allocated_size = 0; | m_allocated_size = 0; | ||||
| } | } | ||||
| gim_array(GUINT reservesize) | gim_array(GUINT reservesize) | ||||
| { | { | ||||
| m_data = 0; | m_data = 0; | ||||
| m_size = 0; | m_size = 0; | ||||
| m_allocated_size = 0; | m_allocated_size = 0; | ||||
| reserve(reservesize); | reserve(reservesize); | ||||
| } | } | ||||
| ~gim_array() | ~gim_array() | ||||
| { | { | ||||
| clear_memory(); | clear_memory(); | ||||
| } | } | ||||
| inline GUINT size() const | inline GUINT size() const | ||||
| { | { | ||||
| return m_size; | return m_size; | ||||
| } | } | ||||
| inline GUINT max_size() const | inline GUINT max_size() const | ||||
| { | { | ||||
| return m_allocated_size; | return m_allocated_size; | ||||
| } | } | ||||
| inline T & operator[](size_t i) | inline T& operator[](size_t i) | ||||
| { | { | ||||
| return m_data[i]; | return m_data[i]; | ||||
| } | } | ||||
| inline const T & operator[](size_t i) const | inline const T& operator[](size_t i) const | ||||
| { | { | ||||
| return m_data[i]; | return m_data[i]; | ||||
| } | } | ||||
| inline T * pointer(){ return m_data;} | inline T* pointer() { return m_data; } | ||||
| inline const T * pointer() const | inline const T* pointer() const | ||||
| { return m_data;} | { | ||||
| return m_data; | |||||
| } | |||||
| inline T * get_pointer_at(GUINT i) | inline T* get_pointer_at(GUINT i) | ||||
| { | { | ||||
| return m_data + i; | return m_data + i; | ||||
| } | } | ||||
| inline const T * get_pointer_at(GUINT i) const | inline const T* get_pointer_at(GUINT i) const | ||||
| { | { | ||||
| return m_data + i; | return m_data + i; | ||||
| } | } | ||||
| inline T & at(GUINT i) | inline T& at(GUINT i) | ||||
| { | { | ||||
| return m_data[i]; | return m_data[i]; | ||||
| } | } | ||||
| inline const T & at(GUINT i) const | inline const T& at(GUINT i) const | ||||
| { | { | ||||
| return m_data[i]; | return m_data[i]; | ||||
| } | } | ||||
| inline T & front() | inline T& front() | ||||
| { | { | ||||
| return *m_data; | return *m_data; | ||||
| } | } | ||||
| inline const T & front() const | inline const T& front() const | ||||
| { | { | ||||
| return *m_data; | return *m_data; | ||||
| } | } | ||||
| inline T & back() | inline T& back() | ||||
| { | { | ||||
| return m_data[m_size-1]; | return m_data[m_size - 1]; | ||||
| } | } | ||||
| inline const T & back() const | inline const T& back() const | ||||
| { | { | ||||
| return m_data[m_size-1]; | return m_data[m_size - 1]; | ||||
| } | } | ||||
| inline void swap(GUINT i, GUINT j) | inline void swap(GUINT i, GUINT j) | ||||
| { | { | ||||
| gim_swap_elements(m_data,i,j); | gim_swap_elements(m_data, i, j); | ||||
| } | } | ||||
| inline void push_back(const T & obj) | inline void push_back(const T& obj) | ||||
| { | { | ||||
| this->growingCheck(); | this->growingCheck(); | ||||
| m_data[m_size] = obj; | m_data[m_size] = obj; | ||||
| m_size++; | m_size++; | ||||
| } | } | ||||
| //!Simply increase the m_size, doesn't call the new element constructor | //!Simply increase the m_size, doesn't call the new element constructor | ||||
| inline void push_back_mem() | inline void push_back_mem() | ||||
| { | { | ||||
| this->growingCheck(); | this->growingCheck(); | ||||
| m_size++; | m_size++; | ||||
| } | } | ||||
| inline void push_back_memcpy(const T & obj) | inline void push_back_memcpy(const T& obj) | ||||
| { | { | ||||
| this->growingCheck(); | this->growingCheck(); | ||||
| irr_simd_memcpy(&m_data[m_size],&obj,sizeof(T)); | gim_simd_memcpy(&m_data[m_size], &obj, sizeof(T)); | ||||
| m_size++; | m_size++; | ||||
| } | } | ||||
| inline void pop_back() | inline void pop_back() | ||||
| { | { | ||||
| m_size--; | m_size--; | ||||
| m_data[m_size].~T(); | m_data[m_size].~T(); | ||||
| } | } | ||||
| //!Simply decrease the m_size, doesn't call the deleted element destructor | //!Simply decrease the m_size, doesn't call the deleted element destructor | ||||
| inline void pop_back_mem() | inline void pop_back_mem() | ||||
| { | { | ||||
| m_size--; | m_size--; | ||||
| } | } | ||||
| //! fast erase | //! fast erase | ||||
| inline void erase(GUINT index) | inline void erase(GUINT index) | ||||
| { | { | ||||
| if(index<m_size-1) | if (index < m_size - 1) | ||||
| { | { | ||||
| swap(index,m_size-1); | swap(index, m_size - 1); | ||||
| } | } | ||||
| pop_back(); | pop_back(); | ||||
| } | } | ||||
| inline void erase_sorted_mem(GUINT index) | inline void erase_sorted_mem(GUINT index) | ||||
| { | { | ||||
| m_size--; | m_size--; | ||||
| for(GUINT i = index;i<m_size;i++) | for (GUINT i = index; i < m_size; i++) | ||||
| { | { | ||||
| gim_simd_memcpy(m_data+i,m_data+i+1,sizeof(T)); | gim_simd_memcpy(m_data + i, m_data + i + 1, sizeof(T)); | ||||
| } | } | ||||
| } | } | ||||
| inline void erase_sorted(GUINT index) | inline void erase_sorted(GUINT index) | ||||
| { | { | ||||
| m_data[index].~T(); | m_data[index].~T(); | ||||
| erase_sorted_mem(index); | erase_sorted_mem(index); | ||||
| } | } | ||||
| inline void insert_mem(GUINT index) | inline void insert_mem(GUINT index) | ||||
| { | { | ||||
| this->growingCheck(); | this->growingCheck(); | ||||
| for(GUINT i = m_size;i>index;i--) | for (GUINT i = m_size; i > index; i--) | ||||
| { | { | ||||
| gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T)); | gim_simd_memcpy(m_data + i, m_data + i - 1, sizeof(T)); | ||||
| } | } | ||||
| m_size++; | m_size++; | ||||
| } | } | ||||
| inline void insert(const T & obj,GUINT index) | inline void insert(const T& obj, GUINT index) | ||||
| { | { | ||||
| insert_mem(index); | insert_mem(index); | ||||
| m_data[index] = obj; | m_data[index] = obj; | ||||
| } | } | ||||
| inline void resize(GUINT size, bool call_constructor = true, const T& fillData=T()) | inline void resize(GUINT size, bool call_constructor = true, const T& fillData = T()) | ||||
| { | { | ||||
| if(size>m_size) | if (size > m_size) | ||||
| { | { | ||||
| reserve(size); | reserve(size); | ||||
| if(call_constructor) | if (call_constructor) | ||||
| { | { | ||||
| while(m_size<size) | while (m_size < size) | ||||
| { | { | ||||
| m_data[m_size] = fillData; | m_data[m_size] = fillData; | ||||
| m_size++; | m_size++; | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| m_size = size; | m_size = size; | ||||
| } | } | ||||
| } | } | ||||
| else if(size<m_size) | else if (size < m_size) | ||||
| { | { | ||||
| if(call_constructor) clear_range(size); | if (call_constructor) clear_range(size); | ||||
| m_size = size; | m_size = size; | ||||
| } | } | ||||
| } | } | ||||
| inline void refit() | inline void refit() | ||||
| { | { | ||||
| resizeData(m_size); | resizeData(m_size); | ||||
| } | } | ||||
| }; | }; | ||||
| #endif // GIM_CONTAINERS_H_INCLUDED | #endif // GIM_CONTAINERS_H_INCLUDED | ||||