/
redgpu
/
bullet
Обзор
Документация
Войти
/
redgpu
/
bullet
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
examples/Experiments/ImplicitCloth/stan/array.h
307 строк
6 KB
erwincoumans
Code-style consistency improvement:
24 сен 2018, 00:17
24 сен 2018, 00:17
ab8f169
Код
Авторство
О чём код?
// // Typical template dynamic array container class. // By S Melax 1998 // // anyone is free to use, inspect, learn from, or ignore // the code here as they see fit. // // A very simple template array class. // Its easiest to understand this array // class by seeing how it is used in code. // // For example: // for(i=0;i<myarray.count;i++) // myarray[i] = somefunction(i); // // When the array runs out of room, it // reallocates memory and doubles the size of its // storage buffer. The reason for *doubleing* the amount of // memory is so the order of any algorithm using this class // is the same as it would be had you used a regular C array. // The penalty for reallocating and copying // For example consider adding n elements to a list. // Lets sum the number of times elements are "copied". // The worst case occurs when n=2^k+1 where k is integer. // In this case we do a big reallocation when we add the last element. // n elements are copied once, n/2 elements are copied twice, // n/4 elements are copied 3 times, and so on ... // total == n* (1+1/2 + 1/4 + 1/8 + ...) == n * 2 // So we do n*2 copies. Therefore adding n // elements to an Array is still O(n). // The memory usage is also of the same order as if a C array was used. // An Array uses less than double the minimum needed space. Again, we // see that we are within a small constant multiple. // // Why no "realloc" to avoid the copy when reallocating memory? // You have a choice to either use malloc/free and friends // or to use new/delete. Its bad mojo to mix these. new/delete was // chosen to be C++ish and have the array elements constructors/destructors // invoked as expected. // // #ifndef SM_ARRAY_H #define SM_ARRAY_H #include <assert.h> #include <stdio.h> template <class Type> class Array { public: Array(int s = 0); Array(Array<Type> &array); ~Array(); void allocate(int s); void SetSize(int s); void Pack(); Type &Add(Type); void AddUnique(Type); int Contains(Type); void Insert(Type, int); int IndexOf(Type); void Remove(Type); void DelIndex(int i); Type &DelIndexWithLast(int i); Type *element; int count; int array_size; const Type &operator[](int i) const { assert(i >= 0 && i < count); return element[i]; } Type &operator[](int i) { assert(i >= 0 && i < count); return element[i]; } Type &Pop() { assert(count); count--; return element[count]; } Array<Type> ©(const Array<Type> &array); Array<Type> &operator=(Array<Type> &array); }; template <class Type> Array<Type>::Array(int s) { if (s == -1) return; count = 0; array_size = 0; element = NULL; if (s) { allocate(s); } } template <class Type> Array<Type>::Array(Array<Type> &array) { count = 0; array_size = 0; element = NULL; *this = array; } template <class Type> Array<Type> &Array<Type>::copy(const Array<Type> &array) { assert(array.array_size >= 0); count = 0; for (int i = 0; i < array.count; i++) { Add(array[i]); } return *this; } template <class Type> Array<Type> &Array<Type>::operator=(Array<Type> &array) { if (array.array_size < 0) // negative number means steal the data buffer instead of copying { delete[] element; element = array.element; array_size = -array.array_size; count = array.count; array.count = array.array_size = 0; array.element = NULL; return *this; } count = 0; for (int i = 0; i < array.count; i++) { Add(array[i]); } return *this; } template <class Type> Array<Type>::~Array() { if (element != NULL && array_size != 0) { delete[] element; } count = 0; array_size = 0; element = NULL; } template <class Type> void Array<Type>::allocate(int s) { assert(s > 0); assert(s >= count); if (s == array_size) return; Type *old = element; array_size = s; element = new Type[array_size]; assert(element); for (int i = 0; i < count; i++) { element[i] = old[i]; } if (old) delete[] old; } template <class Type> void Array<Type>::SetSize(int s) { if (s == 0) { if (element) { delete[] element; element = NULL; } array_size = s; } else { allocate(s); } count = s; } template <class Type> void Array<Type>::Pack() { allocate(count); } template <class Type> Type &Array<Type>::Add(Type t) { assert(count <= array_size); if (count == array_size) { allocate((array_size) ? array_size * 2 : 16); } //int i; //for(i=0;i<count;i++) { // dissallow duplicates // assert(element[i] != t); //} element[count++] = t; return element[count - 1]; } template <class Type> int Array<Type>::Contains(Type t) { int i; int found = 0; for (i = 0; i < count; i++) { if (element[i] == t) found++; } return found; } template <class Type> void Array<Type>::AddUnique(Type t) { if (!Contains(t)) Add(t); } template <class Type> void Array<Type>::DelIndex(int i) { assert(i < count); count--; while (i < count) { element[i] = element[i + 1]; i++; } } template <class Type> Type &Array<Type>::DelIndexWithLast(int i) { assert(i < count); count--; if (i < count) { Type r = element[i]; element[i] = element[count]; element[count] = r; } return element[count]; } template <class Type> void Array<Type>::Remove(Type t) { int i; for (i = 0; i < count; i++) { if (element[i] == t) { break; } } assert(i < count); // assert object t is in the array. DelIndex(i); for (i = 0; i < count; i++) { assert(element[i] != t); } } template <class Type> void Array<Type>::Insert(Type t, int k) { int i = count; Add(t); // to allocate space while (i > k) { element[i] = element[i - 1]; i--; } assert(i == k); element[k] = t; } template <class Type> int Array<Type>::IndexOf(Type t) { int i; for (i = 0; i < count; i++) { if (element[i] == t) { return i; } } assert(0); return -1; } #endif