@@ -128,6 +128,9 @@ using NetInfoList = std::vector<std::reference_wrapper<const NetInfoEntry>>;
128128
129129class NetInfoInterface
130130{
131+ public:
132+ static std::shared_ptr<NetInfoInterface> MakeNetInfo ();
133+
131134public:
132135 virtual ~NetInfoInterface () = default ;
133136
@@ -140,6 +143,12 @@ class NetInfoInterface
140143 virtual std::string ToString () const = 0;
141144
142145 virtual void Clear () = 0;
146+
147+ bool operator ==(const NetInfoInterface& rhs) const { return typeid (*this ) == typeid (rhs) && this ->IsEqual (rhs); }
148+ bool operator !=(const NetInfoInterface& rhs) const { return !(*this == rhs); }
149+
150+ private:
151+ virtual bool IsEqual (const NetInfoInterface& rhs) const = 0;
143152};
144153
145154class MnNetInfo final : public NetInfoInterface
@@ -157,9 +166,6 @@ class MnNetInfo final : public NetInfoInterface
157166
158167 ~MnNetInfo () = default ;
159168
160- bool operator ==(const MnNetInfo& rhs) const { return m_addr == rhs.m_addr ; }
161- bool operator !=(const MnNetInfo& rhs) const { return !(*this == rhs); }
162-
163169 template <typename Stream>
164170 void Serialize (Stream& s) const
165171 {
@@ -187,16 +193,55 @@ class MnNetInfo final : public NetInfoInterface
187193 NetInfoList GetEntries () const override ;
188194
189195 const CService& GetPrimary () const override ;
190- bool IsEmpty () const override { return * this == MnNetInfo (); }
196+ bool IsEmpty () const override { return m_addr. IsEmpty (); }
191197 NetInfoStatus Validate () const override ;
192198 std::string ToString () const override ;
193199
194200 void Clear () override { m_addr.Clear (); }
201+
202+ private:
203+ // operator== and operator!= are defined by the parent which then leverage the child's IsEqual() override
204+ // IsEqual() should only be called by NetInfoInterface::operator== otherwise static_cast assumption could fail
205+ bool IsEqual (const NetInfoInterface& rhs) const override
206+ {
207+ ASSERT_IF_DEBUG (typeid (*this ) == typeid (rhs));
208+ const auto & rhs_obj{static_cast <const MnNetInfo&>(rhs)};
209+ return m_addr == rhs_obj.m_addr ;
210+ }
195211};
196212
197- inline std::shared_ptr<MnNetInfo> MakeNetInfo ()
213+ class NetInfoSerWrapper
198214{
199- return std::make_shared<MnNetInfo>();
200- }
215+ private:
216+ std::shared_ptr<NetInfoInterface>& m_data;
217+
218+ public:
219+ NetInfoSerWrapper () = delete ;
220+ NetInfoSerWrapper (const NetInfoSerWrapper&) = delete ;
221+ NetInfoSerWrapper (std::shared_ptr<NetInfoInterface>& data) :
222+ m_data{data}
223+ {
224+ }
225+
226+ ~NetInfoSerWrapper () = default ;
227+
228+ template <typename Stream>
229+ void Serialize (Stream& s) const
230+ {
231+ if (const auto ptr{std::dynamic_pointer_cast<MnNetInfo>(m_data)}) {
232+ s << *ptr;
233+ } else {
234+ // NetInfoInterface::MakeNetInfo() supplied an unexpected implementation or we didn't call it and
235+ // are left with a nullptr. Neither should happen.
236+ assert (false );
237+ }
238+ }
239+
240+ template <typename Stream>
241+ void Unserialize (Stream& s)
242+ {
243+ m_data = std::make_shared<MnNetInfo>(deserialize, s);
244+ }
245+ };
201246
202247#endif // BITCOIN_EVO_NETINFO_H
0 commit comments