source: src/CodePatterns/Observer/ObservedIterator.hpp@ c1e104

Last change on this file since c1e104 was 9b8fa4, checked in by Frederik Heber <heber@…>, 14 years ago

Huge update of file structure to place installation header files into right folder.

  • The problem ist that we desire use as include "CodePatterns/...". For this to work, especially with the new Observer subfolder structure, it has been necessary to place all header files away from their source files into a distinct folder called CodePatterns. This emulates the later, after make install present structure.
  • essentially all source and header files had to be changed to adapt the include.
  • all Makefile.am's had to be changed.
  • nobase_ ... was removed such that header files are installed flat and not creating their subfolder along the process.
  • We placed Observer into its own convenience library and own folder Observer away from Patterns.

Some other changes:

  • FIX: MemDebug.hpp inclusion has been removed in all stubs.
  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[a80f419]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
[70672e3]11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
[9b8fa4]16#include "CodePatterns/Observer/Observer.hpp"
[a80f419]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
[178da0]101 bool operator==(const ObservedIterator &rhs) const
102 {
[a80f419]103 return iter==rhs.iter;
104 }
105
[178da0]106 bool operator!=(const ObservedIterator &rhs) const
107 {
[a80f419]108 return iter!=rhs.iter;
109 }
110
[4fb16c]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 {
[a80f419]119 // access is requested... time to get the lock
120 acquireLock();
121 return (*iter);
122 }
123
[4fb16c]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 {
[a80f419]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 */
[4fb16c]151 void acquireLock() const {
[a80f419]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;
[4fb16c]168 mutable Observable::_Observable_protector *protector;
[a80f419]169};
170
171#endif /* OBSERVEDITERATOR_HPP_ */
Note: See TracBrowser for help on using the repository browser.