source: src/stackclass.hpp@ 89c8b2

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 89c8b2 was cd4ccc, checked in by Frederik Heber <heber@…>, 15 years ago

definitions for class element and verbose moved to their own header files and reducing contents of helpers.hpp

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