Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

198 lines
4.1 KiB

/**
** File : array.h
** Description: Array template declaration
**/
#ifndef Array_h
#define Array_h
#define ForIndex(i,n) for(int i=0; i<(n); ++i)
#define EndFor
// for PArray<T>, like Array<T>, T must have a public operator=()
template<class T, int psize>
class PArray {
private:
int size; // must come before a
T* a;
int n;
T pa[psize];
private:
void resize(int nsize);
void resize_aux(int ne);
public:
inline PArray(int ne=0)
{
if (ne <= psize)
{
size = psize;
a = pa;
}
else
{
size = ne;
a = new T[ne];
}
n=ne;
}
PArray<T,psize>& operator=(const PArray<T,psize>& ar);
PArray(const PArray<T,psize>& ar);
inline ~PArray() { if (size!=psize) delete[] a; }
inline int num() const { return n; }
inline void clearcompletely()
{
if (size != psize)
{
delete[] a;
size = psize;
a = pa;
}
n=0;
}
/*
* allocate ne, CLEAR if too small
*/
inline void init(int ne)
{
if (ne > size)
{
if (size!=psize) delete[] a;
size=ne;
a=new T[ne];
}
n=ne;
}
/*
* allocate at least e+1, COPY if too small
*/
inline void access(int e)
{
int ne=e+1;
if (ne>size) resize_aux(ne);
if (ne>n) n=ne;
}
/*
* allocate ne, COPY if too small
*/
inline void need(int ne)
{
if (ne>size) resize_aux(ne);
n=ne;
}
/*
* ret: previous num()
*/
inline int add(int ne)
{
int cn=n; need(n+ne); return cn;
}
inline void sub(int ne)
{
n-=ne;
}
/*
* do not use a+=a[..]!!
* add() may allocate a[]!!
*/
inline PArray<T,psize>& operator+=(const T& e)
{
int i=add(1);
a[i]=e;
return *this;
}
inline void squeeze() { if (n<size) resize(n); }
inline operator const T*() const { return a; }
inline operator T*() { return a; }
inline const T& operator[](int i) const { ok(i); return a[i]; }
inline T& operator[](int i) { ok(i); return a[i]; }
inline const T& last() const { return operator[](n-1); }
inline T& last() { return operator[](n-1); }
#if 0
inline void reverse()
{
for(int i=0; i<n/2; ++i)
{
swap(&a[i],&a[n-1-i]);
}
}
#endif
#ifdef __TIGHTER_ASSERTS
inline void ok(int i) const { assertx(i>=0 && i<n); }
#else
inline void ok(int) const { }
#endif
int contains(const T& e) const;
int index(const T& e) const;
};
// was 'const T&', but with 'Cut*', expanded to 'const Cut*&' (bad)
#define ForPArray(A,T,V) ForIndex(zzz,(A).num()) T const& V=(A)[zzz];
template<class T, int psize>
PArray<T,psize>& PArray<T,psize>::operator=(const PArray<T,psize>& ar)
{
if (&ar==this) return *this;
init(ar.num());
ForIndex(i,n) { a[i]=ar[i]; } EndFor;
return *this;
}
template<class T, int psize>
PARRAY_INLINE
PArray<T,psize>::PArray(const PArray<T,psize>& ar) : size(psize), a(pa), n(0)
{
*this=ar;
}
template<class T, int psize>
void PArray<T,psize>::resize(int nsize)
{
T* na;
if (nsize<=psize) {
if (size==psize) return;
na=pa;
} else {
na=new T[nsize];
}
ForIndex(i,n) { na[i]=a[i]; } EndFor;
if (size!=psize) delete[] a;
a=na;
size=nsize<=psize?psize:nsize;
}
template<class T, int psize>
void PArray<T,psize>::resize_aux(int ne)
{
resize(max(int(n*1.5f)+3,ne));
}
template<class T, int psize>
PARRAY_INLINE
int PArray<T,psize>::contains(const T& e) const
{
ForIndex(i,n) { if (a[i]==e) return 1; } EndFor;
return 0;
}
template<class T, int psize>
PARRAY_INLINE
int PArray<T,psize>::index(const T& e) const
{
ForIndex(i,n) { if (a[i]==e) return i; } EndFor;
assertnever(""); return 0;
}
#endif //Array_h