00001 #ifndef STACK_IMPLEMENTATION 00002 #define STACK_IMPLEMENTATION 00003 00004 /*****************************************************************************\ 00005 * * 00006 * Name : stack * 00007 * Author : Chris Koeritz * 00008 * * 00009 ******************************************************************************* 00010 * Copyright (c) 1990-$now By Author. This program is free software; you can * 00011 * redistribute it and/or modify it under the terms of the GNU General Public * 00012 * License as published by the Free Software Foundation; either version 2 of * 00013 * the License or (at your option) any later version. This is online at: * 00014 * http://www.fsf.org/copyleft/gpl.html * 00015 * Please send any updates to: fred@gruntose.com * 00016 \*****************************************************************************/ 00017 00018 #include "stack.h" 00019 00020 #include <basis/array.cpp> 00021 #include <basis/guards.h> 00022 00023 template <class contents> 00024 stack<contents>::stack(int elements) 00025 : _store(elements >= 0? elements : 0), 00026 _kind(_store.length()? BOUNDED : UNBOUNDED), 00027 _valid_fields(0) 00028 {} 00029 00030 template <class contents> 00031 stack<contents>::stack(const stack &to_copy) 00032 : _store(0), _valid_fields(0) 00033 { operator = (to_copy); } 00034 00035 template <class contents> stack<contents>::~stack() {} 00036 00037 template <class contents> 00038 int stack<contents>::size() const { return _valid_fields; } 00039 00040 template <class contents> 00041 void stack<contents>::reset() 00042 { 00043 while (pop() == common::OKAY) {} // pop off elements until all are gone. 00044 } 00045 00046 template <class contents> 00047 int stack<contents>::elements() const { return _store.length(); } 00048 00049 template <class contents> 00050 outcome stack<contents>::push(const contents &element) 00051 { 00052 if (_kind == BOUNDED) { 00053 if (_valid_fields >= elements()) return common::IS_FULL; 00054 outcome result = _store.put(_valid_fields, element); 00055 if (result != common::OKAY) return common::IS_FULL; 00056 } else _store.concatenate(element); 00057 _valid_fields++; 00058 return common::OKAY; 00059 } 00060 00061 template <class contents> 00062 outcome stack<contents>::pop() 00063 { 00064 if (_valid_fields < 1) return common::IS_EMPTY; 00065 if (_kind == UNBOUNDED) 00066 _store.zap(_store.length() - 1, _store.length() - 1); 00067 _valid_fields--; 00068 return common::OKAY; 00069 } 00070 00071 template <class contents> 00072 contents &stack<contents>::top() 00073 { return _store[_valid_fields - 1]; } 00074 00075 template <class contents> 00076 stack<contents> &stack<contents>::operator = (const stack &to_copy) 00077 { 00078 if (this == &to_copy) return *this; 00079 reset(); 00080 _kind = to_copy._kind; 00081 _store.reset(to_copy._store.length()); 00082 for (int i = 0; i < to_copy._store.length(); i++) 00083 _store.put(i, to_copy._store[i]); 00084 _valid_fields = to_copy._valid_fields; 00085 return *this; 00086 } 00087 00088 template <class contents> 00089 void stack<contents>::invert() 00090 { 00091 for (int i = 0; i < _store.length() / 2; i++) { 00092 contents hold = _store.get(i); 00093 int exchange_index = _store.length() - i - 1; 00094 _store.put(i, _store.get(exchange_index)); 00095 _store.put(exchange_index, hold); 00096 } 00097 } 00098 00099 template <class contents> 00100 contents &stack<contents>::operator [](int index) 00101 { 00102 if (index >= _valid_fields) index = -1; // force a bogus return. 00103 return _store[index]; 00104 } 00105 00106 template <class contents> 00107 outcome stack<contents>::acquire_pop(contents &to_stuff) 00108 { 00109 if (!_valid_fields) return common::IS_EMPTY; 00110 to_stuff = _store[_valid_fields - 1]; 00111 if (_kind == UNBOUNDED) _store.zap(elements()-1, elements()-1); 00112 _valid_fields--; 00113 return common::OKAY; 00114 } 00115 00116 #endif 00117
1.5.1