diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index fd6554b5f..e2a9bbec8 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1264,7 +1264,7 @@ connected_clusters::join_cluster_with (typename local_cluster::id_type id, } connections_type &target = m_connections [id]; - target.splice (target.end (), to_join, to_join.begin (), to_join.end ()); + target.splice (to_join); m_connections.erase (tc); diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 030f41c87..2c6b10cbd 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -211,6 +211,273 @@ private: edge_connectivity_type m_ec; }; +/** + * @brief The instance information for a cluster + */ +class DB_PUBLIC ClusterInstElement +{ +public: + ClusterInstElement (const db::InstElement &ie) + { + if (ie.array_inst.at_end ()) { + + m_inst_cell_index = std::numeric_limits::max (); + m_inst_trans = db::ICplxTrans (); + m_inst_prop_id = 0; + + } else { + + m_inst_cell_index = ie.inst_ptr.cell_index (); + m_inst_trans = ie.complex_trans (); + m_inst_prop_id = ie.inst_ptr.prop_id (); + + } + } + + ClusterInstElement (db::cell_index_type inst_cell_index, const db::ICplxTrans &inst_trans, db::properties_id_type inst_prop_id) + : m_inst_cell_index (inst_cell_index), m_inst_trans (inst_trans), m_inst_prop_id (inst_prop_id) + { + // .. nothing yet .. + } + + ClusterInstElement () + : m_inst_cell_index (std::numeric_limits::max ()), m_inst_trans (), m_inst_prop_id (0) + { + // .. nothing yet .. + } + + /** + * @brief Returns true, if the cluster does not have an instance + */ + bool has_instance () const + { + return m_inst_cell_index != std::numeric_limits::max (); + } + + /** + * @brief Gets the cell index of the cell which is instantiated + */ + db::cell_index_type inst_cell_index () const + { + return m_inst_cell_index; + } + + /** + * @brief Gets the instance transformation + */ + const db::ICplxTrans &inst_trans () const + { + return m_inst_trans; + } + + /** + * @brief Gets the instance properties id + */ + db::properties_id_type inst_prop_id () const + { + return m_inst_prop_id; + } + + /** + * @brief Sets the instance properties id + */ + void set_inst_prop_id (db::properties_id_type pid) + { + m_inst_prop_id = pid; + } + + /** + * @brief Transform with the given transformation + */ + void transform (const db::ICplxTrans &tr) + { + m_inst_trans = tr * m_inst_trans; + } + + /** + * @brief Equality + */ + bool operator== (const ClusterInstElement &other) const + { + return m_inst_cell_index == other.m_inst_cell_index && m_inst_trans.equal (other.m_inst_trans) && m_inst_prop_id == other.m_inst_prop_id; + } + + /** + * @brief Inequality + */ + bool operator!= (const ClusterInstElement &other) const + { + return ! operator== (other); + } + + /** + * @brief Less operator + */ + bool operator< (const ClusterInstElement &other) const + { + if (m_inst_cell_index != other.m_inst_cell_index) { + return m_inst_cell_index < other.m_inst_cell_index; + } + if (! m_inst_trans.equal (other.m_inst_trans)) { + return m_inst_trans.less (other.m_inst_trans); + } + return m_inst_prop_id < other.m_inst_prop_id; + } + +private: + db::cell_index_type m_inst_cell_index; + db::ICplxTrans m_inst_trans; + db::properties_id_type m_inst_prop_id; +}; + +/** + * @brief A connection to a cluster in a child instance + */ +class DB_PUBLIC ClusterInstance + : public ClusterInstElement +{ +public: + ClusterInstance (size_t id, db::cell_index_type inst_cell_index, const db::ICplxTrans &inst_trans, db::properties_id_type inst_prop_id) + : ClusterInstElement (inst_cell_index, inst_trans, inst_prop_id), m_id (id) + { + // .. nothing yet .. + } + + ClusterInstance (size_t id, const db::InstElement &inst_element) + : ClusterInstElement (inst_element), m_id (id) + { + // .. nothing yet .. + } + + ClusterInstance (size_t id) + : ClusterInstElement (), m_id (id) + { + // .. nothing yet .. + } + + ClusterInstance () + : ClusterInstElement (), m_id (0) + { + // .. nothing yet .. + } + + /** + * @brief Gets the cluster ID + */ + size_t id () const + { + return m_id; + } + + /** + * @brief Equality + */ + bool operator== (const ClusterInstance &other) const + { + return m_id == other.m_id && ClusterInstElement::operator== (other); + } + + /** + * @brief Inequality + */ + bool operator!= (const ClusterInstance &other) const + { + return ! operator== (other); + } + + /** + * @brief Less operator + */ + bool operator< (const ClusterInstance &other) const + { + if (m_id != other.m_id) { + return m_id < other.m_id; + } + return ClusterInstElement::operator< (other); + } + +private: + size_t m_id; +}; + +/** + * @brief A class representing a list of ClusterInstance objects + * + * It is using a std::list internally, but adds fast size support for STLs which do not have that. + */ +class DB_PUBLIC ClusterInstanceList +{ +public: + typedef std::list inner_list; + typedef inner_list::iterator iterator; + typedef inner_list::const_iterator const_iterator; + + ClusterInstanceList () + : m_list (), m_size (0) + { + // .. nothing yet .. + } + + ClusterInstanceList (const ClusterInstanceList &other) + : m_list (other.m_list), m_size (other.m_size) + { + // .. nothing yet .. + } + + ClusterInstanceList (ClusterInstanceList &&other) + : m_list (other.m_list), m_size (other.m_size) + { + // .. nothing yet .. + } + + ClusterInstanceList &operator= (const ClusterInstanceList &other) + { + if (this != &other) { + m_list = other.m_list; + m_size = other.m_size; + } + return *this; + } + + iterator begin () { return m_list.begin (); } + iterator end () { return m_list.end (); } + const_iterator begin () const { return m_list.begin (); } + const_iterator end () const { return m_list.end (); } + + bool empty () const + { + return m_list.empty (); + } + + void push_back (const ClusterInstance &inst) + { + m_list.push_back (inst); + ++m_size; + } + + void push_back (ClusterInstance &&inst) + { + m_list.push_back (inst); + ++m_size; + } + + void splice (ClusterInstanceList &other) + { + m_size += other.m_size; + m_list.splice (m_list.end (), other.m_list, other.m_list.begin (), other.m_list.end ()); + other.m_size = 0; + } + + size_t size () const + { + return m_size; + } + +private: + inner_list m_list; + size_t m_size; +}; + /** * @brief Represents a cluster of shapes * @@ -596,195 +863,6 @@ inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int x.mem_stat (stat, purpose, cat, no_self, parent); } -/** - * @brief The instance information for a cluster - */ -class DB_PUBLIC ClusterInstElement -{ -public: - ClusterInstElement (const db::InstElement &ie) - { - if (ie.array_inst.at_end ()) { - - m_inst_cell_index = std::numeric_limits::max (); - m_inst_trans = db::ICplxTrans (); - m_inst_prop_id = 0; - - } else { - - m_inst_cell_index = ie.inst_ptr.cell_index (); - m_inst_trans = ie.complex_trans (); - m_inst_prop_id = ie.inst_ptr.prop_id (); - - } - } - - ClusterInstElement (db::cell_index_type inst_cell_index, const db::ICplxTrans &inst_trans, db::properties_id_type inst_prop_id) - : m_inst_cell_index (inst_cell_index), m_inst_trans (inst_trans), m_inst_prop_id (inst_prop_id) - { - // .. nothing yet .. - } - - ClusterInstElement () - : m_inst_cell_index (std::numeric_limits::max ()), m_inst_trans (), m_inst_prop_id (0) - { - // .. nothing yet .. - } - - /** - * @brief Returns true, if the cluster does not have an instance - */ - bool has_instance () const - { - return m_inst_cell_index != std::numeric_limits::max (); - } - - /** - * @brief Gets the cell index of the cell which is instantiated - */ - db::cell_index_type inst_cell_index () const - { - return m_inst_cell_index; - } - - /** - * @brief Gets the instance transformation - */ - const db::ICplxTrans &inst_trans () const - { - return m_inst_trans; - } - - /** - * @brief Gets the instance properties id - */ - db::properties_id_type inst_prop_id () const - { - return m_inst_prop_id; - } - - /** - * @brief Sets the instance properties id - */ - void set_inst_prop_id (db::properties_id_type pid) - { - m_inst_prop_id = pid; - } - - /** - * @brief Transform with the given transformation - */ - void transform (const db::ICplxTrans &tr) - { - m_inst_trans = tr * m_inst_trans; - } - - /** - * @brief Equality - */ - bool operator== (const ClusterInstElement &other) const - { - return m_inst_cell_index == other.m_inst_cell_index && m_inst_trans.equal (other.m_inst_trans) && m_inst_prop_id == other.m_inst_prop_id; - } - - /** - * @brief Inequality - */ - bool operator!= (const ClusterInstElement &other) const - { - return ! operator== (other); - } - - /** - * @brief Less operator - */ - bool operator< (const ClusterInstElement &other) const - { - if (m_inst_cell_index != other.m_inst_cell_index) { - return m_inst_cell_index < other.m_inst_cell_index; - } - if (! m_inst_trans.equal (other.m_inst_trans)) { - return m_inst_trans.less (other.m_inst_trans); - } - return m_inst_prop_id < other.m_inst_prop_id; - } - -private: - db::cell_index_type m_inst_cell_index; - db::ICplxTrans m_inst_trans; - db::properties_id_type m_inst_prop_id; -}; - -/** - * @brief A connection to a cluster in a child instance - */ -class DB_PUBLIC ClusterInstance - : public ClusterInstElement -{ -public: - ClusterInstance (size_t id, db::cell_index_type inst_cell_index, const db::ICplxTrans &inst_trans, db::properties_id_type inst_prop_id) - : ClusterInstElement (inst_cell_index, inst_trans, inst_prop_id), m_id (id) - { - // .. nothing yet .. - } - - ClusterInstance (size_t id, const db::InstElement &inst_element) - : ClusterInstElement (inst_element), m_id (id) - { - // .. nothing yet .. - } - - ClusterInstance (size_t id) - : ClusterInstElement (), m_id (id) - { - // .. nothing yet .. - } - - ClusterInstance () - : ClusterInstElement (), m_id (0) - { - // .. nothing yet .. - } - - /** - * @brief Gets the cluster ID - */ - size_t id () const - { - return m_id; - } - - /** - * @brief Equality - */ - bool operator== (const ClusterInstance &other) const - { - return m_id == other.m_id && ClusterInstElement::operator== (other); - } - - /** - * @brief Inequality - */ - bool operator!= (const ClusterInstance &other) const - { - return ! operator== (other); - } - - /** - * @brief Less operator - */ - bool operator< (const ClusterInstance &other) const - { - if (m_id != other.m_id) { - return m_id < other.m_id; - } - return ClusterInstElement::operator< (other); - } - -private: - size_t m_id; -}; - typedef std::list > cluster_instance_pair_list_type; inline bool equal_array_delegates (const db::ArrayBase *a, const db::ArrayBase *b) @@ -1040,7 +1118,7 @@ public: private: typename local_clusters::const_iterator m_lc_iter; - typedef std::list connections_type; + typedef ClusterInstanceList connections_type; typename std::map::id_type, connections_type>::const_iterator m_x_iter, m_x_iter_end; }; @@ -1060,7 +1138,7 @@ class DB_PUBLIC_TEMPLATE connected_clusters { public: typedef typename local_clusters::id_type id_type; - typedef std::list connections_type; + typedef ClusterInstanceList connections_type; typedef typename local_clusters::box_type box_type; typedef connected_clusters_iterator all_iterator; typedef typename std::map::id_type, connections_type>::const_iterator connections_iterator; diff --git a/src/tl/tl/tl.pro b/src/tl/tl/tl.pro index 0cc8c7ea4..558134601 100644 --- a/src/tl/tl/tl.pro +++ b/src/tl/tl/tl.pro @@ -51,6 +51,7 @@ SOURCES = \ tlLongInt.cc \ tlUniqueId.cc \ tlList.cc \ + tlSList.cc \ tlEquivalenceClusters.cc \ tlUniqueName.cc \ tlRecipe.cc \ @@ -115,6 +116,7 @@ HEADERS = \ tlLongInt.h \ tlUniqueId.h \ tlList.h \ + tlSList.h \ tlEquivalenceClusters.h \ tlUniqueName.h \ tlRecipe.h \ diff --git a/src/tl/tl/tlSList.cc b/src/tl/tl/tlSList.cc new file mode 100644 index 000000000..c70a255b1 --- /dev/null +++ b/src/tl/tl/tlSList.cc @@ -0,0 +1,31 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2022 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "tlSList.h" + +namespace tl +{ + + // .. nothing yet .. + +} diff --git a/src/tl/tl/tlSList.h b/src/tl/tl/tlSList.h new file mode 100644 index 000000000..44d16611c --- /dev/null +++ b/src/tl/tl/tlSList.h @@ -0,0 +1,320 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2022 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + + +#ifndef HDR_tlSList +#define HDR_tlSList + +#include "tlCommon.h" + +#include +#include + +namespace tl +{ + +/** + * @brief A simple single-linked list implementation + * + * This implementation supports: + * - fast size + * - push_back, push_front + * - forward iterator, const_iterator + * - splice + * - pop_front + * - clear + * - empty + */ + +template +class slist +{ +private: + struct node_type + { + node_type (const T &_t) : next (0), t (_t) { } + node_type (T &&_t) : next (0), t (_t) { } + node_type *next; + T t; + }; + +public: + class iterator + { + public: + typedef std::forward_iterator_tag category; + typedef T value_type; + typedef T &reference; + typedef T *pointer; + + iterator (node_type *p = 0) : mp_p (p) { } + iterator operator++ () { mp_p = mp_p->next; return *this; } + + T *operator-> () const + { + return &mp_p->t; + } + + T &operator* () const + { + return mp_p->t; + } + + bool operator== (iterator other) const { return mp_p == other.mp_p; } + bool operator!= (iterator other) const { return mp_p != other.mp_p; } + + private: + node_type *mp_p; + }; + + class const_iterator + { + public: + typedef std::forward_iterator_tag category; + typedef const T value_type; + typedef const T &reference; + typedef const T *pointer; + + const_iterator (const node_type *p = 0) : mp_p (p) { } + const_iterator operator++ () { mp_p = mp_p->next; return *this; } + + const T *operator-> () const + { + return &mp_p->t; + } + + const T &operator* () const + { + return mp_p->t; + } + + bool operator== (const_iterator other) const { return mp_p == other.mp_p; } + bool operator!= (const_iterator other) const { return mp_p != other.mp_p; } + + private: + const node_type *mp_p; + }; + + slist () + : mp_first (0), mp_last (0) + { + // .. nothing yet .. + } + + template + slist (Iter from, Iter to) + : mp_first (0), mp_last (0), m_size (0) + { + for (Iter i = from; i != to; ++i) { + push_back (*i); + } + } + + slist (const slist &other) + : mp_first (0), mp_last (0), m_size (0) + { + for (auto i = other.begin (); i != other.end (); ++i) { + push_back (*i); + } + } + + slist (slist &&other) + : mp_first (0), mp_last (0), m_size (0) + { + std::swap (mp_first, other.mp_first); + std::swap (mp_last, other.mp_last); + std::swap (m_size, other.m_size); + } + + slist &operator= (const slist &other) + { + if (this != &other) { + clear (); + for (const_iterator i = other.begin (); i != other.end (); ++i) { + push_back (*i); + } + } + return *this; + } + + slist &operator= (slist &&other) + { + clear (); + std::swap (mp_first, other.mp_first); + std::swap (mp_last, other.mp_last); + std::swap (m_size, other.m_size); + return *this; + } + + ~slist () + { + clear (); + } + + iterator begin () + { + return iterator (mp_first); + } + + iterator end () + { + return iterator (0); + } + + const_iterator begin () const + { + return const_iterator (mp_first); + } + + const_iterator end () const + { + return const_iterator (0); + } + + size_t size () const + { + return m_size; + } + + bool empty () const + { + return mp_first == 0; + } + + void clear () + { + while (! empty ()) { + pop_front (); + } + } + + void swap (slist &other) + { + std::swap (mp_first, other.mp_first); + std::swap (mp_last, other.mp_last); + std::swap (m_size, other.m_size); + } + + void pop_front () + { + if (mp_first) { + node_type *n = mp_first; + if (n == mp_last) { + mp_first = mp_last = 0; + } else { + mp_first = mp_first->next; + } + delete n; + --m_size; + } + } + + T &front () + { + return mp_first->t; + } + + const T &front () const + { + return mp_first->t; + } + + T &back () + { + return mp_last->t; + } + + const T &back () const + { + return mp_last->t; + } + + void push_front (const T &t) + { + push_front_impl (new node_type (t)); + } + + void push_front (T &&t) + { + push_front_impl (new node_type (t)); + } + + void push_back (const T &t) + { + push_back_impl (new node_type (t)); + } + + void push_back (T &&t) + { + push_back_impl (new node_type (t)); + } + + void splice (slist &other) + { + if (! other.mp_first) { + return; + } + + if (! mp_first) { + mp_first = other.mp_first; + } else { + mp_last->next = other.mp_first; + } + + mp_last = other.mp_last; + m_size += other.m_size; + + other.mp_first = other.mp_last = 0; + other.m_size = 0; + } + +private: + node_type *mp_first, *mp_last; + size_t m_size; + + void push_front_impl (node_type *n) + { + if (mp_first) { + n->next = mp_first; + mp_first = n; + } else { + mp_first = mp_last = n; + } + ++m_size; + } + + void push_back_impl (node_type *n) + { + if (mp_last) { + mp_last->next = n; + mp_last = n; + } else { + mp_first = mp_last = n; + } + ++m_size; + } +}; + +} + +#endif diff --git a/src/tl/unit_tests/tlSListTests.cc b/src/tl/unit_tests/tlSListTests.cc new file mode 100644 index 000000000..63ef20321 --- /dev/null +++ b/src/tl/unit_tests/tlSListTests.cc @@ -0,0 +1,192 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2022 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "tlSList.h" +#include "tlUnitTest.h" +#include "tlString.h" + +namespace +{ + +static size_t obj_count = 0; + +struct MyClass1 +{ + MyClass1 (int _n) : n (_n) { ++obj_count; } + MyClass1 (const MyClass1 &other) : n (other.n) { ++obj_count; } + MyClass1 &operator= (const MyClass1 &other) { n = other.n; return *this; } + ~MyClass1 () { --obj_count; } + int n; + bool operator== (const MyClass1 &other) const { return n == other.n; } + bool operator< (const MyClass1 &other) const { return n < other.n; } +}; + +} + +template +static std::string l2s (const tl::slist &l) +{ + std::string x; + for (typename tl::slist::const_iterator i = l.begin (); i != l.end (); ++i) { + if (!x.empty ()) { + x += ","; + } + x += tl::to_string (i->n); + } + return x; +} + +template +static std::string l2s_nc (tl::slist &l) +{ + std::string x; + for (typename tl::slist::iterator i = l.begin (); i != l.end (); ++i) { + if (!x.empty ()) { + x += ","; + } + x += tl::to_string (i->n); + } + return x; +} + +TEST(1_Basic) +{ + obj_count = 0; + + { + MyClass1 c1 (-1); + tl::slist l1, l2; + + EXPECT_EQ (l1.empty (), true); + EXPECT_EQ (l1.size (), size_t (0)); + EXPECT_EQ (l2s (l1), ""); + + l1.push_back (MyClass1 (17)); + EXPECT_EQ (l1.empty (), false); + EXPECT_EQ (l1.size (), size_t (1)); + EXPECT_EQ (l2s (l1), "17"); + + l1.push_back (MyClass1 (42)); + l2 = l1; + tl::slist l3 (l2); + EXPECT_EQ (l1.empty (), false); + EXPECT_EQ (l1.size (), size_t (2)); + EXPECT_EQ (l2s (l1), "17,42"); + + l1.pop_front (); + EXPECT_EQ (l1.empty (), false); + EXPECT_EQ (l1.size (), size_t (1)); + EXPECT_EQ (l2s (l1), "42"); + + l1.clear (); + EXPECT_EQ (l1.empty (), true); + EXPECT_EQ (l1.size (), size_t (0)); + EXPECT_EQ (l2s (l1), ""); + + EXPECT_EQ (l2s (l2), "17,42"); + l2.pop_front (); + EXPECT_EQ (l2s (l2), "42"); + + l3.push_back (MyClass1 (2)); + l3.push_front (MyClass1 (1)); + EXPECT_EQ (l2s (l3), "1,17,42,2"); + EXPECT_EQ (l2s_nc (l3), "1,17,42,2"); + EXPECT_EQ (l3.size (), size_t (4)); + + l3.pop_front (); + EXPECT_EQ (l2s (l3), "17,42,2"); + EXPECT_EQ (l3.size (), size_t (3)); + + c1 = l3.front (); + EXPECT_EQ (c1.n, 17); + + c1 = l3.back (); + EXPECT_EQ (c1.n, 2); + + l3.pop_front (); + EXPECT_EQ (l2s (l3), "42,2"); + EXPECT_EQ (l3.size (), size_t (2)); + + l3.push_back (MyClass1 (1)); + EXPECT_EQ (l2s (l3), "42,2,1"); + EXPECT_EQ (l3.size (), size_t (3)); + + l3.swap (l2); + EXPECT_EQ (l2s (l2), "42,2,1"); + EXPECT_EQ (l2s (l3), "42"); + + l1.clear (); + l2.swap (l1); + EXPECT_EQ (l2s (l1), "42,2,1"); + EXPECT_EQ (l2s (l2), ""); + + l1.clear (); + l3.clear (); + + l2.swap (l1); + EXPECT_EQ (l2s (l1), ""); + EXPECT_EQ (l2s (l2), ""); + } + + EXPECT_EQ (obj_count, size_t (0)); +} + +TEST(2_SpliceAndMove) +{ + obj_count = 0; + + { + tl::slist l1, l2; + + l1.splice (l2); + EXPECT_EQ (l2s (l1), ""); + + l1.push_back (MyClass1 (17)); + l1.push_back (MyClass1 (42)); + + l1.splice (l2); + EXPECT_EQ (l2s (l1), "17,42"); + EXPECT_EQ (l2s (l2), ""); + l2.splice (l1); + EXPECT_EQ (l2s (l2), "17,42"); + EXPECT_EQ (l2s (l1), ""); + + l1.swap (l2); + + l2.push_back (MyClass1 (2)); + l2.push_back (MyClass1 (1)); + + l1.splice (l2); + EXPECT_EQ (l2s (l1), "17,42,2,1"); + EXPECT_EQ (l2s (l2), ""); + + l2 = std::move (l1); + EXPECT_EQ (l2s (l2), "17,42,2,1"); + EXPECT_EQ (l2s (l1), ""); + + l1 = tl::slist (std::move (l2)); + EXPECT_EQ (l2s (l1), "17,42,2,1"); + EXPECT_EQ (l2s (l2), ""); + } + + EXPECT_EQ (obj_count, size_t (0)); +} diff --git a/src/tl/unit_tests/unit_tests.pro b/src/tl/unit_tests/unit_tests.pro index 692ba586e..c648dcb1b 100644 --- a/src/tl/unit_tests/unit_tests.pro +++ b/src/tl/unit_tests/unit_tests.pro @@ -39,6 +39,7 @@ SOURCES = \ tlThreadsTests.cc \ tlUniqueIdTests.cc \ tlListTests.cc \ + tlSListTests.cc \ tlEquivalenceClustersTests.cc \ tlUniqueNameTests.cc \ tlGlobPatternTests.cc \