source: src/stackclass.hpp@ cee0b57

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since cee0b57 was 29812d, checked in by Saskia Metzler <metzler@…>, 16 years ago

Ticket 11: use templates and/or traits to fix Malloc/ReAlloc-Free warnings in a clean manner

  • Property mode set to 100755
File size: 9.0 KB
Line 
1#ifndef STACKCLASS_HPP_
2#define STACKCLASS_HPP_
3
4#include "verbose.hpp"
5#include "memoryallocator.hpp"
6
7template <typename T> class StackClass;
8
9/******************************** Functions for class StackClass ********************************/
10
11/* Stack of Stuff.
12 * Is used during DepthFirstSearchAnalysis() to detect nonseparable components.
13 */
14template <typename T> class StackClass {
15 public:
16 StackClass<T>(int dimension);
17 ~StackClass<T>();
18
19 bool Push(T object);
20 T PopFirst();
21 T PopLast();
22 bool RemoveItem(T ptr);
23 void ClearStack();
24 bool IsEmpty();
25 bool IsFull();
26 int ItemCount();
27 void Output(ofstream *out) const;
28 void TestImplementation(ofstream *out, T test);
29
30 private:
31 T *StackList; //!< the list containing the atom pointers
32 int EntryCount; //!< number of entries in the stack
33 int CurrentLastEntry; //!< Current last entry (newest item on stack)
34 int CurrentFirstEntry; //!< Current first entry (oldest item on stack)
35 int NextFreeField; //!< Current index of next free field
36};
37
38/** Constructor of class StackClass.
39 */
40template <typename T> StackClass<T>::StackClass(int dimension)
41{
42 CurrentLastEntry = 0;
43 CurrentFirstEntry = 0;
44 NextFreeField = 0;
45 EntryCount = dimension;
46 StackList = Malloc<T>(EntryCount, "StackClass::StackClass: **StackList");
47};
48
49/** Destructor of class StackClass.
50 */
51template <typename T> StackClass<T>::~StackClass()
52{
53 Free(&StackList);
54};
55
56/** Pushes an object onto the stack.
57 * \param *object atom to be pushed on stack
58 * \return true - sucess, false - failure, meaning stack field was occupied
59 */
60template <typename T> bool StackClass<T>::Push(T object)
61{
62 if (!IsFull()) { // check whether free field is really not occupied
63 StackList[NextFreeField] = object;
64 CurrentLastEntry = NextFreeField;
65 NextFreeField = (NextFreeField + 1) % EntryCount; // step on to next free field
66 return true;
67 } else {
68 cerr << "ERROR: Stack is full, " << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tNextFreeField " << NextFreeField << "\tEntryCount " << EntryCount << "!" << endl;
69 return false;
70 }
71};
72
73/** Pops first/oldest atom from stack.
74 * First in, last out.
75 * \return atom pointer from stack, NULL - if failure (no atom pointer in field)
76 */
77template <typename T> T StackClass<T>::PopFirst()
78{
79 T Walker = NULL;
80 if (!IsEmpty()) {
81 Walker = StackList[CurrentFirstEntry];
82 if (Walker == NULL)
83 cerr << "ERROR: Stack's field is empty!" << endl;
84 StackList[CurrentFirstEntry] = NULL;
85 if (CurrentFirstEntry != CurrentLastEntry) { // hasn't last item been popped as well?
86 CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
87 } else {
88 CurrentFirstEntry = (CurrentFirstEntry + 1) % EntryCount; // step back from current free field to last used (somehow modulo does not work in -1)
89 CurrentLastEntry = CurrentFirstEntry;
90 }
91 } else
92 cerr << "ERROR: Stack is empty!" << endl;
93 return Walker;
94};
95
96/** Pops last element from stack.
97 * First in, first out.
98 * \return element pointer from stack, NULL - if failure (no atom pointer in field)
99 */
100template <typename T> T StackClass<T>::PopLast()
101{
102 T Walker = NULL;
103 if (!IsEmpty()) {
104 Walker = StackList[CurrentLastEntry];
105 StackList[CurrentLastEntry] = NULL;
106 if (Walker == NULL)
107 cerr << "ERROR: Stack's field is empty!" << endl;
108 NextFreeField = CurrentLastEntry;
109 if (CurrentLastEntry != CurrentFirstEntry) // has there been more than one item on stack
110 CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount; // step back from current free field to last (modulo does not work in -1, thus go EntryCount-1 instead)
111 } else {
112 cerr << "ERROR: Stack is empty!" << endl;
113 }
114 return Walker;
115};
116
117/** Removes a certain item from the stack.
118 * Item is seeked between \a CurrentFirstEntry and \a CurrentLastEntry, if found, place in stack is NULL'd and
119 * all subsequent items shifted by one position downward (with wrapping taken into account).
120 * \param *ptr adress of item
121 * \return true - item was removed, false - item was not found
122 */
123template <typename T> bool StackClass<T>::RemoveItem(T ptr)
124{
125 bool found = false;
126 cout << Verbose(5) << "First " << CurrentFirstEntry<< "\tLast " << CurrentLastEntry<< "\tNext " << NextFreeField<< "\tCount " << EntryCount<< "." << endl;
127 int i=CurrentFirstEntry;
128 if (!IsEmpty())
129 do {
130 if (StackList[i] == ptr) { // if item found, remove
131 cout << Verbose(5) << "Item " << *ptr << " was number " << i << " on stack, removing it." << endl;
132 found = true;
133 StackList[i] = NULL;
134 }
135 if ((found) && (StackList[i] != NULL)) { // means we have to shift (and not the removed item)
136 if (i == 0) { // we are down to first item in stack, have to put onto last item
137 cout << Verbose(5) << "Shifting item 0 to place " << EntryCount-1 << "." << endl;
138 StackList[EntryCount-1] = StackList[0];
139 } else {
140 cout << Verbose(5) << "Shifting item " << i << " to place " << i-1 << "." << endl;
141 StackList[i-1] = StackList[i];
142 }
143 }
144 i=((i + 1) % EntryCount); // step on
145 } while (i!=NextFreeField);
146 else
147 cerr << "ERROR: Stack is already empty!" << endl;
148 if (found) {
149 NextFreeField = CurrentLastEntry;
150 if (CurrentLastEntry != CurrentFirstEntry) // has there been more than one item on stack
151 CurrentLastEntry = (CurrentLastEntry + (EntryCount-1)) % EntryCount;
152 }
153 return found;
154};
155
156/** Test the functionality of the stack.
157 * \param *out ofstream for debugging
158 * \param *test one item to put on stack
159 * \return true - all tests worked correctly
160 */
161template <typename T> void StackClass<T>::TestImplementation(ofstream *out, T test)
162{
163 T Walker = test;
164 *out << Verbose(1) << "Testing the snake stack..." << endl;
165 for (int i=0;i<EntryCount;i++) {
166 *out << Verbose(2) << "Filling " << i << "th element of stack." << endl;
167 Push(Walker);
168 Walker=Walker->next;
169 }
170 *out << endl;
171 Output(out);
172 if (IsFull())
173 *out << "Stack is full as supposed to be!" << endl;
174 else
175 *out << "ERROR: Stack is not as full as supposed to be!" << endl;
176 //if (StackList[(EntryCount+1)/2] != NULL) {
177 *out << "Removing element in the middle ..." << endl;
178 RemoveItem(StackList[(EntryCount+1)/2]);
179 Output(out);
180 //}
181 //if (StackList[CurrentFirstEntry] != NULL) {
182 *out << "Removing first element ..." << endl;
183 RemoveItem(StackList[CurrentFirstEntry]);
184 Output(out);
185 //}
186 //if (StackList[CurrentLastEntry] != NULL) {
187 *out << "Removing last element ..." << endl;
188 RemoveItem(StackList[CurrentLastEntry]);
189 Output(out);
190 //}
191 *out << "Clearing stack ... " << endl;
192 ClearStack();
193 Output(out);
194 if (IsEmpty())
195 *out << "Stack is empty as supposed to be!" << endl;
196 else
197 *out << "ERROR: Stack is not as empty as supposed to be!" << endl;
198 *out << "done." << endl;
199};
200
201/** Puts contents of stack into ofstream \a *out.
202 * \param *out ofstream for output
203 */
204template <typename T> void StackClass<T>::Output(ofstream *out) const
205{
206 *out << "Contents of Stack: ";
207 for(int i=0;i<EntryCount;i++) {
208 *out << "\t";
209 if (i == CurrentFirstEntry)
210 *out << " 1";
211 if (i == CurrentLastEntry)
212 *out << " "<< EntryCount;
213 if (i == NextFreeField)
214 *out << " F";
215 *out << ": " << StackList[i];
216 }
217 *out << endl;
218};
219
220/** Checks whether stack is empty.
221 * Simply checks whether StackClass::NextFreeField is equal to StackClass::CurrentFirstEntry and
222 * StackClass::CurrentFirstEntry is equal to StackClass::CurrentLastEntry.
223 * \return true - empty, false - not
224 */
225template <typename T> bool StackClass<T>::IsEmpty()
226{
227 return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry == CurrentFirstEntry));
228};
229
230/** Checks whether stack is full.
231 * Simply checks whether StackClass::NextFreeField is equal to StackClass::CurrentFirstEntry and
232 * StackClass::CurrentFirstEntry is _not_ equal to StackClass::CurrentLastEntry.
233 * \return true - full, false - not
234 */
235template <typename T> bool StackClass<T>::IsFull()
236{
237 return((NextFreeField == CurrentFirstEntry) && (CurrentLastEntry != CurrentFirstEntry));
238};
239
240/** Returns number of items on stack.
241 * Simply returns difference between StackClass::Stacklist entry StackClass::CurrentEntry-1.
242 * \return number of items on stack
243 * \warning will never return correct item count if stack is full, i.e. count would be StackClass::EntryCount.
244 */
245template <typename T> int StackClass<T>::ItemCount()
246{
247 //cout << "Stack: CurrentLastEntry " << CurrentLastEntry<< "\tCurrentFirstEntry " << CurrentFirstEntry << "\tEntryCount " << EntryCount << "." << endl;
248 return((NextFreeField + (EntryCount - CurrentFirstEntry)) % EntryCount);
249};
250
251/** Clears the stack from all atoms.
252 * \return true - sucess, false - failure
253 */
254template <typename T> void StackClass<T>::ClearStack()
255{
256 for(int i=EntryCount; i--;)
257 StackList[i] = NULL;
258 CurrentFirstEntry = 0;
259 CurrentLastEntry = 0;
260 NextFreeField = 0;
261};
262
263
264
265#endif /*STACKCLASS_HPP_*/
Note: See TracBrowser for help on using the repository browser.