📄 charray.h
字号:
#ifndef CH_ARRAY_H
#define CH_ARRAY_H
// Ch 表示此类为ChenZhibiao编写
#define ARRAY_GROWTH_THRESHOLD 0x10000
template <class T> class ChArray
{
public:
ChArray(int initPhysicalLength = 0, int initGrowLength = 8);
ChArray(const ChArray<T>&);
~ChArray();
// Copy operator.
//
ChArray<T>& operator = (const ChArray<T>&);
bool operator == (const ChArray<T>&);
// Indexing into the array.
//
T& operator [] (int);
const T operator [] (int) const;
// More access to array-elements.
//
T at (int index) const;
ChArray<T>& setAt (int index, const T& value);
ChArray<T>& setAll (const T& value);
T& first ();
const T first () const;
T& last ();
const T last () const;
// Adding array-elements.
//
int append (const T& value);
ChArray<T>& append (const ChArray<T>& array);
ChArray<T>& insertAt (int index, const T& value);
// Removing array-elements.
//
ChArray<T>& removeAt (int index);
bool remove (const T& value, int start = 0);
ChArray<T>& removeFirst ();
ChArray<T>& removeLast ();
ChArray<T>& removeSubArray (int startIndex, int endIndex);
// Query about array-elements.
//
bool contains (const T& value, int start = 0) const;
bool find (const T& value, int& foundAt,
int start = 0) const;
// Array length.
//
int length () const; // Logical length.
bool isEmpty () const;
int logicalLength() const;
ChArray<T>& setLogicalLength(int);
int physicalLength() const;
ChArray<T>& setPhysicalLength(int);
// Automatic resizing.
//
int growLength () const;
ChArray<T>& setGrowLength(int);
// Utility.
//
ChArray<T>& reverse ();
ChArray<T>& swap (int i1, int i2);
// Treat as simple array of T.
//
const T* asArrayPtr () const;
T* asArrayPtr ();
protected:
T* mpArray;
int mPhysicalLen;// Actual buffer length.
int mLogicalLen;// Number of items in the array.
int mGrowLen; // Buffer grows by this value.
bool isValid (int) const;
};
template <class T> inline bool
ChArray<T>::contains(const T& value, int start) const
{ int dummy; return find(value, dummy, start); }
template <class T> inline int
ChArray<T>::length() const
{ return mLogicalLen; }
template <class T> inline bool
ChArray<T>::isEmpty() const
{ return mLogicalLen == 0; }
template <class T> inline int
ChArray<T>::logicalLength() const
{ return mLogicalLen; }
template <class T> inline int
ChArray<T>::physicalLength() const
{ return mPhysicalLen; }
template <class T> inline int
ChArray<T>::growLength() const
{ return mGrowLen; }
template <class T> inline const T*
ChArray<T>::asArrayPtr() const
{ return mpArray; }
template <class T> inline T*
ChArray<T>::asArrayPtr()
{ return mpArray; }
template <class T> inline bool
ChArray<T>::isValid(int i) const
{ return i >= 0 && i < mLogicalLen; }
template <class T> inline T&
ChArray<T>::operator [] (int i)
{ assert(isValid(i)); return mpArray[i]; }
template <class T> inline const T
ChArray<T>::operator [] (int i) const
{ assert(isValid(i)); return mpArray[i]; }
template <class T> inline T
ChArray<T>::at(int i) const
{ assert(isValid(i)); return mpArray[i]; }
template <class T> inline ChArray<T>&
ChArray<T>::setAt(int i, const T& value)
{ assert(isValid(i)); mpArray[i] = value; return *this; }
template <class T> inline T&
ChArray<T>::first()
{ assert(!isEmpty()); return mpArray[0]; }
template <class T> inline const T
ChArray<T>::first() const
{ assert(!isEmpty()); return mpArray[0]; }
template <class T> inline T&
ChArray<T>::last()
{ assert(!isEmpty()); return mpArray[mLogicalLen-1]; }
template <class T> inline const T
ChArray<T>::last() const
{ assert(!isEmpty()); return mpArray[mLogicalLen-1]; }
template <class T> inline int
ChArray<T>::append(const T& value)
{ insertAt(mLogicalLen, value); return mLogicalLen-1; }
template <class T> inline ChArray<T>&
ChArray<T>::removeFirst()
{ assert(!isEmpty()); return removeAt(0); }
template <class T> inline ChArray<T>&
ChArray<T>::removeLast()
{ assert(!isEmpty()); mLogicalLen--; return *this; }
template <class T> inline ChArray<T>&
ChArray<T>::setGrowLength(int glen)
{ assert(glen > 0); mGrowLen = glen; return *this; }
template < class T >
ChArray<T> ::ChArray(int physicalLength, int growLength)
: mpArray(NULL),
mPhysicalLen(physicalLength),
mLogicalLen(0),
mGrowLen(growLength)
{
assert(mGrowLen > 0);
assert(mPhysicalLen >= 0);
if (mPhysicalLen > 0) {
mpArray = new T[mPhysicalLen];
if (mpArray == NULL) {
mPhysicalLen = 0;
}
}
}
// This is the usual copy constructor with the caveat that,
// if the system can not allocate enough memory to satisfy the
// request then it is assumed that the entire system is in a
// dangerously low memory situation, and there is no alternative
// but to have the system gracefully abort (i.e., prompting the
// users to save files, and/or free up more memory, or what-have-you).
//
template <class T>
ChArray<T>::ChArray(const ChArray<T>& src)
: mpArray(NULL),
mPhysicalLen(src.mPhysicalLen),
mLogicalLen(src.mLogicalLen),
mGrowLen(src.mGrowLen)
{
if (mPhysicalLen > 0) {
mpArray = new T[mPhysicalLen];
if (mpArray == NULL) {
mPhysicalLen = 0;
mLogicalLen = 0;
} else {
for (int i=0; i<mLogicalLen; i++) {
mpArray[i] = src.mpArray[i];
}
}
}
}
template <class T>
ChArray<T>::~ChArray()
{
if (mpArray != NULL)
delete[] mpArray;
}
// The assignment operator. The assignment operator copies
// the data from the source array to this array. If the
// source array contains more elements that this array has
// space to store, then this array is grown to meet the demand.
// Otherwise, the physical length of this array does not change.
// After this operation is completed the logical lengths of the
// two arrays will be equal. The grow length of this array is
// not affected by this operation.
//
template <class T> ChArray<T>&
ChArray<T>::operator = (const ChArray<T>& src)
{
if (this != &src) {
if (mPhysicalLen < src.mLogicalLen) {
if (mpArray != NULL)
delete[] mpArray;
mPhysicalLen = src.mLogicalLen;
// mPhysicalLen will never be zero...
mpArray = new T[mPhysicalLen];
if (mpArray == NULL) { // ...so this only happens if failure.
mPhysicalLen = 0;
mLogicalLen = 0;
return *this;
}
}
mLogicalLen = src.mLogicalLen;
for (register int i=0; i<mLogicalLen; i++) {
mpArray[i] = src.mpArray[i];
}
}
return *this;
}
// The equal to operator. The equal to operator compares
// the data in two arrays. If the logical length of the
// two arrays are the same and the corresponding entries of
// the two arrays are equal, true is returned. Otherwise,
// false is returned.
//
template <class T> bool
ChArray<T>::operator == (const ChArray<T>& cpr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -