source: src/Patterns/ObservedIterator.hpp@ 8774c5

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 8774c5 was 8774c5, checked in by Tillmann Crueger <crueger@…>, 14 years ago

Added operator-> for Observed Iterators

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 * ObservedIterator.hpp
3 *
4 * Created on: Mar 4, 2010
5 * Author: crueger
6 */
7
8#ifndef OBSERVEDITERATOR_HPP_
9#define OBSERVEDITERATOR_HPP_
10
11#include "Patterns/Observer.hpp"
12
13#include <iterator>
14
15// we build an iterator that observes traversion of some kind of Data structure conforming to STL
16template<class _Set>
17class ObservedIterator
18 : public std::iterator<typename std::iterator_traits<typename _Set::iterator>::iterator_category,
19 typename std::iterator_traits<typename _Set::iterator>::value_type,
20 typename std::iterator_traits<typename _Set::iterator>::difference_type,
21 typename std::iterator_traits<typename _Set::iterator>::pointer,
22 typename std::iterator_traits<typename _Set::iterator>::reference>
23{
24public:
25 // Some typedefs to conform to STL-Iterator structure
26 typedef typename _Set::iterator _Iter;
27 typedef typename _Iter::value_type value_type;
28 typedef typename _Iter::difference_type difference_type;
29 typedef typename _Iter::pointer pointer;
30 typedef typename _Iter::reference reference;
31 typedef typename _Iter::iterator_category iterator_category;
32
33 ObservedIterator() :
34 protector(0)
35 {}
36
37 ObservedIterator(_Iter iter,Observable *obs) :
38 iter(iter),
39 collection(obs),
40 protector(0)
41 {}
42
43 ObservedIterator(const ObservedIterator &dest) :
44 iter(dest.iter),
45 collection(dest.collection),
46 protector(dest.copyLock())
47 {}
48
49 ~ObservedIterator(){
50 if(protector)
51 delete protector;
52 }
53
54 // standard Iterator methods
55 ObservedIterator& operator=(const ObservedIterator& dest){
56 if(&dest !=this){
57 // get the new lock first, in case the two locks point to the same observable
58 Observable::_Observable_protector *newLock = dest.copyLock();
59 if(protector)
60 delete protector;
61 protector = newLock;
62 // After the new lock is aquired we can safely set the iterator
63 iter = dest.iter;
64 // we need to know the collection, in case we still have to set the lock
65 collection = dest.collection;
66 }
67 return *this;
68 }
69
70 ObservedIterator& operator++() // prefix
71 {
72 ++iter;
73 return *this;
74 }
75
76 ObservedIterator operator++(int) // postfix with the dummy int parameter
77 {
78 ObservedIterator ret(*this);
79 ++(*this);
80 return ret;
81 }
82
83 ObservedIterator& operator--() // prefix
84 {
85 --iter;
86 return *this;
87 }
88
89 ObservedIterator operator--(int) // postfix with the dummy int parameter
90 {
91 ObservedIterator ret(*this);
92 --(*this);
93 return ret;
94 }
95
96 bool operator==(const ObservedIterator &rhs){
97 return iter==rhs.iter;
98 }
99
100 bool operator!=(const ObservedIterator &rhs){
101 return iter!=rhs.iter;
102 }
103
104 value_type operator*(){
105 // access is requested... time to get the lock
106 acquireLock();
107 return (*iter);
108 }
109
110 value_type *operator->(){
111 acquireLock();
112 return &(*iter);
113 }
114
115 // when we turn into a const iterator we can loose our lock
116 operator typename _Set::const_iterator() {
117 // typecast will be handled by the typecast method of the original iterator
118 return iter;
119 }
120
121private:
122
123 /**
124 * gets the lock for the collection when needed
125 *
126 * The lock is only acquired when the first change is done, so we can be free to do
127 * anything with the iterator before that. I.e. step forward, turn into a const_iterator
128 * etc.
129 */
130 void acquireLock(){
131 if(!protector)
132 protector = new Observable::_Observable_protector(collection);
133 }
134
135 Observable::_Observable_protector *copyLock() const{
136 // we only copy if we actually carry a lock
137 if(protector){
138 return new Observable::_Observable_protector(*protector);
139 }
140 else{
141 return 0;
142 }
143 }
144
145 _Iter iter;
146 Observable *collection;
147 Observable::_Observable_protector *protector;
148};
149
150#endif /* OBSERVEDITERATOR_HPP_ */
Note: See TracBrowser for help on using the repository browser.