retdec
subject.h
Go to the documentation of this file.
1 
7 #ifndef RETDEC_LLVMIR2HLL_SUPPORT_SUBJECT_H
8 #define RETDEC_LLVMIR2HLL_SUPPORT_SUBJECT_H
9 
10 #include <algorithm>
11 #include <vector>
12 
14 
15 namespace retdec {
16 namespace llvmir2hll {
17 
42 template<typename SubjectType, typename ArgType = SubjectType>
43 class Subject {
44 public:
47 
49  // We have to use a weak pointer instead of a shared one because of
50  // possible circular references.
52 
53 public:
58 
62  virtual ~Subject() = default;
63 
84  virtual ShPtr<SubjectType> getSelf() = 0;
85 
91  void addObserver(ObserverPtr observer) {
92  observers.push_back(observer);
93  }
94 
100  void removeObserver(ObserverPtr observer) {
102  }
103 
108  observers.clear();
109  }
110 
125  void notifyObservers(ShPtr<ArgType> arg = nullptr) {
126  // We have to iterate over a copy of the container because it can be
127  // modified during the iteration (either by us or in an update() call).
128  for (const auto &observer : ObserverContainer(observers)) {
130  }
131  }
132 
133 protected:
135  // Note that the used container has to preserve the order in which
136  // observers are added to it.
137  using ObserverContainer = std::vector<ObserverPtr>;
138 
139  // Observer iterator.
140  using observer_iterator = typename ObserverContainer::const_iterator;
141 
142 protected:
147  return observers.begin();
148  }
149 
154  return observers.end();
155  }
156 
157 private:
158 
164  ShPtr<ArgType> arg) {
165  if (observerExists(observer)) {
166  notifyObserver(observer, arg);
167  } else {
168  removeObserver(observer);
169  }
170  }
171 
175  bool observerExists(ObserverPtr observer) {
176  return !observer.expired();
177  }
178 
183  if (ShPtr<ConcreteObserver> existingObserver = observer.lock()) {
184  existingObserver->update(getSelf(), arg);
185  }
186  }
187 
192  observers.erase(std::remove_if(observers.begin(), observers.end(),
193  [&observer](const auto &other) {
194  return other.expired() || observer.lock() == other.lock();
195  }
196  ));
197  }
198 
199 private:
202 };
203 
204 } // namespace llvmir2hll
205 } // namespace retdec
206 
207 #endif
Implementation of a generic typed observer using shared pointers (observer part).
Definition: observer.h:41
Implementation of a generic typed observer using shared pointers (subject part).
Definition: subject.h:43
bool observerExists(ObserverPtr observer)
Checks if the given observer still exists.
Definition: subject.h:175
void removeObservers()
Removes all observers.
Definition: subject.h:107
virtual ~Subject()=default
Destructs the subject.
void addObserver(ObserverPtr observer)
Adds a new observer to the list of observers.
Definition: subject.h:91
observer_iterator observer_begin() const
Returns a constant iterator to the first observer.
Definition: subject.h:146
WkPtr< ConcreteObserver > ObserverPtr
A pointer to an observer.
Definition: subject.h:51
void notifyObservers(ShPtr< ArgType > arg=nullptr)
Notifies all observers by calling Observer::update() on them.
Definition: subject.h:125
typename ObserverContainer::const_iterator observer_iterator
Definition: subject.h:140
observer_iterator observer_end() const
Returns a constant iterator past the last observer.
Definition: subject.h:153
virtual ShPtr< SubjectType > getSelf()=0
Returns a shared pointer of self.
Subject()
Creates a new subject.
Definition: subject.h:57
void notifyObserverOrRemoveItIfNotExists(ObserverPtr observer, ShPtr< ArgType > arg)
Notifies the given observer (if it exists) or removes it (if it does not exist).
Definition: subject.h:163
std::vector< ObserverPtr > ObserverContainer
A container to store observers.
Definition: subject.h:137
void removeObserverAndNonExistingObservers(ObserverPtr observer)
Removes the given observer and all the non-existing observers.
Definition: subject.h:191
void notifyObserver(ObserverPtr observer, ShPtr< ArgType > arg)
Notifies the given observer, provided it still exists.
Definition: subject.h:182
ObserverContainer observers
Container to store observers.
Definition: subject.h:201
void removeObserver(ObserverPtr observer)
Removes the selected observer from the list of observers.
Definition: subject.h:100
A library providing API for working with back-end IR.
std::weak_ptr< T > WkPtr
An alias for a weak pointer.
Definition: smart_ptr.h:22
std::shared_ptr< T > ShPtr
An alias for a shared pointer.
Definition: smart_ptr.h:18
Definition: archive_wrapper.h:19
Declarations, aliases, macros, etc. for the use of smart pointers.