/* KLayout Layout Viewer Copyright (C) 2006-2025 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 "tlAlgorithm.h" #include "tlString.h" #include "tlTimer.h" #include "tlUnitTest.h" #include #include #include #include std::string to_string (const std::vector &v) { std::string t; for (std::vector::const_iterator s = v.begin (); s != v.end (); ++s) { t += *s; t += " "; } return t; } class SimpleString { public: ~SimpleString () { delete [] m_cp; } SimpleString () { m_cp = new char [2]; strcpy (m_cp, ""); } SimpleString &operator= (const SimpleString &d) { if (this != &d) { delete [] m_cp; m_cp = new char [strlen (d.m_cp) + 1]; strcpy (m_cp, d.m_cp); } return *this; } SimpleString (const SimpleString &d) { m_cp = new char [strlen (d.m_cp) + 1]; strcpy (m_cp, d.m_cp); } SimpleString (const std::string &cp) { m_cp = new char [strlen (cp.c_str ()) + 1]; strcpy (m_cp, cp.c_str ()); } SimpleString (const char *cp) { m_cp = new char [strlen (cp) + 1]; strcpy (m_cp, cp); } bool operator< (const SimpleString &d) const { return strcmp (m_cp, d.m_cp) < 0; } bool operator== (const SimpleString &d) const { return strcmp (m_cp, d.m_cp) == 0; } const char *c_str () const { return m_cp; } private: char *m_cp; }; std::ostream &operator<< (std::ostream &os, const SimpleString &s) { os << s.c_str (); return os; } struct test_compare { bool operator() (const SimpleString &a, const SimpleString &b) const { return b < a; } bool operator() (const std::string &a, const std::string &b) const { return b < a; } bool operator() (int a, int b) const { return b < a; } }; TEST(1) { std::vector v; v.push_back ("d"); v.push_back ("a"); v.push_back ("bx"); v.push_back ("ba"); tl::sort (v.begin (), v.end ()); EXPECT_EQ (to_string (v), "a ba bx d "); tl::sort (v.begin (), v.end (), test_compare ()); EXPECT_EQ (to_string (v), "d bx ba a "); } TEST(2) { std::vector v; int n = 0x100000; v.reserve (n); for (int i = 0; i < n; ++i) { v.push_back (tl::sprintf ("%06x", i ^ 0x43abc)); // "unsorted" } { tl::SelfTimer timer ("sorting to reverse"); tl::sort (v.begin (), v.end (), test_compare ()); } { tl::SelfTimer timer ("sorting"); tl::sort (v.begin (), v.end ()); } for (int i = 0; i < n; ++i) { EXPECT_EQ (v[i], tl::sprintf ("%06x", i)); } { tl::SelfTimer timer ("sorting again"); tl::sort (v.begin (), v.end ()); } v.clear (); v.reserve (n); for (int i = 0; i < n; ++i) { v.push_back (tl::sprintf ("%06x", i ^ 0x43abc)); // "unsorted" } { tl::SelfTimer timer ("std::sorting to reverse"); std::sort (v.begin (), v.end (), test_compare ()); } { tl::SelfTimer timer ("std::sorting"); std::sort (v.begin (), v.end ()); } for (int i = 0; i < n; ++i) { EXPECT_EQ (v[i], tl::sprintf ("%06x", i)); } { tl::SelfTimer timer ("std::sorting again"); std::sort (v.begin (), v.end ()); } } TEST(3) { std::vector v; int n = 10000; v.reserve (n); for (int i = 0; i < n; ++i) { v.push_back (i); } { tl::SelfTimer timer ("sorting"); tl::sort (v.begin (), v.end (), test_compare ()); tl::sort (v.begin (), v.end ()); } for (int i = 0; i < n; ++i) { EXPECT_EQ (v[i], i); } }