📄 vectorgeneric.h
字号:
// Do not include this file directly
#ifndef VECTOR_TRAMPOLINE
#error "vectorgeneric.h cannot be included directly"
#endif
#ifdef _DEBUG
#include <assert.h>
#endif
#include "gamesys.h"
#include "log.h"
#include <malloc.h>
#include <new>
#ifndef ALIGN
#define _aligned_free free
#define _aligned_malloc(x,y) malloc(x)
#define _aligned_realloc(x,y,z) realloc(x,y)
#else
#define CVector CAlignedVec
#endif
#define VECTOR_GRANULARITY 8 // elements
#define VECTOR_GRAN_BASE (VECTOR_GRANULARITY-1)
// used for Save / Load
#include <stdio.h>
template <class T>
class CVector {
public:
CVector();
CVector(CVector& v);
CVector(int n);
~CVector();
T& operator[](int i);
CVector&
operator=(CVector& v);
void Resize(int new_size);
void Reserve(int new_size);
void Remove(int i); // Swaps i with last. Possibly unsafe sometimes
int Append(CVector& vec);
int Append(T& element); // Only Append and TailAlloc increment num
int AppendNoBCheck(T& element);
int TailAlloc(int n);
T& TailAlloc();
T* Find(T* element);
void Clear();
//void ClearData();
int GetNum();
void SetNum(int n);
T& Tail();
int GetSize();
void Swap(CVector& l);
T* GetData(); // Fast access
T& GetElemNoBCheck(int i);
bool Save(FILE *fp);
void Load(FILE *fp, int num);
private:
T *data;
int num; // No. elements appended
int size; // No. elements allocated
};
template <class T>
inline bool CVector<T>::Save(FILE *fp) {
if(fwrite(data, sizeof(T), num, fp) != num) {
return 1;
}
return 0;
};
template <class T>
inline void CVector<T>::Load(FILE *fp, int n) {
Clear();
Reserve(n);
num = (int)fread(data, sizeof(T), n, fp);
};
template <class T>
CVector<T>::CVector(CVector<T>& v) {
data = (T*)_aligned_malloc(v.num*sizeof(T), 16);
if(data) {
num = v.num;
size = num;
for(int i=0; i<num; i++) {
new( data + i ) T(v[i]);
}
} else {
num = 0;
size = 0;
}
}
template <class T>
inline CVector<T>::CVector(int n): data(0), num(0) {
Reserve(n);
};
template <class T>
inline CVector<T>::CVector(): data(0), num(0), size(0) {};
template <class T>
inline CVector<T>::~CVector() {
Clear();
}
template <class T>
inline void CVector<T>::Clear() {
while(num)
data[--num].~T();
_aligned_free(data);
data = 0;
num = 0;
size = 0;
}
template <class T>
inline int CVector<T>::GetSize() {
return size;
}
template <class T>
inline int CVector<T>::GetNum() {
return num;
}
template <class T>
inline void CVector<T>::SetNum(int n) {
if(n > size)
Resize(n);
num = n;
}
template <class T>
inline T& CVector<T>::Tail() {
return *(data + num - 1);
}
template <class T>
T& CVector<T>::operator[](int i) {
#if 0
if(i >= size)
Resize(i+1);
#endif
return data[i];
}
template <class T>
T& CVector<T>::GetElemNoBCheck(int i){
return data[i];
}
template <class T>
inline void CVector<T>::Reserve(int new_size) {
void *p = _aligned_malloc(new_size*sizeof(T), 16);
#ifdef _DEBUG
assert(p);
#endif
if(p) {
size = new_size;
#ifdef NO_BUG_IN_PLACEMENT_NEW // data and p are sometimes different
data = new(p) T[size];
#else
for(int i=0; i<size; i++)
new( (T*)p + i ) T;
data = (T*)p;
#endif
}
else
size = 0;
}
template <class T>
inline void CVector<T>::Resize(int new_size) {
#if 0
new_size <<= 1;
#endif
if(new_size & VECTOR_GRAN_BASE)
new_size = ((new_size / VECTOR_GRANULARITY) + 1)*VECTOR_GRANULARITY ;
T *p = (T*)_aligned_realloc(data, new_size*sizeof(T), 16);
#ifdef _DEBUG
assert(p);
#endif
//if(p) {
#if 0
new(p+size) T[new_size - size]; // Might also be affected by the pl. new bug
#else
for (int i=size; i<new_size; i++)
new( (T*)p + i ) T; // Call constructors
data = p;
size = new_size;
#endif
//}
}
template <class T>
inline void CVector<T>::Swap(CVector& l) {
T* my_data = data;
int my_num = num;
int my_size = size;
data = l.data;
num = l.num;
size = l.size;
l.data = my_data;
l.num = my_num;
l.size = my_size;
}
template <class T>
inline CVector<T>& CVector<T>::operator=(CVector<T>& v) {
while(num)
data[--num].~T();
_aligned_free(data);
data = (T*)_aligned_malloc(v.num*sizeof(T), 16);
// data = (T*)_aligned_realloc(data, v.num*sizeof(T), 16);
if(data) {
num = v.num;
size = num;
for(int i=0; i<num; i++) {
new( data + i ) T(v[i]);
//data[i] = v[i];
}
}
return *this;
}
template <class T>
inline T* CVector<T>::GetData() {
return data;
}
template <class T>
inline int CVector<T>::Append(T& element) {
int r = num;
if(num >= size)
Resize(num + 1);
data[num] = element;
num++;
return r;
}
template <class T>
inline int CVector<T>::Append(CVector<T> &vec) {
int r = num + 1;
int new_num = num + vec.num;
if(new_num > size)
Resize(new_num);
for(int i=0; i<vec.num; i++) {
data[num++] = vec.data[i];
}
return r;
}
template <class T>
inline int CVector<T>::AppendNoBCheck(T& element) {
int r = num;
data[num] = element;
num++;
return r;
}
template <class T>
inline int CVector<T>::TailAlloc(int n) {
int r = num;
num += n;
if(num > size)
Resize(num);
return r;
}
template <class T>
inline T& CVector<T>::TailAlloc() {
int r = num;
num ++;
if(num > size)
Resize(num);
return data[r];
}
template <class T>
inline T* CVector<T>::Find(T* element) {
for(int i=0; i<num; i++)
if(data[i] == element)
return data + i;
}
template <class T>
void CVector<T>::Remove(int i) {
num--;
data[i] = data[num];
}
#ifndef ALIGN
#undef _aligned_free
#undef _aligned_malloc
#undef _aligned_realloc
#else
#undef CVector
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -