From 1868dcc1048a2413ef88df7ee7c4ace4251d3c17 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 30 Mar 2024 00:58:09 +0100 Subject: [PATCH] Copy ctor, swap and move for tl::shared_collection and tl::weak_collection --- src/edt/edt/edtEditorHooks.cc | 9 ++-- src/edt/edt/edtEditorHooks.h | 27 ++++++++---- src/tl/tl/tlObjectCollection.h | 69 +++++++++++++++++++++++++----- src/tl/unit_tests/tlObjectTests.cc | 42 ++++++++++++++++++ 4 files changed, 123 insertions(+), 24 deletions(-) diff --git a/src/edt/edt/edtEditorHooks.cc b/src/edt/edt/edtEditorHooks.cc index 5641ddd20..eaca9b718 100644 --- a/src/edt/edt/edtEditorHooks.cc +++ b/src/edt/edt/edtEditorHooks.cc @@ -64,9 +64,10 @@ public: m_hooks.push_back (hook); } - std::vector get_editor_hooks (const std::string &for_technology) + tl::weak_collection + get_editor_hooks (const std::string &for_technology) { - std::vector res; + tl::weak_collection res; for (auto h = m_hooks.begin (); h != m_hooks.end (); ++h) { if (! h->for_technologies () || h->is_for_technology (for_technology)) { res.push_back (h.operator-> ()); @@ -135,13 +136,13 @@ EditorHooks::register_editor_hook (EditorHooks *hook) } } -std::vector +tl::weak_collection EditorHooks::get_editor_hooks (const std::string &for_technology) { if (EditorHooksManager::instance ()) { return EditorHooksManager::instance ()->get_editor_hooks (for_technology); } else { - return std::vector (); + return tl::weak_collection (); } } diff --git a/src/edt/edt/edtEditorHooks.h b/src/edt/edt/edtEditorHooks.h index 5a557a4b3..076fa193b 100644 --- a/src/edt/edt/edtEditorHooks.h +++ b/src/edt/edt/edtEditorHooks.h @@ -29,6 +29,7 @@ #include "dbTrans.h" #include "gsiObject.h" #include "tlExceptions.h" +#include "tlObjectCollection.h" #include #include @@ -152,7 +153,7 @@ public: * * The order of the hooks is determined by the registration order. */ - static std::vector get_editor_hooks (const std::string &for_technology); + static tl::weak_collection get_editor_hooks (const std::string &for_technology); private: std::set m_technologies; @@ -167,12 +168,14 @@ private: */ inline -void call_editor_hooks (const std::vector &hooks, void (EditorHooks::*meth) ()) +void call_editor_hooks (const tl::weak_collection &hooks, void (EditorHooks::*meth) ()) { for (auto h = hooks.begin (); h != hooks.end (); ++h) { BEGIN_PROTECTED try { - ((*h)->*meth) (); + if (h.operator-> ()) { + (const_cast (h.operator-> ())->*meth) (); + } } catch (tl::CancelException &) { return; } @@ -188,12 +191,14 @@ END_PROTECTED template inline -void call_editor_hooks (const std::vector &hooks, void (EditorHooks::*meth) (A1), A1 a1) +void call_editor_hooks (const tl::weak_collection &hooks, void (EditorHooks::*meth) (A1), A1 a1) { for (auto h = hooks.begin (); h != hooks.end (); ++h) { BEGIN_PROTECTED try { - ((*h)->*meth) (a1); + if (h.operator-> ()) { + (const_cast (h.operator-> ())->*meth) (a1); + } } catch (tl::CancelException &) { return; } @@ -209,12 +214,14 @@ END_PROTECTED template inline -void call_editor_hooks (const std::vector &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2) +void call_editor_hooks (const tl::weak_collection &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2) { for (auto h = hooks.begin (); h != hooks.end (); ++h) { BEGIN_PROTECTED try { - ((*h)->*meth) (a1, a2); + if (h.operator-> ()) { + (const_cast (h.operator-> ())->*meth) (a1, a2); + } } catch (tl::CancelException &) { return; } @@ -230,12 +237,14 @@ END_PROTECTED template inline -void call_editor_hooks (const std::vector &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2, A3 a3) +void call_editor_hooks (const tl::weak_collection &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2, A3 a3) { for (auto h = hooks.begin (); h != hooks.end (); ++h) { BEGIN_PROTECTED try { - ((*h)->*meth) (a1, a2, a3); + if (h.operator-> ()) { + (const_cast (h.operator-> ())->*meth) (a1, a2, a3); + } } catch (tl::CancelException &) { return; } diff --git a/src/tl/tl/tlObjectCollection.h b/src/tl/tl/tlObjectCollection.h index 878e09dab..c2a4ff820 100644 --- a/src/tl/tl/tlObjectCollection.h +++ b/src/tl/tl/tlObjectCollection.h @@ -176,38 +176,36 @@ public: : public weak_or_shared_ptr { public: - holder_type (weak_or_shared_collection *collection) - : weak_or_shared_ptr (), next (0), prev (0), mp_collection (collection) + holder_type (weak_or_shared_collection *_collection) + : weak_or_shared_ptr (), next (0), prev (0), collection (_collection) { // .. nothing yet .. } - holder_type (weak_or_shared_collection *collection, T *t) - : weak_or_shared_ptr (t), next (0), prev (0), mp_collection (collection) + holder_type (weak_or_shared_collection *_collection, T *t) + : weak_or_shared_ptr (t), next (0), prev (0), collection (_collection) { // .. nothing yet .. } - holder_type (weak_or_shared_collection *collection, const weak_or_shared_ptr &d) - : weak_or_shared_ptr (d), next (0), prev (0), mp_collection (collection) + holder_type (weak_or_shared_collection *_collection, const weak_or_shared_ptr &d) + : weak_or_shared_ptr (d), next (0), prev (0), collection (_collection) { // .. nothing yet .. } holder_type *next, *prev; + weak_or_shared_collection *collection; protected: virtual void reset_object () { weak_or_shared_ptr::reset_object (); - if (mp_collection) { + if (collection) { // Caution: this will probably delete "this"! - mp_collection->remove_element (this); + collection->remove_element (this); } } - - private: - weak_or_shared_collection *mp_collection; }; typedef weak_or_shared_collection_iterator iterator; @@ -224,6 +222,24 @@ public: { } + /** + * @brief The copy constructor + */ + weak_or_shared_collection (const weak_or_shared_collection &other) + : mp_first (0), mp_last (0), m_size (0) + { + operator= (other); + } + + /** + * @brief The move constructor + */ + weak_or_shared_collection (weak_or_shared_collection &&other) + : mp_first (0), mp_last (0), m_size (0) + { + swap (other); + } + /** * @brief Destructor */ @@ -234,6 +250,37 @@ public: } } + /** + * @brief Assignment + */ + weak_or_shared_collection &operator= (const weak_or_shared_collection &other) + { + if (this != &other) { + clear (); + for (auto i = other.begin (); i != other.end (); ++i) { + push_back (const_cast (i.operator-> ())); + } + } + return *this; + } + + /** + * @brief Swap + */ + void swap (weak_or_shared_collection &other) + { + std::swap (mp_first, other.mp_first); + std::swap (mp_last, other.mp_last); + std::swap (m_size, other.m_size); + + for (holder_type *h = mp_first; h; h = h->next) { + h->collection = this; + } + for (holder_type *h = other.mp_first; h; h = h->next) { + h->collection = &other; + } + } + /** * @brief Returns a value indicating whether the collection is empty */ diff --git a/src/tl/unit_tests/tlObjectTests.cc b/src/tl/unit_tests/tlObjectTests.cc index d4b5653d3..b5cfaabd5 100644 --- a/src/tl/unit_tests/tlObjectTests.cc +++ b/src/tl/unit_tests/tlObjectTests.cc @@ -516,6 +516,48 @@ TEST(24) EXPECT_EQ (MyClass::instances (), 0); } +TEST(25) +{ + MyClass::reset_instance_counter (); + MyClass *o1 = new MyClass (1); + MyClass *o2 = new MyClass (2); + EXPECT_EQ (MyClass::instances (), 2); + + tl::shared_collection sc1, sc2; + sc1.push_back (o1); + sc1.push_back (o2); + EXPECT_EQ (sc1.size (), size_t (2)); + EXPECT_EQ (sc2.size (), size_t (0)); + EXPECT_EQ (sc1.front () == o1, true); + + sc1.swap (sc2); + EXPECT_EQ (sc1.size (), size_t (0)); + EXPECT_EQ (sc2.size (), size_t (2)); + EXPECT_EQ (sc2.front () == o1, true); + EXPECT_EQ (MyClass::instances (), 2); + + sc1 = sc2; + EXPECT_EQ (sc1.size (), size_t (2)); + EXPECT_EQ (sc2.size (), size_t (2)); + EXPECT_EQ (sc1.front () == o1, true); + EXPECT_EQ (sc2.front () == o1, true); + EXPECT_EQ (MyClass::instances (), 2); + + delete o1; + EXPECT_EQ (sc1.size (), size_t (1)); + EXPECT_EQ (sc2.size (), size_t (1)); + EXPECT_EQ (sc1.front () == o2, true); + EXPECT_EQ (sc2.front () == o2, true); + EXPECT_EQ (MyClass::instances (), 1); + + sc1.clear (); + sc2.clear (); + EXPECT_EQ (sc1.size (), size_t (0)); + EXPECT_EQ (sc2.size (), size_t (0)); + + EXPECT_EQ (MyClass::instances (), 0); +} + TEST(30) { MyClass::reset_instance_counter ();