/////////////////////////////////////////////////////////////////////////////// // g++ -fhandle-exceptions Stack.C -o Stack /////////////////////////////////////////////////////////////////////////////// //================================< Array.h >================================= // WARNING: Requires exceptions (use g++ -fhandle-exceptions) #ifndef Array_First #define Array_First template class Array { enum { log2BucketSize = 4, // LOG (BASE 2) OF HOW MANY ELEMENTS PER BUCKET bucketSize = 1<; public: explicit Size(int s) : myElemCount(s) {} private: int myElemCount; }; // THIS CLASS IMPLEMENTS AN EXCEPTION ON BOUNDS ERROR struct BoundsError { BoundsError(int i, int m) : index(i) , max(m) {} int index; int max; }; private: int myBucketCount; // NUMBER OF BUCKETS ALLOCATED int myNextFree; // INDEX OF NEXT FREE ELEMENT ElementType** myElement; // POINTER TO VECTOR OF BUCKETS // 1. CONVERT AN INDEX INTO A BUCKET NUMBER AND INDEX WITHIN THAT BUCKET // RETURN A REFERENCE TO THE CORRESPONDING ELEMENT ElementType& access(int index) const { return myElement[index>>divBucketSize][index&modBucketSize]; } // 2. REALLOCATE THE REQUIRED NUMBER OF BUCKETS // IF THE REQUIRED NUMBER IS 0, ALLOCATE ENOUGH SPACE // FOR AT LEAST ONE EXTRA ELEMENT void reallocate(int reqBucketCount = 0) { if (reqBucketCount>0 && reqBucketCount>myBucketCount) { // ALLOCATE A VECTOR OF THE REQUIRED NUMBER OF BUCKETS ElementType** newelement = new ElementType* [reqBucketCount]; int i; // MOVE EACH EXISTING BUCKET TO NEW BUCKET VECTOR for (i=0;i & array) : myBucketCount(0) , myNextFree(array.myNextFree) , myElement(0) { // ALLOCATE AS MANY BUCKETS AS REQUIRED TO STORE THE // NUMBER OF ELEMENTS IN THE EXISTING ARRAY array reallocate(array.myNextFree+modBucketSize >> divBucketSize); // COPY EACH ELEMENT ACROSS for (int i=0; i::Size initsize) : myBucketCount(0) , myNextFree(0) , myElement(0) { // CONVERT ELEMENT COUNT TO BUCKET COUNT reallocate(initsize.myElemCount+modBucketSize >> divBucketSize); } Array(Size initsize, const ElementType& initval) : myBucketCount(0) , myNextFree(initsize.myElemCount) , myElement(0) { // CONVERT ELEMENT COUNT TO BUCKET COUNT reallocate(initsize.myElemCount+modBucketSize >> divBucketSize); // INITIALIZE EACH REQUESTED BUCKET for (int i=0;i> divBucketSize); // COPY EACH ELEMENT for (int i=0; i=0 && i=0 && i> divBucketSize); access(myNextFree) = elem; myNextFree++; return *this; } Array& Append(const Array& array) { // ENSURE ENOUGH SPACE FOR THE EXTRA ELEMENTS reallocate(myNextFree+array.myNextFree+modBucketSize>>divBucketSize); // COPY EACH EXTRA ELEMENT TO THE NEXT EMPTY SLOT for (int i=0; i=0) { myNextFree -= n; } return *this; } // 11. CHECK FOR AN ELEMENT VALUE IN THE ARRAY // RETURNS: 0 ON FAILURE OR // (index+1) WHERE index IS THE INDEX OF THE FIRST // ELEMENT WITH A MATCHING VALUE int Contains(const ElementType& elem) const { for (int i=0;i================================= // #include "Array.h" template class Stack : private Array { public: /*using*/ Array::Count; // "using" not yet supported void Push(const ElementType& elem) { Append(elem); } const ElementType& Top(void) { return operator[]( Count()-1 ); } ElementType Pop(void) { ElementType top = Top(); RemoveLast(); return top; } }; //==============================< StackTest.C >=============================== #include int main(void) { Stack stack; stack.Push(1); cout << stack.Count() << endl; stack.Push(2); cout << stack.Count() << endl; stack.Push(3); cout << stack.Count() << endl; stack.Push(4); cout << stack.Count() << endl; cout << stack.Top() << endl; cout << stack.Pop() << endl; cout << stack.Pop() << endl; cout << stack.Pop() << endl; cout << stack.Pop() << endl; }