Copy ctor, swap and move for tl::shared_collection and tl::weak_collection

This commit is contained in:
Matthias Koefferlein 2024-03-30 00:58:09 +01:00
parent d1216b5891
commit 1868dcc104
4 changed files with 123 additions and 24 deletions

View File

@ -64,9 +64,10 @@ public:
m_hooks.push_back (hook);
}
std::vector<EditorHooks *> get_editor_hooks (const std::string &for_technology)
tl::weak_collection<EditorHooks>
get_editor_hooks (const std::string &for_technology)
{
std::vector<EditorHooks *> res;
tl::weak_collection<EditorHooks> 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<EditorHooks *>
tl::weak_collection<EditorHooks>
EditorHooks::get_editor_hooks (const std::string &for_technology)
{
if (EditorHooksManager::instance ()) {
return EditorHooksManager::instance ()->get_editor_hooks (for_technology);
} else {
return std::vector<EditorHooks *> ();
return tl::weak_collection<EditorHooks> ();
}
}

View File

@ -29,6 +29,7 @@
#include "dbTrans.h"
#include "gsiObject.h"
#include "tlExceptions.h"
#include "tlObjectCollection.h"
#include <set>
#include <string>
@ -152,7 +153,7 @@ public:
*
* The order of the hooks is determined by the registration order.
*/
static std::vector<EditorHooks *> get_editor_hooks (const std::string &for_technology);
static tl::weak_collection<EditorHooks> get_editor_hooks (const std::string &for_technology);
private:
std::set<std::string> m_technologies;
@ -167,12 +168,14 @@ private:
*/
inline
void call_editor_hooks (const std::vector<EditorHooks *> &hooks, void (EditorHooks::*meth) ())
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) ())
{
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
BEGIN_PROTECTED
try {
((*h)->*meth) ();
if (h.operator-> ()) {
(const_cast<EditorHooks *> (h.operator-> ())->*meth) ();
}
} catch (tl::CancelException &) {
return;
}
@ -188,12 +191,14 @@ END_PROTECTED
template <class A1>
inline
void call_editor_hooks (const std::vector<EditorHooks *> &hooks, void (EditorHooks::*meth) (A1), A1 a1)
void call_editor_hooks (const tl::weak_collection<EditorHooks> &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<EditorHooks *> (h.operator-> ())->*meth) (a1);
}
} catch (tl::CancelException &) {
return;
}
@ -209,12 +214,14 @@ END_PROTECTED
template <class A1, class A2>
inline
void call_editor_hooks (const std::vector<EditorHooks *> &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2)
void call_editor_hooks (const tl::weak_collection<EditorHooks> &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<EditorHooks *> (h.operator-> ())->*meth) (a1, a2);
}
} catch (tl::CancelException &) {
return;
}
@ -230,12 +237,14 @@ END_PROTECTED
template <class A1, class A2, class A3>
inline
void call_editor_hooks (const std::vector<EditorHooks *> &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2, A3 a3)
void call_editor_hooks (const tl::weak_collection<EditorHooks> &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<EditorHooks *> (h.operator-> ())->*meth) (a1, a2, a3);
}
} catch (tl::CancelException &) {
return;
}

View File

@ -176,38 +176,36 @@ public:
: public weak_or_shared_ptr<T, Shared>
{
public:
holder_type (weak_or_shared_collection<T, Shared> *collection)
: weak_or_shared_ptr<T, Shared> (), next (0), prev (0), mp_collection (collection)
holder_type (weak_or_shared_collection<T, Shared> *_collection)
: weak_or_shared_ptr<T, Shared> (), next (0), prev (0), collection (_collection)
{
// .. nothing yet ..
}
holder_type (weak_or_shared_collection<T, Shared> *collection, T *t)
: weak_or_shared_ptr<T, Shared> (t), next (0), prev (0), mp_collection (collection)
holder_type (weak_or_shared_collection<T, Shared> *_collection, T *t)
: weak_or_shared_ptr<T, Shared> (t), next (0), prev (0), collection (_collection)
{
// .. nothing yet ..
}
holder_type (weak_or_shared_collection<T, Shared> *collection, const weak_or_shared_ptr<T, Shared> &d)
: weak_or_shared_ptr<T, Shared> (d), next (0), prev (0), mp_collection (collection)
holder_type (weak_or_shared_collection<T, Shared> *_collection, const weak_or_shared_ptr<T, Shared> &d)
: weak_or_shared_ptr<T, Shared> (d), next (0), prev (0), collection (_collection)
{
// .. nothing yet ..
}
holder_type *next, *prev;
weak_or_shared_collection<T, Shared> *collection;
protected:
virtual void reset_object ()
{
weak_or_shared_ptr<T, Shared>::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<T, Shared> *mp_collection;
};
typedef weak_or_shared_collection_iterator<T, holder_type, Shared> iterator;
@ -224,6 +222,24 @@ public:
{
}
/**
* @brief The copy constructor
*/
weak_or_shared_collection (const weak_or_shared_collection<T, Shared> &other)
: mp_first (0), mp_last (0), m_size (0)
{
operator= (other);
}
/**
* @brief The move constructor
*/
weak_or_shared_collection (weak_or_shared_collection<T, Shared> &&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<T, Shared> &other)
{
if (this != &other) {
clear ();
for (auto i = other.begin (); i != other.end (); ++i) {
push_back (const_cast<T *> (i.operator-> ()));
}
}
return *this;
}
/**
* @brief Swap
*/
void swap (weak_or_shared_collection<T, Shared> &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
*/

View File

@ -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<MyClass> 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 ();