mirror of https://github.com/KLayout/klayout.git
Fixed a performance issue with many markers.
This commit is contained in:
parent
eb9363eca1
commit
1b1ed7b291
|
|
@ -41,20 +41,21 @@ namespace tl
|
|||
* It is based on a opaque internal iterator (Iter) which provides the standard
|
||||
* compare and assignment methods.
|
||||
*/
|
||||
template <class T, class Iter, bool Shared>
|
||||
template <class T, class Holder, bool Shared>
|
||||
class weak_or_shared_collection_iterator
|
||||
: public Iter
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T &reference;
|
||||
typedef T *pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
weak_or_shared_collection_iterator ()
|
||||
: Iter ()
|
||||
: mp_holder (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -62,21 +63,36 @@ public:
|
|||
/**
|
||||
* @brief Constructor from the internal iterator type
|
||||
*/
|
||||
weak_or_shared_collection_iterator (Iter i)
|
||||
: Iter (i)
|
||||
weak_or_shared_collection_iterator (Holder *holder)
|
||||
: mp_holder (holder)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Equality of iterators
|
||||
*/
|
||||
bool operator== (const weak_or_shared_collection_iterator &other) const
|
||||
{
|
||||
return mp_holder == other.mp_holder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inequality of iterators
|
||||
*/
|
||||
bool operator!= (const weak_or_shared_collection_iterator &other) const
|
||||
{
|
||||
return mp_holder != other.mp_holder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dereferencing
|
||||
* Dereferencing delivers a reference to the stored object (T &).
|
||||
*/
|
||||
reference operator* () const
|
||||
{
|
||||
T *t = dynamic_cast<T *> (Iter::operator* ().operator-> ());
|
||||
tl_assert (t != 0);
|
||||
return *t;
|
||||
tl_assert (mp_holder != 0);
|
||||
return mp_holder->operator* ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -84,63 +100,64 @@ public:
|
|||
*/
|
||||
pointer operator-> () const
|
||||
{
|
||||
return dynamic_cast<T *> (Iter::operator* ().operator-> ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the iterator offset by the distance d.
|
||||
*/
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> operator+ (typename Iter::difference_type d) const
|
||||
{
|
||||
return weak_or_shared_collection_iterator<T, Iter, Shared> (Iter::operator+ (d));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Offsets the iterator by the distance d.
|
||||
*/
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> operator+= (typename Iter::difference_type d) const
|
||||
{
|
||||
Iter::operator+= (d);
|
||||
return *this;
|
||||
tl_assert (mp_holder != 0);
|
||||
return mp_holder->operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pre-decrement
|
||||
*/
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> &operator-- ()
|
||||
weak_or_shared_collection_iterator<T, Holder, Shared> &operator-- ()
|
||||
{
|
||||
Iter::operator-- ();
|
||||
tl_assert (mp_holder);
|
||||
mp_holder = mp_holder->prev;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post-decrement
|
||||
*/
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> operator-- (int n)
|
||||
weak_or_shared_collection_iterator<T, Holder, Shared> operator-- (int n)
|
||||
{
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> ret = *this;
|
||||
Iter::operator-- (n);
|
||||
weak_or_shared_collection_iterator<T, Holder, Shared> ret = *this;
|
||||
while (n-- > 0) {
|
||||
operator-- ();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pre-increment
|
||||
*/
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> &operator++ ()
|
||||
weak_or_shared_collection_iterator<T, Holder, Shared> &operator++ ()
|
||||
{
|
||||
Iter::operator++ ();
|
||||
tl_assert (mp_holder);
|
||||
mp_holder = mp_holder->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post-increment
|
||||
*/
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> operator++ (int n)
|
||||
weak_or_shared_collection_iterator<T, Holder, Shared> operator++ (int n)
|
||||
{
|
||||
weak_or_shared_collection_iterator<T, Iter, Shared> ret = *this;
|
||||
Iter::operator++ (n);
|
||||
weak_or_shared_collection_iterator<T, Holder, Shared> ret = *this;
|
||||
while (n-- > 0) {
|
||||
operator++ ();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal: access to the holder object
|
||||
*/
|
||||
Holder *holder () const
|
||||
{
|
||||
return mp_holder;
|
||||
}
|
||||
|
||||
public:
|
||||
Holder *mp_holder;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -155,29 +172,31 @@ public:
|
|||
template <class T, bool Shared>
|
||||
class weak_or_shared_collection
|
||||
{
|
||||
private:
|
||||
public:
|
||||
class holder_type
|
||||
: public weak_or_shared_ptr<T, Shared>
|
||||
{
|
||||
public:
|
||||
holder_type (weak_or_shared_collection<T, Shared> *collection)
|
||||
: weak_or_shared_ptr<T, Shared> (), mp_collection (collection)
|
||||
: weak_or_shared_ptr<T, Shared> (), next (0), prev (0), mp_collection (collection)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
holder_type (weak_or_shared_collection<T, Shared> *collection, T *t)
|
||||
: weak_or_shared_ptr<T, Shared> (t), mp_collection (collection)
|
||||
: weak_or_shared_ptr<T, Shared> (t), next (0), prev (0), mp_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), mp_collection (collection)
|
||||
: weak_or_shared_ptr<T, Shared> (d), next (0), prev (0), mp_collection (collection)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
holder_type *next, *prev;
|
||||
|
||||
protected:
|
||||
virtual void reset_object ()
|
||||
{
|
||||
|
|
@ -192,11 +211,8 @@ private:
|
|||
weak_or_shared_collection<T, Shared> *mp_collection;
|
||||
};
|
||||
|
||||
typedef std::vector<holder_type> basic_vector_type;
|
||||
|
||||
public:
|
||||
typedef weak_or_shared_collection_iterator<T, typename basic_vector_type::iterator, Shared> iterator;
|
||||
typedef weak_or_shared_collection_iterator<const T, typename basic_vector_type::const_iterator, Shared> const_iterator;
|
||||
typedef weak_or_shared_collection_iterator<T, holder_type, Shared> iterator;
|
||||
typedef weak_or_shared_collection_iterator<const T, holder_type, Shared> const_iterator;
|
||||
typedef T value_type;
|
||||
typedef T &reference;
|
||||
typedef T *pointer;
|
||||
|
|
@ -205,24 +221,34 @@ public:
|
|||
* @brief The default constructor
|
||||
*/
|
||||
weak_or_shared_collection ()
|
||||
: m_c ()
|
||||
: mp_first (0), mp_last (0), m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~weak_or_shared_collection ()
|
||||
{
|
||||
while (! empty ()) {
|
||||
erase (mp_first);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the collection is empty
|
||||
*/
|
||||
bool empty () const
|
||||
{
|
||||
return m_c.empty ();
|
||||
return mp_first == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the collection
|
||||
*/
|
||||
typename basic_vector_type::size_type size () const
|
||||
size_t size () const
|
||||
{
|
||||
return m_c.size ();
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -230,11 +256,12 @@ public:
|
|||
*/
|
||||
void clear ()
|
||||
{
|
||||
if (! m_c.empty ()) {
|
||||
m_about_to_change ();
|
||||
m_c.clear ();
|
||||
m_changed ();
|
||||
m_about_to_change ();
|
||||
while (! empty ()) {
|
||||
erase (mp_first);
|
||||
}
|
||||
tl_assert (m_size == 0);
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -244,11 +271,15 @@ public:
|
|||
*/
|
||||
void erase (T *t)
|
||||
{
|
||||
for (iterator i = begin (); i != end (); ++i) {
|
||||
if (i.operator->() == t) {
|
||||
erase (i);
|
||||
break;
|
||||
}
|
||||
holder_type *h = mp_first;
|
||||
while (h && h->operator-> () != t) {
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (h) {
|
||||
m_about_to_change ();
|
||||
erase (h);
|
||||
m_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,7 +291,7 @@ public:
|
|||
void erase (iterator i)
|
||||
{
|
||||
m_about_to_change ();
|
||||
m_c.erase (i);
|
||||
erase (i.holder ());
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +302,7 @@ public:
|
|||
void insert (iterator before, T *object)
|
||||
{
|
||||
m_about_to_change ();
|
||||
m_c.insert (before, holder_type (this, object));
|
||||
insert (before.holder (), new holder_type (this, object));
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +313,7 @@ public:
|
|||
void insert (iterator before, const weak_or_shared_ptr<T, Shared> &object)
|
||||
{
|
||||
m_about_to_change ();
|
||||
m_c.insert (before, holder_type (this, object));
|
||||
insert (before.holder (), new holder_type (this, object));
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +324,7 @@ public:
|
|||
void push_back (T *object)
|
||||
{
|
||||
m_about_to_change ();
|
||||
m_c.insert (m_c.end (), holder_type (this, object));
|
||||
insert (0, new holder_type (this, object));
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +335,7 @@ public:
|
|||
void push_back (const weak_or_shared_ptr<T, Shared> &object)
|
||||
{
|
||||
m_about_to_change ();
|
||||
m_c.insert (m_c.end (), holder_type (this, object));
|
||||
insert (0, new holder_type (this, object));
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +348,7 @@ public:
|
|||
{
|
||||
if (! empty ()) {
|
||||
m_about_to_change ();
|
||||
m_c.pop_back ();
|
||||
erase (mp_last);
|
||||
m_changed ();
|
||||
}
|
||||
}
|
||||
|
|
@ -327,7 +358,7 @@ public:
|
|||
*/
|
||||
typename iterator::pointer front ()
|
||||
{
|
||||
return begin ().operator-> ();
|
||||
return mp_first->operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -335,7 +366,7 @@ public:
|
|||
*/
|
||||
typename iterator::pointer back ()
|
||||
{
|
||||
return (--end ()).operator-> ();
|
||||
return mp_last->operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -343,7 +374,7 @@ public:
|
|||
*/
|
||||
typename const_iterator::pointer front () const
|
||||
{
|
||||
return begin ().operator-> ();
|
||||
return mp_first->operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -351,23 +382,7 @@ public:
|
|||
*/
|
||||
typename const_iterator::pointer back () const
|
||||
{
|
||||
return (--end ()).operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a pointer to the nth object in the collection
|
||||
*/
|
||||
typename iterator::pointer operator[] (typename iterator::difference_type i)
|
||||
{
|
||||
return (begin () + i).operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a pointer to the nth object in the collection (const version)
|
||||
*/
|
||||
typename const_iterator::pointer operator[] (typename iterator::difference_type i) const
|
||||
{
|
||||
return (begin () + i).operator-> ();
|
||||
return mp_last->operator-> ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -375,7 +390,7 @@ public:
|
|||
*/
|
||||
iterator begin ()
|
||||
{
|
||||
return iterator (m_c.begin ());
|
||||
return iterator (mp_first);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -383,7 +398,7 @@ public:
|
|||
*/
|
||||
iterator end ()
|
||||
{
|
||||
return iterator (m_c.end ());
|
||||
return iterator (0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -391,7 +406,7 @@ public:
|
|||
*/
|
||||
const_iterator begin () const
|
||||
{
|
||||
return const_iterator (m_c.begin ());
|
||||
return const_iterator (mp_first);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -399,7 +414,7 @@ public:
|
|||
*/
|
||||
const_iterator end () const
|
||||
{
|
||||
return const_iterator (m_c.end ());
|
||||
return const_iterator (0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -420,24 +435,70 @@ public:
|
|||
|
||||
private:
|
||||
friend class holder_type;
|
||||
basic_vector_type m_c;
|
||||
QMutex m_lock;
|
||||
|
||||
void remove_element (holder_type *h)
|
||||
{
|
||||
QMutexLocker locker (&m_lock);
|
||||
tl_assert (! empty ());
|
||||
// NOTE: this is a quick but somewhat dirty hack to obtain the index of an element.
|
||||
// It is based on the assumption that a vector's elements are stored inside a
|
||||
// contiguous memory array.
|
||||
size_t index = h - &(m_c.front ());
|
||||
tl_assert (index < m_c.size ());
|
||||
m_about_to_change ();
|
||||
m_c.erase (m_c.begin () + index);
|
||||
erase (h);
|
||||
m_changed ();
|
||||
}
|
||||
|
||||
void erase (holder_type *h)
|
||||
{
|
||||
if (h == mp_first) {
|
||||
mp_first = h->next;
|
||||
}
|
||||
if (h == mp_last) {
|
||||
mp_last = h->prev;
|
||||
}
|
||||
if (h->next) {
|
||||
h->next->prev = h->prev;
|
||||
}
|
||||
if (h->prev) {
|
||||
h->prev->next = h->next;
|
||||
}
|
||||
|
||||
delete h;
|
||||
|
||||
--m_size;
|
||||
}
|
||||
|
||||
void insert (holder_type *before, holder_type *h)
|
||||
{
|
||||
if (! before) {
|
||||
|
||||
h->prev = mp_last;
|
||||
h->next = 0;
|
||||
if (mp_last) {
|
||||
mp_last->next = h;
|
||||
}
|
||||
|
||||
mp_last = h;
|
||||
if (! mp_first) {
|
||||
mp_first = h;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
h->prev = before->prev;
|
||||
h->next = before;
|
||||
before->prev = h;
|
||||
|
||||
if (before == mp_first) {
|
||||
mp_first = h;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
++m_size;
|
||||
}
|
||||
|
||||
tl::Event m_about_to_change, m_changed;
|
||||
holder_type *mp_first, *mp_last;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -326,8 +326,8 @@ TEST(20)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (sc.size ()), 1);
|
||||
EXPECT_EQ (sc.empty (), false);
|
||||
EXPECT_EQ (sc[0] == o, true);
|
||||
EXPECT_EQ (sc[0]->attr (), 17);
|
||||
EXPECT_EQ (sc.front () == o, true);
|
||||
EXPECT_EQ (sc.front ()->attr (), 17);
|
||||
|
||||
delete o;
|
||||
o = 0;
|
||||
|
|
@ -350,7 +350,7 @@ TEST(21)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (sc.size ()), 1);
|
||||
EXPECT_EQ (sc.empty (), false);
|
||||
EXPECT_EQ (sc[0]->attr (), 1);
|
||||
EXPECT_EQ (sc.front ()->attr (), 1);
|
||||
|
||||
sc.clear ();
|
||||
EXPECT_EQ (int (sc.size ()), 0);
|
||||
|
|
@ -361,7 +361,7 @@ TEST(21)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (sc.size ()), 1);
|
||||
EXPECT_EQ (sc.empty (), false);
|
||||
EXPECT_EQ (sc[0]->attr (), 2);
|
||||
EXPECT_EQ (sc.front ()->attr (), 2);
|
||||
}
|
||||
|
||||
EXPECT_EQ (MyClass::instances (), 0);
|
||||
|
|
@ -380,8 +380,8 @@ TEST(22)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (sc.size ()), 2);
|
||||
EXPECT_EQ (sc.empty (), false);
|
||||
EXPECT_EQ (sc[0]->attr (), 1);
|
||||
EXPECT_EQ (sc[1]->attr (), 1);
|
||||
EXPECT_EQ (sc.front ()->attr (), 1);
|
||||
EXPECT_EQ ((++sc.begin ())->attr (), 1);
|
||||
|
||||
sc.pop_back ();
|
||||
EXPECT_EQ (int (sc.size ()), 1);
|
||||
|
|
@ -399,8 +399,8 @@ TEST(22)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (sc.size ()), 2);
|
||||
EXPECT_EQ (sc.empty (), false);
|
||||
EXPECT_EQ (sc[0]->attr (), 2);
|
||||
EXPECT_EQ (sc[1]->attr (), 2);
|
||||
EXPECT_EQ (sc.front ()->attr (), 2);
|
||||
EXPECT_EQ ((++sc.begin ())->attr (), 2);
|
||||
}
|
||||
|
||||
EXPECT_EQ (MyClass::instances (), 0);
|
||||
|
|
@ -450,7 +450,7 @@ TEST(23)
|
|||
++inc;
|
||||
EXPECT_EQ (inc == sc.end (), true);
|
||||
|
||||
tl::shared_ptr<MyClass> o2t = sc[1];
|
||||
tl::shared_ptr<MyClass> o2t ((++sc.begin ()).operator-> ());
|
||||
sc.clear ();
|
||||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (o2t->attr (), 2);
|
||||
|
|
@ -473,26 +473,26 @@ TEST(24)
|
|||
|
||||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
|
||||
EXPECT_EQ (sc1[0]->attr (), 1);
|
||||
EXPECT_EQ (sc1.front ()->attr (), 1);
|
||||
EXPECT_EQ (int (sc1.size ()), 1);
|
||||
EXPECT_EQ (sc1.empty (), false);
|
||||
EXPECT_EQ (sc2[0]->attr (), 1);
|
||||
EXPECT_EQ (sc2.front ()->attr (), 1);
|
||||
EXPECT_EQ (int (sc2.size ()), 1);
|
||||
EXPECT_EQ (sc2.empty (), false);
|
||||
|
||||
sc1[0]->set_attr (42);
|
||||
EXPECT_EQ (sc1[0]->attr (), 42);
|
||||
EXPECT_EQ (sc2[0]->attr (), 42);
|
||||
sc1.front ()->set_attr (42);
|
||||
EXPECT_EQ (sc1.front ()->attr (), 42);
|
||||
EXPECT_EQ (sc2.front ()->attr (), 42);
|
||||
|
||||
sc1.clear ();
|
||||
sc1.push_back (new MyClass (2));
|
||||
EXPECT_EQ (sc1[0] == o, false);
|
||||
EXPECT_EQ (sc2[0] == o, true);
|
||||
EXPECT_EQ (sc1[0]->attr (), 2);
|
||||
EXPECT_EQ (sc1.front () == o, false);
|
||||
EXPECT_EQ (sc2.front () == o, true);
|
||||
EXPECT_EQ (sc1.front ()->attr (), 2);
|
||||
EXPECT_EQ (MyClass::instances (), 2);
|
||||
|
||||
sc2.clear ();
|
||||
EXPECT_EQ (sc1[0]->attr (), 2);
|
||||
EXPECT_EQ (sc1.front ()->attr (), 2);
|
||||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
}
|
||||
|
||||
|
|
@ -518,8 +518,8 @@ TEST(30)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (wc.size ()), 1);
|
||||
EXPECT_EQ (wc.empty (), false);
|
||||
EXPECT_EQ (wc[0] == o, true);
|
||||
EXPECT_EQ (wc[0]->attr (), 17);
|
||||
EXPECT_EQ (wc.front () == o, true);
|
||||
EXPECT_EQ (wc.front ()->attr (), 17);
|
||||
|
||||
so.reset (0);
|
||||
|
||||
|
|
@ -549,8 +549,8 @@ TEST(31)
|
|||
EXPECT_EQ (MyClass::instances (), 1);
|
||||
EXPECT_EQ (int (wc.size ()), 1);
|
||||
EXPECT_EQ (wc.empty (), false);
|
||||
EXPECT_EQ (wc[0] == o, true);
|
||||
EXPECT_EQ (wc[0]->attr (), 17);
|
||||
EXPECT_EQ (wc.front () == o, true);
|
||||
EXPECT_EQ (wc.front ()->attr (), 17);
|
||||
|
||||
tl::shared_ptr<MyClass> so2 (new MyClass ());
|
||||
so2->set_attr (42);
|
||||
|
|
@ -560,18 +560,21 @@ TEST(31)
|
|||
EXPECT_EQ (MyClass::instances (), 2);
|
||||
EXPECT_EQ (int (wc.size ()), 3);
|
||||
EXPECT_EQ (wc.empty (), false);
|
||||
EXPECT_EQ (wc[0] == o, true);
|
||||
EXPECT_EQ (wc[0]->attr (), 17);
|
||||
EXPECT_EQ (wc[1] == so2.get (), true);
|
||||
EXPECT_EQ (wc[1]->attr (), 42);
|
||||
EXPECT_EQ (wc[2] == o, true);
|
||||
EXPECT_EQ (wc[2]->attr (), 17);
|
||||
tl::weak_collection<MyClass>::iterator i = wc.begin ();
|
||||
EXPECT_EQ (i.operator-> () == o, true);
|
||||
EXPECT_EQ (i->attr (), 17);
|
||||
++i;
|
||||
EXPECT_EQ (i.operator-> () == so2.get (), true);
|
||||
EXPECT_EQ (i->attr (), 42);
|
||||
++i;
|
||||
EXPECT_EQ (i.operator-> () == o, true);
|
||||
EXPECT_EQ (i->attr (), 17);
|
||||
|
||||
so.reset (0);
|
||||
|
||||
EXPECT_EQ (int (wc.size ()), 1);
|
||||
EXPECT_EQ (wc[0] == so2.get (), true);
|
||||
EXPECT_EQ (wc[0]->attr (), 42);
|
||||
EXPECT_EQ (wc.front () == so2.get (), true);
|
||||
EXPECT_EQ (wc.front ()->attr (), 42);
|
||||
|
||||
so2 = so;
|
||||
|
||||
|
|
@ -651,3 +654,21 @@ TEST(40)
|
|||
so.reset (0);
|
||||
EXPECT_EQ (MyClass::instances (), 0);
|
||||
}
|
||||
|
||||
TEST(41)
|
||||
{
|
||||
tl::weak_collection<MyClass> wc;
|
||||
|
||||
std::vector<MyClass *> objects;
|
||||
for (size_t i = 0; i < 2000000; ++i) {
|
||||
objects.push_back (new MyClass ());
|
||||
wc.push_back (objects.back ());
|
||||
}
|
||||
|
||||
for (std::vector<MyClass *>::const_iterator i = objects.begin (); i != objects.end (); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
objects.clear ();
|
||||
|
||||
EXPECT_EQ (wc.empty (), true);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue