15 inline observer_token_data::observer_token_data(
base_subject* pSubject,
void* pObserver) noexcept
16 : m_pSubject(pSubject)
17 , m_pObserver(pObserver)
23 if (m_pSubject && m_pObserver)
24 m_pSubject->
detach(m_pObserver);
27 m_pObserver =
nullptr;
32 std::swap(m_pSubject, other.m_pSubject);
33 std::swap(m_pObserver, other.m_pObserver);
38 std::swap(m_pSubject, other.m_pSubject);
39 std::swap(m_pObserver, other.m_pObserver);
43 inline observer_token_data::~observer_token_data() noexcept
48 inline bool observer_token_data::operator==(
const observer_token_data& other)
const noexcept
50 return m_pSubject == other.m_pSubject && m_pObserver == other.m_pObserver;
53 inline observer_token_data::operator bool() const noexcept
55 return m_pSubject && m_pObserver;
62 template<
class observer_t>
63 template<
class base_iterator_t>
65 const base_iterator_t& other,
67 : base_iterator_t(other)
68 , m_pSubject(pSubject)
73 template<
class observer_t>
74 template<
class base_iterator_t>
75 inline subject<observer_t>::base_iterator<base_iterator_t>::base_iterator(
const base_iterator& other) noexcept
76 : base_iterator_t(other)
77 , m_pSubject(other.m_pSubject)
82 template<
class observer_t>
83 template<
class base_iterator_t>
84 inline subject<observer_t>::base_iterator<base_iterator_t>::~base_iterator() noexcept
86 m_pSubject->on_iterator_destructed();
89 template<
class observer_t>
90 template<
class base_iterator_t>
91 inline typename subject<observer_t>::template base_iterator<base_iterator_t>& subject<observer_t>::base_iterator<
92 base_iterator_t>::operator=(
const base_iterator& other) noexcept
94 *
this = std::move(base_iterator(other));
98 template<
class observer_t>
99 template<
class base_iterator_t>
100 inline observer_t* subject<observer_t>::base_iterator<base_iterator_t>::operator->(
void) noexcept
102 return static_cast<observer_t*
>(*base_iterator_t::operator->());
105 template<
class observer_t>
106 template<
class base_iterator_t>
107 inline observer_t& subject<observer_t>::base_iterator<base_iterator_t>::operator*(
void) noexcept
109 return static_cast<observer_t&
>(*base_iterator_t::operator*());
112 template<
class observer_t>
113 template<
class base_iterator_t>
114 inline void subject<observer_t>::base_iterator<base_iterator_t>::init() noexcept
116 m_pSubject->on_iterator_constructed();
123 template<
class observer_t>
124 template<
class base_iterator_t>
125 inline subject<observer_t>::const_base_iterator<base_iterator_t>::const_base_iterator(
126 const base_iterator_t& other) noexcept
127 : base_iterator_t(other)
131 template<
class observer_t>
132 template<
class base_iterator_t>
133 const observer_t* subject<observer_t>::const_base_iterator<base_iterator_t>::operator->() const noexcept
135 return static_cast<const observer_t*
>(*base_iterator_t::operator->());
138 template<
class observer_t>
139 template<
class base_iterator_t>
140 const observer_t& subject<observer_t>::const_base_iterator<base_iterator_t>::operator*() const noexcept
142 return static_cast<const observer_t&
>(*base_iterator_t::operator*());
149 template<
class observer_t>
150 inline subject<observer_t>::~subject()
153 const auto tokens = m_Tokens;
154 for (
const auto pToken : tokens)
158 template<
class observer_t>
161 if (std::find(m_Observers.begin(), m_Observers.end(), pObserver) == m_Observers.end())
163 m_Observers.push_back(pObserver);
164 auto token = std::make_unique<observer_token_data>(
this, pObserver);
165 m_Tokens.push_back(token.get());
170 return observer_token();
174 template<
class observer_t>
177 for (
auto pObserver : m_Observers)
178 notifyFunc(pObserver);
181 template<
class observer_t>
184 return iterator(m_Observers.begin(),
this);
187 template<
class observer_t>
193 template<
class observer_t>
196 return const_iterator(m_Observers.cbegin());
199 template<
class observer_t>
202 return iterator(m_Observers.end(),
this);
205 template<
class observer_t>
211 template<
class observer_t>
214 return const_iterator(m_Observers.cend());
217 template<
class observer_t>
220 return reverse_iterator(m_Observers.rbegin(),
this);
223 template<
class observer_t>
229 template<
class observer_t>
232 return const_reverse_iterator(m_Observers.crbegin());
235 template<
class observer_t>
238 return reverse_iterator(m_Observers.rend(),
this);
241 template<
class observer_t>
247 template<
class observer_t>
250 return const_reverse_iterator(m_Observers.crend());
253 template<
class observer_t>
256 return m_Observers.size();
259 template<
class observer_t>
262 if (m_nIterators == 0)
268 return pToken->m_pObserver == pObserver;
271 m_Observers.erase(std::remove(m_Observers.begin(), m_Observers.end(), pObserver), m_Observers.end());
278 [pObserver](
const observer_token_data* pToken)
280 return pToken && pToken->m_pObserver == pObserver;
282 static_cast<observer_token_data*
>(
nullptr));
287 static_cast<observer_t*
>(pObserver),
288 static_cast<observer_t*
>(
nullptr));
292 template<
class observer_t>
293 inline void subject<observer_t>::on_iterator_destructed() noexcept
296 if (m_nIterators == 0)
298 m_Tokens.erase(std::remove(m_Tokens.begin(), m_Tokens.end(),
nullptr), m_Tokens.end());
300 m_Observers.erase(std::remove(m_Observers.begin(), m_Observers.end(),
nullptr), m_Observers.end());
304 template<
class observer_t>
305 inline void subject<observer_t>::on_iterator_constructed() noexcept
virtual void detach(void *pObserver) noexcept=0
Detach observer from subject.
Const random access iterator type.
Const reverse random access iterator type.
Tokens are used to automatically detach observer when the observer object is destroyed.
void reset() noexcept
Reset observer_token.
Class maintains a list of its dependents, called observers, and notifies them automatically of any st...
const_iterator cbegin() const
Return const iterator to beginning.
iterator begin()
Return iterator to beginning.
const_iterator cend() const
Return const iterator to end.
observer_token attach(observer_t *pObserver) noexcept
Attach observer to this subject.
iterator end()
Return iterator to end.
reverse_iterator rbegin()
Return reverse iterator to reverse beginning.
size_t get_num_observers() const noexcept
Get number of observers attached to this subject.
void notify(const notify_func ¬ifyFunc) const noexcept
Notify all observers.
const_reverse_iterator crend() const
Return const reverse iterator to reverse end.
reverse_iterator rend()
Return reverse iterator to reverse end.
const_reverse_iterator crbegin() const
Return const reverse iterator to reverse beginning.