199 lines
4.1 KiB
C
199 lines
4.1 KiB
C
|
/**
|
||
|
** 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
|