📄 array.h
字号:
// this simplifies the computation.
resize(num + 1, DONT_SHRINK_UNDERLYING_ARRAY);
data[num - 1] = value;
}
}
inline void append(const T& v1, const T& v2) {
if (inArray(&v1) || inArray(&v2)) {
T t1 = v1;
T t2 = v2;
append(t1, t2);
} else if (num + 1 < numAllocated) {
// This is a simple situation; just stick it in the next free slot using
// the copy constructor.
new (data + num) T(v1);
new (data + num + 1) T(v2);
num += 2;
} else {
resize(num + 2, DONT_SHRINK_UNDERLYING_ARRAY);
data[num - 2] = v1;
data[num - 1] = v2;
}
}
inline void append(const T& v1, const T& v2, const T& v3) {
if (inArray(&v1) || inArray(&v2) || inArray(&v3)) {
T t1 = v1;
T t2 = v2;
T t3 = v3;
append(t1, t2, t3);
} else if (num + 2 < numAllocated) {
// This is a simple situation; just stick it in the next free slot using
// the copy constructor.
new (data + num) T(v1);
new (data + num + 1) T(v2);
new (data + num + 2) T(v3);
num += 3;
} else {
resize(num + 3, DONT_SHRINK_UNDERLYING_ARRAY);
data[num - 3] = v1;
data[num - 2] = v2;
data[num - 1] = v3;
}
}
inline void append(const T& v1, const T& v2, const T& v3, const T& v4) {
if (inArray(&v1) || inArray(&v2) || inArray(&v3) || inArray(&v4)) {
T t1 = v1;
T t2 = v2;
T t3 = v3;
T t4 = v4;
append(t1, t2, t3, t4);
} else if (num + 3 < numAllocated) {
// This is a simple situation; just stick it in the next free slot using
// the copy constructor.
new (data + num) T(v1);
new (data + num + 1) T(v2);
new (data + num + 2) T(v3);
new (data + num + 3) T(v4);
num += 4;
} else {
resize(num + 4, DONT_SHRINK_UNDERLYING_ARRAY);
data[num - 4] = v1;
data[num - 3] = v2;
data[num - 2] = v3;
data[num - 1] = v4;
}
}
/**
Returns true if the given element is in the array.
*/
bool contains(const T& e) const {
for (int i = 0; i < size(); ++i) {
if ((*this)[i] == e) {
return true;
}
}
return false;
}
/**
Append the elements of array. Cannot be called with this array
as an argument.
*/
void append(const Array<T>& array) {
debugAssert(this != &array);
int oldNum = num;
int arrayLength = array.length();
resize(num + arrayLength, false);
for (int i = 0; i < arrayLength; i++) {
data[oldNum + i] = array.data[i];
}
}
/**
Pushes a new element onto the end and returns its address.
This is the same as A.resize(A.size() + 1, false); A.last()
*/
inline T& next() {
resize(num + 1, false);
return last();
}
/**
Pushes an element onto the end (appends)
*/
inline void push(const T& value) {
append(value);
}
inline void push(const Array<T>& array) {
append(array);
}
/** Alias to provide std::vector compatibility */
inline void push_back(const T& v) {
push(v);
}
/** "The member function removes the last element of the controlled sequence, which must be non-empty."
For compatibility with std::vector. */
inline void pop_back() {
pop();
}
/**
"The member function returns the storage currently allocated to hold the controlled
sequence, a value at least as large as size()"
For compatibility with std::vector.
*/
int capacity() const {
return numAllocated;
}
/**
"The member function returns a reference to the first element of the controlled sequence,
which must be non-empty."
For compatibility with std::vector.
*/
T& front() {
return (*this)[0];
}
/**
"The member function returns a reference to the first element of the controlled sequence,
which must be non-empty."
For compatibility with std::vector.
*/
const T& front() const {
return (*this)[0];
}
/**
Removes the last element and returns it.
*/
inline T pop(bool shrinkUnderlyingArrayIfNecessary = false) {
debugAssert(num > 0);
T temp = data[num - 1];
resize(num - 1, shrinkUnderlyingArrayIfNecessary);
return temp;
}
/** Pops the last element and discards it. Faster than pop.*/
inline void popDiscard(bool shrinkUnderlyingArrayIfNecessary = false) {
debugAssert(num > 0);
resize(num - 1, shrinkUnderlyingArrayIfNecessary);
}
/**
"The member function swaps the controlled sequences between *this and str."
This is slower than the optimal std implementation; please post on the G3D user's forum
if you need a fast version.
For compatibility with std::vector.
*/
void swap(Array<T>& str) {
Array<T> temp = str;
str = *this;
*this = temp;
}
/**
Performs bounds checks in debug mode
*/
inline T& operator[](int n) {
debugAssert((n >= 0) && (n < num));
debugAssert(data!=NULL);
return data[n];
}
inline T& operator[](unsigned int n) {
debugAssert(((int)n < num));
return data[n];
}
/**
Performs bounds checks in debug mode
*/
inline const T& operator[](int n) const {
debugAssert((n >= 0) && (n < num));
debugAssert(data!=NULL);
return data[n];
}
inline const T& operator[](unsigned int n) const {
debugAssert((n < (unsigned int)num));
debugAssert(data!=NULL);
return data[n];
}
inline T& randomElement() {
debugAssert(num > 0);
debugAssert(data!=NULL);
return data[iRandom(0, num - 1)];
}
inline const T& randomElement() const {
debugAssert(num > 0);
debugAssert(data!=NULL);
return data[iRandom(0, num - 1)];
}
/**
Returns the last element, performing a check in
debug mode that there is at least one element.
*/
inline const T& last() const {
debugAssert(num > 0);
debugAssert(data!=NULL);
return data[num - 1];
}
inline T& last() {
debugAssert(num > 0);
debugAssert(data!=NULL);
return data[num - 1];
}
/**
Calls delete on all objects[0...size-1]
and sets the size to zero.
*/
void deleteAll() {
for (int i = 0; i < num; i++) {
delete(data[i]);
}
resize(0);
}
/**
Returns the index of (the first occurance of) an index or -1 if
not found.
*/
int findIndex(const T& value) const {
for (int i = 0; i < num; ++i) {
if (data[i] == value) {
return i;
}
}
return -1;
}
/**
Finds an element and returns the iterator to it. If the element
isn't found then returns end().
*/
Iterator find(const T& value) {
for (int i = 0; i < num; ++i) {
if (data[i] == value) {
return data + i;
}
}
return end();
}
ConstIterator find(const T& value) const {
for (int i = 0; i < num; ++i) {
if (data[i] == value) {
return data + i;
}
}
return end();
}
/**
Removes count elements from the array
referenced either by index or Iterator.
*/
void remove(Iterator element, int count = 1) {
debugAssert((element >= begin()) && (element < end()));
debugAssert((count > 0) && (element + count) <= end());
Iterator last = end() - count;
while(element < last) {
element[0] = element[count];
++element;
}
resize(num - count);
}
void remove(int index, int count = 1) {
debugAssert((index >= 0) && (index < num));
debugAssert((count > 0) && (index + count <= num));
remove(begin() + index, count);
}
/**
Reverse the elements of the array in place.
*/
void reverse() {
T temp;
int n2 = num / 2;
for (int i = 0; i < n2; ++i) {
temp = data[num - 1 - i];
data[num - 1 - i] = data[i];
data[i] = temp;
}
}
/**
Sort using a specific less-than function, e.g.:
<PRE>
bool __cdecl myLT(const MyClass& elem1, const MyClass& elem2) {
return elem1.x < elem2.x;
}
</PRE>
Note that for pointer arrays, the <CODE>const</CODE> must come
<I>after</I> the class name, e.g., <CODE>Array<MyClass*></CODE> uses:
<PRE>
bool __cdecl myLT(MyClass*const& elem1, MyClass*const& elem2) {
return elem1->x < elem2->x;
}
</PRE>
*/
void sort(bool (*lessThan)(const T& elem1, const T& elem2)) {
std::sort(data, data + num, lessThan);
}
/**
Sorts the array in increasing order using the > or < operator. To
invoke this method on Array<T>, T must override those operator.
You can overide these operators as follows:
<code>
bool T::operator>(const T& other) const {
return ...;
}
bool T::operator<(const T& other) const {
return ...;
}
</code>
*/
void sort(int direction=SORT_INCREASING) {
if (direction == SORT_INCREASING) {
std::sort(data, data + num);
} else {
std::sort(data, data + num, compareGT);
}
}
/**
Sorts elements beginIndex through and including endIndex.
*/
void sortSubArray(int beginIndex, int endIndex, int direction=SORT_INCREASING) {
if (direction == SORT_INCREASING) {
std::sort(data + beginIndex, data + endIndex + 1);
} else {
std::sort(data + beginIndex, data + endIndex + 1, compareGT);
}
}
void sortSubArray(int beginIndex, int endIndex, bool (*lessThan)(const T& elem1, const T& elem2)) {
std::sort(data + beginIndex, data + endIndex + 1, lessThan);
}
/** Redistributes the elements so that the new order is statistically independent
of the original order. O(n) time.*/
void randomize() {
T temp;
for (int i = size() - 1; i >= 0; --i) {
int x = iRandom(0, i);
temp = data[i];
data[i] = data[x];
data[x] = temp;
}
}
};
/** Array::contains for C-arrays */
template<class T> bool contains(const T* array, int len, const T& e) {
for (int i = len - 1; i >= 0; --i) {
if (array[i] == e) {
return true;
}
}
return false;
}
} // namespace
#endif
#ifdef G3D_WIN32
# pragma warning (push)
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -