Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/stackclass.hpp

    r6ac7ee rcc2ee5  
    1010 */
    1111template <typename T> class StackClass {
    12         public:
    13         StackClass<T>(int dimension);
    14         ~StackClass<T>();
    15 
    16         bool Push(T object);
    17         T PopFirst();
    18         T PopLast();
    19         bool RemoveItem(T ptr);
    20         void ClearStack();
    21         bool IsEmpty();
    22         bool IsFull();
    23         int ItemCount();
    24         void Output(ofstream *out) const;
    25         void TestImplementation(ofstream *out, T test);
    26 
    27         private:
    28                 T *StackList;    //!< the list containing the atom pointers
    29                 int EntryCount;          //!< number of entries in the stack
    30                 int CurrentLastEntry;    //!< Current last entry (newest item on stack)
    31                 int CurrentFirstEntry;  //!< Current first entry (oldest item on stack)
    32                 int NextFreeField;                      //!< Current index of next free field
     12  public:
     13  StackClass<T>(int dimension);
     14  ~StackClass<T>();
     15 
     16  bool Push(T object);
     17  T PopFirst();
     18  T PopLast();
     19  bool RemoveItem(T ptr);
     20  void ClearStack();
     21  bool IsEmpty();
     22  bool IsFull();
     23  int ItemCount();
     24  void Output(ofstream *out) const;
     25  void TestImplementation(ofstream *out, T test);
     26 
     27  private:
     28    T *StackList;  //!< the list containing the atom pointers
     29    int EntryCount;    //!< number of entries in the stack
     30    int CurrentLastEntry;  //!< Current last entry (newest item on stack)
     31    int CurrentFirstEntry;  //!< Current first entry (oldest item on stack)
     32    int NextFreeField;      //!< Current index of next free field
    3333};
    3434
     
    3737template <typename T> StackClass<T>::StackClass(int dimension)
    3838{
    39         CurrentLastEntry = 0;
    40         CurrentFirstEntry = 0;
    41         NextFreeField = 0;
    42         EntryCount = dimension;
    43         StackList = (T *) Malloc(sizeof(T)*EntryCount, "StackClass::StackClass: **StackList");
     39  CurrentLastEntry = 0;
     40  CurrentFirstEntry = 0;
     41  NextFreeField = 0;
     42  EntryCount = dimension;
     43  StackList = (T *) Malloc(sizeof(T)*EntryCount, "StackClass::StackClass: **StackList");
    4444};
    4545
     
    4848template <typename T> StackClass<T>::~StackClass()
    4949{
    50         Free((void **)&StackList, "StackClass::StackClass: **StackList");
     50  Free((void **)&StackList, "StackClass::StackClass: **StackList");
    5151};
    5252
     
    5757template <typename T> bool StackClass<T>::Push(T object)
    5858{
    59         if (!IsFull()) {                // check whether free field is really not occupied
    60                 StackList[NextFreeField] = object;
    61                 CurrentLastEntry = NextFreeField;
    62                 NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
    63                 return true;
    64         } else {
    65                 cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
    66                 return false;
    67         }
     59  if (!IsFull()) {    // check whether free field is really not occupied
     60    StackList[NextFreeField] = object;
     61    CurrentLastEntry = NextFreeField;
     62    NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
     63    return true;
     64  } else {
     65    cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
     66    return false;
     67  }
    6868};
    6969
     
    7474template <typename T> T StackClass<T>::PopFirst()
    7575{
    76         T Walker = NULL;
    77         if (!IsEmpty()) {
    78                 Walker = StackList[CurrentFirstEntry];
    79                 if (Walker == NULL)
    80                         cerr << "ERROR: Stack's field is empty!" << endl;
    81                 StackList[CurrentFirstEntry] = NULL;
    82                 if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
    83                         CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
    84                 } else {
    85                         CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
    86                         CurrentLastEntry = CurrentFirstEntry;
    87                 }
    88         } else
    89                 cerr << "ERROR: Stack is empty!" << endl;
    90         return Walker;
     76  T Walker = NULL;
     77  if (!IsEmpty()) {
     78    Walker = StackList[CurrentFirstEntry];
     79    if (Walker == NULL)
     80      cerr << "ERROR: Stack's field is empty!" << endl;
     81    StackList[CurrentFirstEntry] = NULL;
     82    if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
     83      CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
     84    } else {
     85      CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
     86      CurrentLastEntry = CurrentFirstEntry;
     87    }
     88  } else
     89    cerr << "ERROR: Stack is empty!" << endl;
     90  return Walker;
    9191};
    9292
     
    9797template <typename T> T StackClass<T>::PopLast()
    9898{
    99         T Walker = NULL;
    100         if (!IsEmpty()) {
    101                 Walker = StackList[CurrentLastEntry];
    102                 StackList[CurrentLastEntry] = NULL;
    103                 if (Walker == NULL)
    104                         cerr << "ERROR: Stack's field is empty!" << endl;
    105                 NextFreeField = CurrentLastEntry;
    106                 if (CurrentLastEntry != CurrentFirstEntry)      // has there been more than one item on stack
    107                         CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
    108         } else {
    109                 cerr << "ERROR: Stack is empty!" << endl;
    110         }
    111         return Walker;
     99  T Walker = NULL;
     100  if (!IsEmpty()) {
     101    Walker = StackList[CurrentLastEntry];
     102    StackList[CurrentLastEntry] = NULL;
     103    if (Walker == NULL)
     104      cerr << "ERROR: Stack's field is empty!" << endl;
     105    NextFreeField = CurrentLastEntry;
     106    if (CurrentLastEntry != CurrentFirstEntry)  // has there been more than one item on stack
     107      CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
     108  } else {
     109    cerr << "ERROR: Stack is empty!" << endl;
     110  }
     111  return Walker;
    112112};
    113113
     
    120120template <typename T> bool StackClass<T>::RemoveItem(T ptr)
    121121{
    122         bool found = false;
    123         cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
    124         int i=CurrentFirstEntry;
    125         if (!IsEmpty())
    126                 do {
    127                         if (StackList[i] == ptr) {      // if item found, remove
    128                                 cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
    129                                 found = true;
    130                                 StackList[i] = NULL;
    131                         }
    132                         if ((found) && (StackList[i] != NULL)) {        // means we have to shift (and not the removed item)
    133                                 if (i == 0) { // we are down to first item in stack, have to put onto last item
    134                                         cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
    135                                         StackList[EntryCount-1] = StackList[0];
    136                                 } else {
    137                                         cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
    138                                         StackList[i-1] = StackList[i];
    139                                 }
    140                         }
    141                         i=((i + 1) % EntryCount); // step on
    142                 } while (i!=NextFreeField);
    143         else
    144                 cerr << "ERROR: Stack is already empty!" << endl;
    145         if (found) {
    146                 NextFreeField = CurrentLastEntry;
    147                 if (CurrentLastEntry != CurrentFirstEntry)      // has there been more than one item on stack
    148                         CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
    149         }
    150         return found;
     122  bool found = false;
     123  cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
     124  int i=CurrentFirstEntry;
     125  if (!IsEmpty())
     126    do {
     127      if (StackList[i] == ptr) {  // if item found, remove
     128        cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
     129        found = true;
     130        StackList[i] = NULL;
     131      }
     132      if ((found) && (StackList[i] != NULL)) {  // means we have to shift (and not the removed item)
     133        if (i == 0) { // we are down to first item in stack, have to put onto last item
     134          cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
     135          StackList[EntryCount-1] = StackList[0];
     136        } else {
     137          cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
     138          StackList[i-1] = StackList[i];
     139        }
     140      }
     141      i=((i + 1) % EntryCount); // step on
     142    } while (i!=NextFreeField);
     143  else
     144    cerr << "ERROR: Stack is already empty!" << endl;
     145  if (found) {
     146    NextFreeField = CurrentLastEntry;
     147    if (CurrentLastEntry != CurrentFirstEntry)  // has there been more than one item on stack
     148      CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
     149  }
     150  return found;
    151151};
    152152
    153153/** Test the functionality of the stack.
    154154 * \param *out ofstream for debugging
    155  * \param *test one item to put on stack
     155 * \param *test one item to put on stack 
    156156 * \return true - all tests worked correctly
    157157 */
    158158template <typename T> void StackClass<T>::TestImplementation(ofstream *out, T test)
    159159{
    160         T Walker = test;
    161         *out << Verbose(1) << "Testing the snake stack..." << endl;
    162         for (int i=0;i<EntryCount;i++) {
    163                 *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
    164                 Push(Walker);
    165                 Walker=Walker->next;
    166         }
    167         *out << endl;
    168         Output(out);
    169         if (IsFull())
    170                 *out << "Stack is full as supposed to be!" << endl;
    171         else
    172                 *out << "ERROR: Stack is not as full as supposed to be!" << endl;
    173         //if (StackList[(EntryCount+1)/2] != NULL) {
    174                 *out << "Removing element in the middle ..." << endl;
    175                 RemoveItem(StackList[(EntryCount+1)/2]);
    176                 Output(out);
    177         //}
    178         //if (StackList[CurrentFirstEntry] != NULL) {
    179                 *out << "Removing first element ..." << endl;
    180                 RemoveItem(StackList[CurrentFirstEntry]);
    181                 Output(out);
    182         //}
    183         //if (StackList[CurrentLastEntry] != NULL) {
    184                 *out << "Removing last element ..." << endl;
    185                 RemoveItem(StackList[CurrentLastEntry]);
    186                 Output(out);
    187         //}
    188         *out << "Clearing stack ... " << endl;
    189         ClearStack();
    190         Output(out);
    191         if (IsEmpty())
    192                 *out << "Stack is empty as supposed to be!" << endl;
    193         else
    194                 *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
    195         *out << "done." << endl;
     160  T Walker = test;
     161  *out << Verbose(1) << "Testing the snake stack..." << endl;
     162  for (int i=0;i<EntryCount;i++) {
     163    *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
     164    Push(Walker);
     165    Walker=Walker->next;
     166  }
     167  *out << endl;
     168  Output(out);
     169  if (IsFull())
     170    *out << "Stack is full as supposed to be!" << endl;
     171  else
     172    *out << "ERROR: Stack is not as full as supposed to be!" << endl;
     173  //if (StackList[(EntryCount+1)/2] != NULL) {
     174    *out << "Removing element in the middle ..." << endl;
     175    RemoveItem(StackList[(EntryCount+1)/2]);
     176    Output(out);
     177  //}
     178  //if (StackList[CurrentFirstEntry] != NULL) {
     179    *out << "Removing first element  ..." << endl;
     180    RemoveItem(StackList[CurrentFirstEntry]);
     181    Output(out);
     182  //}
     183  //if (StackList[CurrentLastEntry] != NULL) {
     184    *out << "Removing last element ..." << endl;
     185    RemoveItem(StackList[CurrentLastEntry]);
     186    Output(out);
     187  //}
     188  *out << "Clearing stack ... " << endl; 
     189  ClearStack();
     190  Output(out);
     191  if (IsEmpty())
     192    *out << "Stack is empty as supposed to be!" << endl;
     193  else
     194    *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
     195  *out << "done." << endl;
    196196};
    197197
     
    201201template <typename T> void StackClass<T>::Output(ofstream *out) const
    202202{
    203         *out << "Contents of Stack: ";
    204         for(int i=0;i<EntryCount;i++) {
    205                 *out << "\t";
    206                 if (i == CurrentFirstEntry)
    207                         *out << " 1";
    208                 if      (i == CurrentLastEntry)
    209                         *out << " "<< EntryCount;
    210                 if (i ==        NextFreeField)
    211                         *out << " F";
    212                 *out << ": " << StackList[i];
    213         }
    214         *out << endl;
     203  *out << "Contents of Stack: ";
     204  for(int i=0;i<EntryCount;i++) {
     205    *out << "\t";
     206    if (i == CurrentFirstEntry)
     207      *out << " 1";
     208    if  (i == CurrentLastEntry)
     209      *out << " "<< EntryCount;
     210    if (i ==  NextFreeField)
     211      *out << " F";
     212    *out << ": " << StackList[i];
     213  }
     214  *out << endl;
    215215};
    216216
     
    222222template <typename T> bool StackClass<T>::IsEmpty()
    223223{
    224         return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
     224  return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
    225225};
    226226
     
    232232template <typename T> bool StackClass<T>::IsFull()
    233233{
    234         return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
     234  return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
    235235};
    236236
     
    242242template <typename T> int StackClass<T>::ItemCount()
    243243{
    244         //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
    245         return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
     244  //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
     245  return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
    246246};
    247247
     
    251251template <typename T> void StackClass<T>::ClearStack()
    252252{
    253         for(int i=EntryCount; i--;)
    254                 StackList[i] = NULL;
    255         CurrentFirstEntry = 0;
    256         CurrentLastEntry = 0;
    257         NextFreeField = 0;
     253  for(int i=EntryCount; i--;)
     254    StackList[i] = NULL;
     255  CurrentFirstEntry = 0;
     256  CurrentLastEntry = 0;
     257  NextFreeField = 0;
    258258};
    259259
Note: See TracChangeset for help on using the changeset viewer.