source: src/stackclass.hpp@ 70ff32

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 70ff32 was f66195, checked in by Frederik Heber <heber@…>, 15 years ago

forward declarations used to untangle interdependet classes.

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