From 82b30303525a2cb516f67b37b977cdf3aabc1ee5 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 6 Aug 2024 18:19:31 +0200 Subject: [PATCH] const versions of Layout#cell and Layout#top_cell(s) --- src/db/db/gsiDeclDbLayout.cc | 78 ++++++++++++++++++++++++++++++++- testdata/python/dbLayoutTest.py | 14 ++++++ testdata/ruby/dbLayoutTests2.rb | 10 +++++ 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/db/db/gsiDeclDbLayout.cc b/src/db/db/gsiDeclDbLayout.cc index 751c4152e..3edf80298 100644 --- a/src/db/db/gsiDeclDbLayout.cc +++ b/src/db/db/gsiDeclDbLayout.cc @@ -854,6 +854,11 @@ static db::Cell *cell_from_index (db::Layout *ly, db::cell_index_type ci) return &ly->cell (ci); } +static const db::Cell *cell_from_index_const (const db::Layout *layout, db::cell_index_type ci) +{ + return cell_from_index (const_cast (layout), ci); +} + static db::Cell *cell_from_name (db::Layout *ly, const std::string &name) { std::pair cn = ly->cell_by_name (name.c_str ()); @@ -864,6 +869,11 @@ static db::Cell *cell_from_name (db::Layout *ly, const std::string &name) } } +static const db::Cell *cell_from_name_const (const db::Layout *layout, const std::string &name) +{ + return cell_from_name (const_cast (layout), name); +} + static std::vector cells_from_name (db::Layout *layout, const std::string &filter) { tl::GlobPattern gp (filter); @@ -880,6 +890,12 @@ static std::vector cells_from_name (db::Layout *layout, const std::s return result; } +static std::vector cells_from_name_const (const db::Layout *layout, const std::string &filter) +{ + std::vector tcs = cells_from_name (const_cast (layout), filter); + return std::vector (tcs.begin (), tcs.end ()); +} + static std::vector top_cells (db::Layout *layout) { std::vector tc; @@ -891,6 +907,12 @@ static std::vector top_cells (db::Layout *layout) return tc; } +static std::vector top_cells_const (const db::Layout *layout) +{ + std::vector tcs = top_cells (const_cast (layout)); + return std::vector (tcs.begin (), tcs.end ()); +} + static db::Cell *top_cell (db::Layout *layout) { db::Cell *tc = 0; @@ -906,6 +928,11 @@ static db::Cell *top_cell (db::Layout *layout) return tc; } +static const db::Cell *top_cell_const (const db::Layout *layout) +{ + return top_cell (const_cast (layout)); +} + static db::Cell *create_cell (db::Layout *layout, const std::string &name) { return &layout->cell (layout->add_cell (name.c_str ())); @@ -1328,7 +1355,16 @@ Class decl_Layout ("db", "Layout", "\n" "This method has been introduced in version 0.23." ) + - gsi::method_ext ("top_cells", &top_cells, + gsi::method_ext ("top_cell", &top_cell_const, + "@brief Returns the top cell object (const version)\n" + "@return The \\Cell object of the top cell\n" + "If the layout has a single top cell, this method returns the top cell's \\Cell object.\n" + "If the layout does not have a top cell, this method returns \"nil\". If the layout has multiple\n" + "top cells, this method raises an error.\n" + "\n" + "This variant has been introduced in version 0.29.6." + ) + + gsi::method_ext ("top_cells", &top_cells, "@brief Returns the top cell objects\n" "@return The \\Cell objects of the top cells\n" "This method returns and array of \\Cell objects representing the top cells of the layout.\n" @@ -1336,6 +1372,14 @@ Class decl_Layout ("db", "Layout", "\n" "This method has been introduced in version 0.23." ) + + gsi::method_ext ("top_cells", &top_cells_const, + "@brief Returns the top cell objects (const version)\n" + "@return The \\Cell objects of the top cells\n" + "This method returns and array of \\Cell objects representing the top cells of the layout.\n" + "This array can be empty, if the layout does not have a top cell (i.e. no cell at all).\n" + "\n" + "This variant has been introduced in version 0.29.6." + ) + gsi::method ("has_cell?", &db::Layout::has_cell, gsi::arg ("name"), "@brief Returns true if a cell with a given name exists\n" "Returns true, if the layout has a cell with the given name" @@ -1780,6 +1824,16 @@ Class decl_Layout ("db", "Layout", "\n" "This method has been introduced in version 0.27.3.\n" ) + + gsi::method_ext ("cells", &cells_from_name_const, gsi::arg ("name_filter"), + "@brief Gets the cell objects for a given name filter (const version)\n" + "\n" + "@param name_filter The cell name filter (glob pattern)\n" + "@return A list of \\Cell object of the cells matching the pattern\n" + "\n" + "This method has been introduced in version 0.27.3.\n" + "\n" + "This variant has been introduced in version 0.29.6." + ) + gsi::method_ext ("cell", &cell_from_name, gsi::arg ("name"), "@brief Gets a cell object from the cell name\n" "\n" @@ -1789,6 +1843,17 @@ Class decl_Layout ("db", "Layout", "If name is not a valid cell name, this method will return \"nil\".\n" "This method has been introduced in version 0.23 and replaces \\cell_by_name.\n" ) + + gsi::method_ext ("cell", &cell_from_name_const, gsi::arg ("name"), + "@brief Gets a cell object from the cell name (const version)\n" + "\n" + "@param name The cell name\n" + "@return A reference to the cell (a \\Cell object)\n" + "\n" + "If name is not a valid cell name, this method will return \"nil\".\n" + "This method has been introduced in version 0.23 and replaces \\cell_by_name.\n" + "\n" + "This variant has been introduced in version 0.29.6." + ) + gsi::method_ext ("cell", &cell_from_index, gsi::arg ("i"), "@brief Gets a cell object from the cell index\n" "\n" @@ -1798,6 +1863,17 @@ Class decl_Layout ("db", "Layout", "If the cell index is not a valid cell index, this method will raise an error. " "Use \\is_valid_cell_index? to test whether a given cell index is valid.\n" ) + + gsi::method_ext ("cell", &cell_from_index_const, gsi::arg ("i"), + "@brief Gets a cell object from the cell index (const version)\n" + "\n" + "@param i The cell index\n" + "@return A reference to the cell (a \\Cell object)\n" + "\n" + "If the cell index is not a valid cell index, this method will raise an error. " + "Use \\is_valid_cell_index? to test whether a given cell index is valid.\n" + "\n" + "This variant has been introduced in version 0.29.6." + ) + gsi::iterator ("each_cell", (db::Layout::iterator (db::Layout::*) ()) &db::Layout::begin, (db::Layout::iterator (db::Layout::*) ()) &db::Layout::end, "@brief Iterates the unsorted cell list\n" ) + diff --git a/testdata/python/dbLayoutTest.py b/testdata/python/dbLayoutTest.py index b0e535b7a..1e01a3533 100644 --- a/testdata/python/dbLayoutTest.py +++ b/testdata/python/dbLayoutTest.py @@ -75,13 +75,20 @@ class DBLayoutTest(unittest.TestCase): self.assertEqual( ly.cell_name(ci), "new_cell" ) self.assertEqual( ly.cell_by_name("new_cell"), ci ) + self.assertEqual( ly.cell(ci).cell_index(), ci ) self.assertEqual( ly.cell("new_cell").name, "new_cell" ) self.assertEqual( repr(ly.cell("x")), "None" ) + lyc = ly.dup() + self.assertEqual( lyc._to_const_object().cell("new_cell").name, "new_cell" ) + self.assertEqual( lyc._to_const_object().cell(ci).cell_index(), ci ) ci2 = ly.add_cell( "new_cell_b" ) self.assertEqual( ly.cells(), 2 ) self.assertEqual( ly.cell_by_name("new_cell_b"), ci2 ) + self.assertEqual( sorted([ c.name for c in ly.cells("new*") ]), ['new_cell', 'new_cell_b'] ) self.assertEqual( ci != ci2, True ) + lyc = ly.dup() + self.assertEqual( sorted([ c.name for c in lyc._to_const_object().cells("new*") ]), ['new_cell', 'new_cell_b'] ) ly.rename_cell( ci2, "x" ) self.assertEqual( ly.cell_by_name("x"), ci2 ) @@ -918,6 +925,8 @@ class DBLayoutTest(unittest.TestCase): tc.append(l.cell(t).name) self.assertEqual(",".join(tc), "c0") self.assertEqual(l.top_cell().name, "c0") + lc = l.dup() + self.assertEqual(lc._to_const_object().top_cell().name, "c0") # const version tc = [] for t in l.top_cells(): tc.append(t.name) @@ -939,6 +948,11 @@ class DBLayoutTest(unittest.TestCase): for t in l.top_cells(): tc.append(t.name) self.assertEqual(",".join(tc), "c0,c1") + tc = [] + lc = l.dup() + for t in lc._to_const_object().top_cells(): # const version + tc.append(t.name) + self.assertEqual(",".join(tc), "c0,c1") c2 = l.create_cell("c1") self.assertEqual(c2.name, "c1$1") diff --git a/testdata/ruby/dbLayoutTests2.rb b/testdata/ruby/dbLayoutTests2.rb index fc1be5ac6..111d0e9f8 100644 --- a/testdata/ruby/dbLayoutTests2.rb +++ b/testdata/ruby/dbLayoutTests2.rb @@ -83,14 +83,21 @@ class DBLayoutTests2_TestClass < TestBase assert_equal( ly.cell_name(ci), "new_cell" ) assert_equal( ly.cell_by_name("new_cell"), ci ) + assert_equal( ly.cell(ci).cell_index, ci ) assert_equal( ly.cells("A*"), [] ) assert_equal( ly.cell("new_cell").name, "new_cell" ) assert_equal( ly.cell("x").inspect, "nil" ) + lyc = ly.dup + assert_equal( lyc._to_const_object.cell("new_cell").name, "new_cell" ) + assert_equal( lyc._to_const_object.cell(ci).cell_index, ci ) ci2 = ly.add_cell( "new_cell_b" ) assert_equal( ly.cells, 2 ) assert_equal( ly.cell_by_name("new_cell_b"), ci2 ) + assert_equal( ly.cells("new*").collect { |c| c.name }.sort, ['new_cell', 'new_cell_b'] ) assert_equal( ci != ci2, true ) + lyc = ly.dup + assert_equal( lyc._to_const_object.cells("new*").collect { |c| c.name }.sort, ['new_cell', 'new_cell_b'] ) ly.rename_cell( ci2, "x" ) assert_equal( ly.cell_by_name("x"), ci2 ) @@ -900,6 +907,9 @@ class DBLayoutTests2_TestClass < TestBase assert_equal(tc.collect { |s| s.to_s }.join(","), "c0") assert_equal(l.top_cell.name, "c0") assert_equal(l.top_cells.collect { |t| t.name }.join(","), "c0") + lc = l.dup + assert_equal(lc._to_const_object.top_cell.name, "c0") + assert_equal(lc._to_const_object.top_cells.collect { |t| t.name }.join(","), "c0") c1 = l.create_cell("c1") assert_equal(c1.name, "c1")