source: src/CodePatterns/Observer/ObservedIterator.hpp@ 084729c

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 084729c was 084729c, checked in by Frederik Heber <heber@…>, 8 years ago

Squashed 'ThirdParty/CodePatterns/' content from commit c1e1041

git-subtree-dir: ThirdParty/CodePatterns
git-subtree-split: c1e10418c454f98be2f43d93167642b0008428fc

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