@@ -29,6 +29,7 @@ namespace tmcppc::data_structures {
2929 explicit notification (notification_type t)
3030 : id_{ id++ }
3131 , type_{ t }
32+ , index_of_changed_element_{ 0 }
3233 {}
3334 notification (notification_type t, size_t i)
3435 : id_{ id++ }
@@ -42,9 +43,9 @@ namespace tmcppc::data_structures {
4243 private:
4344 static inline size_t id{};
4445
45- size_t id_{} ;
46- notification_type type_{} ;
47- size_t index_of_changed_element_{} ;
46+ size_t id_;
47+ notification_type type_;
48+ size_t index_of_changed_element_;
4849 };
4950
5051
@@ -60,7 +61,7 @@ namespace tmcppc::data_structures {
6061
6162 using group_t = std::string;
6263 using id_t = size_t ;
63- std::map<group_t , id_t > cache_{} ;
64+ std::map<group_t , id_t > cache_;
6465 };
6566
6667
@@ -78,14 +79,18 @@ namespace tmcppc::data_structures {
7879 explicit observer (std::ostream& os, std::shared_ptr<observable_vector<T>> sp_ov) noexcept
7980 : id_{ id_generator_ (" observer" ) }
8081 , os_{ os }
81- , sp_ov_{ sp_ov }
82+ , sp_ov_{ std::move ( sp_ov) }
8283 {}
84+ constexpr observer (const observer& other) = default;
85+ constexpr observer (observer&& other) = default;
86+ constexpr observer& operator =(const observer& other) = default ;
87+ constexpr observer& operator =(observer&& other) = default ;
8388 private:
8489 static inline group_id_generator& id_generator_{ group_id_generator::get_instance () };
8590
86- size_t id_{} ;
91+ size_t id_;
8792 std::ostream& os_;
88- std::shared_ptr<observable_vector<T>> sp_ov_{} ;
93+ std::shared_ptr<observable_vector<T>> sp_ov_;
8994 };
9095
9196
@@ -96,7 +101,12 @@ namespace tmcppc::data_structures {
96101 class concrete_observer_1 : public observer <T> {
97102 public:
98103 explicit concrete_observer_1 (std::ostream& os, std::shared_ptr<observable_vector<T>> sp_ov) noexcept
99- : observer<T>::observer{ os, sp_ov } {}
104+ : observer<T>::observer{ os, std::move (sp_ov) } {}
105+ constexpr concrete_observer_1 (const concrete_observer_1& other) = default;
106+ constexpr concrete_observer_1 (concrete_observer_1&& other) = default;
107+ constexpr concrete_observer_1& operator =(const concrete_observer_1& other) = default ;
108+ constexpr concrete_observer_1& operator =(concrete_observer_1&& other) = default ;
109+ ~concrete_observer_1 () = default ;
100110 protected:
101111 void update (const notification& n) noexcept override {
102112 auto id{ observer<T>::get_id () };
@@ -112,7 +122,12 @@ namespace tmcppc::data_structures {
112122 class concrete_observer_2 : public observer <T> {
113123 public:
114124 explicit concrete_observer_2 (std::ostream& os, std::shared_ptr<observable_vector<T>> sp_ov) noexcept
115- : observer<T>::observer{ os, sp_ov } {}
125+ : observer<T>::observer{ os, std::move (sp_ov) } {}
126+ constexpr concrete_observer_2 (const concrete_observer_2& other) = default;
127+ constexpr concrete_observer_2 (concrete_observer_2&& other) = default;
128+ constexpr concrete_observer_2& operator =(const concrete_observer_2& other) = default ;
129+ constexpr concrete_observer_2& operator =(concrete_observer_2&& other) = default ;
130+ ~concrete_observer_2 () = default ;
116131 protected:
117132 void update (const notification& n) noexcept override {
118133 auto id{ observer<T>::get_id () };
@@ -131,11 +146,14 @@ namespace tmcppc::data_structures {
131146
132147 [[nodiscard]] size_t get_id () const noexcept { return id_; }
133148
134- void attach (const std::shared_ptr<observer<T>> observer ) noexcept {
135- observers_.insert (std::end (observers_), observer );
149+ void attach (const std::shared_ptr<observer<T>>& observer_sp ) noexcept {
150+ observers_.insert (std::end (observers_), observer_sp );
136151 }
137- void detach (const std::shared_ptr<observer<T>> observer) noexcept {
138- observers_.remove_if ([&observer](auto sp) { return sp->get_id () == observer->get_id (); });
152+ void detach (const std::shared_ptr<observer<T>>& observer_sp) noexcept {
153+ observers_.remove_if ([&observer_sp](const auto & wp) {
154+ auto sp{ wp.lock () };
155+ return sp and sp->get_id () == observer_sp->get_id ();
156+ });
139157 }
140158
141159 protected:
@@ -157,14 +175,19 @@ namespace tmcppc::data_structures {
157175 [[nodiscard]] bool is_observed () const noexcept { return not observers_.empty (); }
158176
159177 void notify (const notification& n) const {
160- std::ranges::for_each (observers_, [&n](auto sp) { sp->update (n); });
178+ std::ranges::for_each (observers_, [&n](const auto & wp) {
179+ auto sp{ wp.lock () };
180+ if (sp) {
181+ sp->update (n);
182+ }
183+ });
161184 }
162185
163186 private:
164187 static inline group_id_generator& id_generator_{ group_id_generator::get_instance () };
165188
166- size_t id_{} ;
167- std::list<std::shared_ptr <observer<T>>> observers_{} ;
189+ size_t id_;
190+ std::list<std::weak_ptr <observer<T>>> observers_;
168191 };
169192
170193
@@ -187,7 +210,7 @@ namespace tmcppc::data_structures {
187210 constexpr observable_vector (InputIt first, InputIt last)
188211 : v_(first, last) {}
189212 constexpr observable_vector (std::initializer_list<T> init)
190- : v_( init) {}
213+ : v_{ init } {}
191214
192215 constexpr observable_vector (const observable_vector& other)
193216 : subject<T>{ other }
0 commit comments