CellMapping: documentation, some convenience bindings

This commit is contained in:
Matthias Koefferlein 2022-08-27 15:38:10 +02:00
parent 7c776779a6
commit f590d39c19
2 changed files with 328 additions and 34 deletions

View File

@ -36,9 +36,98 @@ static db::cell_index_type drop_cell_const ()
return db::DropCell;
}
static void create_single_mapping (db::CellMapping *cm, db::Cell &a, const db::Cell &b)
{
tl_assert (a.layout () != 0);
tl_assert (b.layout () != 0);
cm->create_single_mapping (*a.layout (), a.cell_index (), *b.layout(), b.cell_index ());
}
static std::vector<db::cell_index_type> create_single_mapping_full (db::CellMapping *cm, db::Cell &a, const db::Cell &b)
{
tl_assert (a.layout () != 0);
tl_assert (b.layout () != 0);
return cm->create_single_mapping_full (*a.layout (), a.cell_index (), *b.layout(), b.cell_index ());
}
static std::vector<db::cell_index_type> create_multi_mapping_gen (db::CellMapping *cm, const std::vector<db::Cell *> &a, const std::vector<const db::Cell *> &b, bool full)
{
db::Layout *lya = 0;
const db::Layout *lyb = 0;
std::vector<db::cell_index_type> cia, cib;
for (auto i = a.begin (); i != a.end (); ++i) {
tl_assert (*i != 0);
tl_assert ((*i)->layout () != 0);
cia.push_back ((*i)->cell_index ());
if (lya == 0) {
lya = (*i)->layout ();
} else if (lya != (*i)->layout ()) {
throw tl::Exception (tl::to_string (tr ("First cell array contains cells from different layouts")));
}
}
for (auto i = b.begin (); i != b.end (); ++i) {
tl_assert (*i != 0);
tl_assert ((*i)->layout () != 0);
cib.push_back ((*i)->cell_index ());
if (lyb == 0) {
lyb = (*i)->layout ();
} else if (lyb != (*i)->layout ()) {
throw tl::Exception (tl::to_string (tr ("Second cell array contains cells from different layouts")));
}
}
if (full) {
return cm->create_multi_mapping_full (*lya, cia, *lyb, cib);
} else {
cm->create_multi_mapping (*lya, cia, *lyb, cib);
return std::vector<db::cell_index_type> ();
}
}
static std::vector<db::cell_index_type> create_multi_mapping_full (db::CellMapping *cm, const std::vector<db::Cell *> &a, const std::vector<const db::Cell *> &b)
{
return create_multi_mapping_gen (cm, a, b, true);
}
static void create_multi_mapping (db::CellMapping *cm, const std::vector<db::Cell *> &a, const std::vector<const db::Cell *> &b)
{
create_multi_mapping_gen (cm, a, b, false);
}
static void create_from_geometry (db::CellMapping *cm, db::Cell &a, const db::Cell &b)
{
tl_assert (a.layout () != 0);
tl_assert (b.layout () != 0);
return cm->create_from_geometry (*a.layout (), a.cell_index (), *b.layout(), b.cell_index ());
}
static std::vector<db::cell_index_type> create_from_geometry_full (db::CellMapping *cm, db::Cell &a, const db::Cell &b)
{
tl_assert (a.layout () != 0);
tl_assert (b.layout () != 0);
return cm->create_from_geometry_full (*a.layout (), a.cell_index (), *b.layout(), b.cell_index ());
}
static void create_from_names (db::CellMapping *cm, db::Cell &a, const db::Cell &b)
{
tl_assert (a.layout () != 0);
tl_assert (b.layout () != 0);
return cm->create_from_names (*a.layout (), a.cell_index (), *b.layout(), b.cell_index ());
}
static std::vector<db::cell_index_type> create_from_names_full (db::CellMapping *cm, db::Cell &a, const db::Cell &b)
{
tl_assert (a.layout () != 0);
tl_assert (b.layout () != 0);
return cm->create_from_names_full (*a.layout (), a.cell_index (), *b.layout(), b.cell_index ());
}
Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
gsi::method ("DropCell", &drop_cell_const,
"@brief A constant indicating the reques to drop a cell\n"
"@brief A constant indicating the request to drop a cell\n"
"\n"
"If used as a pseudo-target for the cell mapping, this index indicates "
"that the cell shall be dropped rather than created on the target side "
@ -65,9 +154,19 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.23."
) +
gsi::method ("for_single_cell_full", &db::CellMapping::create_single_mapping_full, gsi::arg ("layout_a"), gsi::arg ("cell_index_a"), gsi::arg ("layout_b"), gsi::arg ("cell_index_b"),
gsi::method_ext ("for_single_cell", &create_single_mapping, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping for top-level identity\n"
"\n"
"@param cell_a The target cell.\n"
"@param cell_b The source cell.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("for_single_cell_full", &db::CellMapping::create_single_mapping_full, gsi::arg ("layout_a"), gsi::arg ("cell_index_a"), gsi::arg ("layout_b"), gsi::arg ("cell_index_b"),
"@brief Initializes the cell mapping for top-level identity in full mapping mode\n"
"\n"
"@param layout_a The target layout.\n"
"@param cell_index_a The index of the target cell.\n"
"@param layout_b The source layout.\n"
@ -80,6 +179,16 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.23."
) +
gsi::method_ext ("for_single_cell_full", &create_single_mapping_full, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping for top-level identity in full mapping mode\n"
"\n"
"@param cell_a The target cell.\n"
"@param cell_b The source cell.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("for_multi_cells", &db::CellMapping::create_multi_mapping, gsi::arg ("layout_a"), gsi::arg ("cell_indexes_a"), gsi::arg ("layout_b"), gsi::arg ("cell_indexes_b"),
"@brief Initializes the cell mapping for top-level identity\n"
"\n"
@ -97,9 +206,19 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.27."
) +
gsi::method ("for_multi_cells_full", &db::CellMapping::create_multi_mapping_full, gsi::arg ("layout_a"), gsi::arg ("cell_indexes_a"), gsi::arg ("layout_b"), gsi::arg ("cell_indexes_b"),
gsi::method_ext ("for_multi_cells", &create_multi_mapping, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping for top-level identity\n"
"\n"
"@param cell_a A list of target cells.\n"
"@param cell_b A list of source cells.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("for_multi_cells_full", &db::CellMapping::create_multi_mapping_full, gsi::arg ("layout_a"), gsi::arg ("cell_indexes_a"), gsi::arg ("layout_b"), gsi::arg ("cell_indexes_b"),
"@brief Initializes the cell mapping for top-level identity in full mapping mode\n"
"\n"
"@param layout_a The target layout.\n"
"@param cell_indexes_a A list of cell indexes for the target cells.\n"
"@param layout_b The source layout.\n"
@ -112,6 +231,16 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.27."
) +
gsi::method_ext ("for_multi_cells_full", &create_multi_mapping_full, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping for top-level identity in full mapping mode\n"
"\n"
"@param cell_a A list of target cells.\n"
"@param cell_b A list of source cells.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("from_geometry_full", &db::CellMapping::create_from_geometry_full, gsi::arg ("layout_a"), gsi::arg ("cell_index_a"), gsi::arg ("layout_b"), gsi::arg ("cell_index_b"),
"@brief Initializes the cell mapping using the geometrical identity in full mapping mode\n"
"\n"
@ -132,6 +261,16 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.23."
) +
gsi::method_ext ("from_geometry_full", &create_from_geometry_full, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping using the geometrical identity in full mapping mode\n"
"\n"
"@param cell_a The target cell.\n"
"@param cell_b The source cell.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("from_geometry", &db::CellMapping::create_from_geometry, gsi::arg ("layout_a"), gsi::arg ("cell_index_a"), gsi::arg ("layout_b"), gsi::arg ("cell_index_b"),
"@brief Initializes the cell mapping using the geometrical identity\n"
"\n"
@ -147,6 +286,16 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.23."
) +
gsi::method_ext ("from_geometry", &create_from_geometry, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping using the geometrical identity\n"
"\n"
"@param cell_a The target cell.\n"
"@param cell_b The source cell.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("from_names", &db::CellMapping::create_from_names, gsi::arg ("layout_a"), gsi::arg ("cell_index_a"), gsi::arg ("layout_b"), gsi::arg ("cell_index_b"),
"@brief Initializes the cell mapping using the name identity\n"
"\n"
@ -161,6 +310,16 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.23."
) +
gsi::method_ext ("from_names", &create_from_names, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping using the name identity\n"
"\n"
"@param cell_a The target cell.\n"
"@param cell_b The source cell.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("from_names_full", &db::CellMapping::create_from_names_full, gsi::arg ("layout_a"), gsi::arg ("cell_index_a"), gsi::arg ("layout_b"), gsi::arg ("cell_index_b"),
"@brief Initializes the cell mapping using the name identity in full mapping mode\n"
"\n"
@ -180,7 +339,17 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"This method has been introduced in version 0.23."
) +
gsi::method ("clear", &db::CellMapping::clear,
gsi::method_ext ("from_names_full", &create_from_names_full, gsi::arg ("cell_a"), gsi::arg ("cell_b"),
"@brief Initializes the cell mapping using the name identity in full mapping mode\n"
"\n"
"@param cell_a The target cell.\n"
"@param cell_b The source cell.\n"
"@return A list of indexes of cells created.\n"
"\n"
"This is a convenience version which uses cell references instead of layout/cell index combinations. "
"It has been introduced in version 0.28."
) +
gsi::method ("clear", &db::CellMapping::clear,
"@brief Clears the mapping.\n"
"\n"
"This method has been introduced in version 0.23."
@ -208,7 +377,6 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
gsi::method ("has_mapping?", &db::CellMapping::has_mapping, gsi::arg ("cell_index_b"),
"@brief Returns as value indicating whether a cell of layout_b has a mapping to a layout_a cell.\n"
"\n"
"\n"
"@param cell_index_b The index of the cell in layout_b whose mapping is requested.\n"
"@return true, if the cell has a mapping\n"
"\n"
@ -231,15 +399,27 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"the mapping of cells of a source layout B to a target layout A. The cell mapping object "
"is basically a table associating a cell in layout B with a cell in layout A.\n"
"\n"
"The cell mapping is of particular interest for providing the cell mapping recipe in "
"\\Cell#copy_tree_shapes or \\Cell#move_tree_shapes.\n"
"\n"
"The mapping object is used to create and hold that table. There are three basic modes in which "
"a table can be generated:\n"
"\n"
"@ul\n"
" @li Top-level identity @/li\n"
" @li Geometrical identity @/li\n"
" @li Name identity @/li\n"
" @li Top-level identity (\\for_single_cell and \\for_single_cell_full) @/li\n"
" @li Top-level identify for multiple cells (\\for_multi_cells_full and \\for_multi_cells_full) @/li\n"
" @li Geometrical identity (\\from_geometry and \\from_geometry_full)@/li\n"
" @li Name identity (\\from_names and \\from_names_full) @/li\n"
"@/ul\n"
"\n"
"'full' refers to the way cells are treated which are not mentioned. In the 'full' versions, "
"cells for which no mapping is established explicitly - specifically all child cells in top-level identity modes - "
"are created in the target layout and instantiated according to their source layout hierarchy. Then, these new "
"cells become targets of the respective source cells. "
"In the plain version (without 'full' cells), no additional cells are created. For the case of \\Layout#copy_tree_shapes "
"cells not explicitly mapped are flattened. Hence for example, \\for_single_cell will flatten all children of the source cell during "
"\\Layout#copy_tree_shapes or \\Layout#move_tree_shapes.\n"
"\n"
"Top-level identity means that only one cell (the top cell) is regarded identical. All child cells are "
"not considered identical. In full mode (see below), this will create a new, identical cell tree "
"below the top cell in layout A.\n"
@ -264,10 +444,42 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\\from_names_full or \\from_geometry_full. These versions will create new cells and their corresponding "
"instances in the target layout if no suitable target cell is found.\n"
"\n"
"CellMapping objects play a role mainly in the hierarchical copy or move operations of \\Layout. "
"However, use is not restricted to these applications.\n"
"This is a simple example for a cell mapping preserving the hierarchy of the source cell and creating "
"a hierarchy copy in the top cell of the target layout ('hierarchical merge'):\n"
"\n"
"Here is one example for using \\CellMapping. It extracts cells 'A', 'B' and 'C' from one layout "
"@code\n"
"cell_names = [ \"A\", \"B\", \"C\" ]\n"
"\n"
"source = RBA::Layout::new\n"
"source.read(\"input.gds\")\n"
"\n"
"target = RBA::Layout::new\n"
"target_top = target.create_cell(\"IMPORTED\")\n"
"\n"
"cm = RBA::CellMapping::new\n"
"# Copies the source layout hierarchy into the target top cell:\n"
"cm.for_single_cell_full(target_top, source.top_cell)\n"
"target.copy_tree_shapes(source, cm)\n"
"@/code\n"
"\n"
"Without 'full', the effect is move-with-flattening (note we're using 'move' in this example):\n"
"\n"
"@code\n"
"cell_names = [ \"A\", \"B\", \"C\" ]\n"
"\n"
"source = RBA::Layout::new\n"
"source.read(\"input.gds\")\n"
"\n"
"target = RBA::Layout::new\n"
"target_top = target.create_cell(\"IMPORTED\")\n"
"\n"
"cm = RBA::CellMapping::new\n"
"# Flattens the source layout hierarchy into the target top cell:\n"
"cm.for_single_cell(target_top, source.top_cell)\n"
"target.move_tree_shapes(source, cm)\n"
"@/code\n"
"\n"
"This is another example for using \\CellMapping in multiple top cell identity mode. It extracts cells 'A', 'B' and 'C' from one layout "
"and copies them to another. It will also copy all shapes and all child cells. Child cells which are "
"shared between the three initial cells will be shared in the target layout too.\n"
"\n"
@ -279,11 +491,11 @@ Class<db::CellMapping> decl_CellMapping ("db", "CellMapping",
"\n"
"target = RBA::Layout::new\n"
"\n"
"source_cells = cell_names.collect { |n| source.cell_by_name(n).cell_index }\n"
"target_cells = cell_names.collect { |n| target.create_cell(n).cell_index }\n"
"source_cells = cell_names.collect { |n| source.cell_by_name(n) }\n"
"target_cells = cell_names.collect { |n| target.create_cell(n) }\n"
"\n"
"cm = RBA::CellMapping::new\n"
"cm.for_multi_cells_full(source, source_cells, target, target_cells)\n"
"cm.for_multi_cells_full(target_cells, source_cells)\n"
"target.copy_tree_shapes(source, cm)\n"
"@/code\n"
);

View File

@ -25,14 +25,14 @@ load("test_prologue.rb")
def mapping_to_s(ly1, ly2, cm)
r = ""
ly1.each_cell_top_down do |c|
s = ly1.cell(c).name
ly2.each_cell_top_down do |c|
s = ly2.cell(c).name
if cm.has_mapping?(c)
t = cm.cell_mapping(c)
if t == RBA::CellMapping::DropCell
s += "=>(0)"
else
s += "=>" + ly2.cell(t).name
s += "=>" + ly1.cell(t).name
end
end
r == "" || (r += ";")
@ -44,14 +44,14 @@ end
def mapping_to_s_from_table(ly1, ly2, cm)
table = cm.table
r = ""
ly1.each_cell_top_down do |c|
s = ly1.cell(c).name
ly2.each_cell_top_down do |c|
s = ly2.cell(c).name
if table[c]
t = table[c]
if t == RBA::CellMapping::DropCell
s += "=>(0)"
else
s += "=>" + ly2.cell(t).name
s += "=>" + ly1.cell(t).name
end
end
r == "" || (r += ";")
@ -120,12 +120,21 @@ class DBCellMapping_TestClass < TestBase
mp = RBA::CellMapping::new
mp.from_names(ly1, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
assert_equal(mapping_to_s_from_table(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
assert_equal(mapping_to_s_from_table(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
mp = RBA::CellMapping::new
mp.from_names(ly1.cell(top1), ly2.cell(top2))
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
assert_equal(mapping_to_s_from_table(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
mp = RBA::CellMapping::new
mp.from_geometry(ly1, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
mp = RBA::CellMapping::new
mp.from_geometry(ly1.cell(top1), ly2.cell(top2))
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
ly = RBA::Layout::new
@ -150,17 +159,23 @@ class DBCellMapping_TestClass < TestBase
mp = RBA::CellMapping::new
mp.from_names(ly1, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;cx")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;cx")
ly1dup = ly1.dup
mp = RBA::CellMapping::new
nc = mp.from_names_full(ly1dup, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1dup, mp), "c0;c2=>c2;c1=>c1;cx=>cx")
assert_equal(mapping_to_s(ly1dup, ly2, mp), "c0;c2=>c2;c1=>c1;cx=>cx")
assert_equal(nc.inspect, "[3]")
ly1dup = ly1.dup
mp = RBA::CellMapping::new
nc = mp.from_names_full(ly1dup.cell(top1), ly2.cell(top2))
assert_equal(mapping_to_s(ly1dup, ly2, mp), "c0;c2=>c2;c1=>c1;cx=>cx")
assert_equal(nc.inspect, "[3]")
mp = RBA::CellMapping::new
mp.from_geometry(ly1, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;cx=>c3")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;cx=>c3")
ly = RBA::Layout::new
@ -185,23 +200,29 @@ class DBCellMapping_TestClass < TestBase
mp = RBA::CellMapping::new
mp.from_names(ly1, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3")
mp = RBA::CellMapping::new
mp.from_geometry(ly1, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>c2;c1=>c1;c3")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>c2;c1=>c1;c3")
ly1dup = ly1.dup
mp = RBA::CellMapping::new
nc = mp.from_geometry_full(ly1dup, top1, ly2, top2)
assert_equal(mapping_to_s(ly2, ly1dup, mp), "c0;c2=>c2;c1=>c1;c3=>c3$1")
assert_equal(mapping_to_s(ly1dup, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3$1")
assert_equal(nc.inspect, "[3]")
ly1dup = ly1.dup
mp = RBA::CellMapping::new
nc = mp.from_geometry_full(ly1dup.cell(top1), ly2.cell(top2))
assert_equal(mapping_to_s(ly1dup, ly2, mp), "c0;c2=>c2;c1=>c1;c3=>c3$1")
assert_equal(nc.inspect, "[3]")
mp.clear
mp.from_geometry(ly1, top1, ly2, top2)
mp.map(ci2, RBA::CellMapping::DropCell)
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>(0);c1=>c1;c3")
assert_equal(mapping_to_s_from_table(ly2, ly1, mp), "c0;c2=>(0);c1=>c1;c3")
assert_equal(mapping_to_s(ly1, ly2, mp), "c0;c2=>(0);c1=>c1;c3")
assert_equal(mapping_to_s_from_table(ly1, ly2, mp), "c0;c2=>(0);c1=>c1;c3")
end
@ -223,6 +244,53 @@ class DBCellMapping_TestClass < TestBase
a1.insert(RBA::CellInstArray::new(a3.cell_index, RBA::Trans::new))
a2.insert(RBA::CellInstArray::new(a4.cell_index, RBA::Trans::new))
ly_target = RBA::Layout::new
b0 = ly_target.create_cell("b0")
cm = RBA::CellMapping::new
cm.for_single_cell(ly_target, b0.cell_index, ly, a1.cell_index)
assert_equal(mapping_to_s(ly_target, ly, cm), "a0;a1=>b0;a2;a3;a4;a5")
cm = RBA::CellMapping::new
cm.for_single_cell(b0, a1)
assert_equal(mapping_to_s(ly_target, ly, cm), "a0;a1=>b0;a2;a3;a4;a5")
lytdup = ly_target.dup
cm = RBA::CellMapping::new
nc = cm.for_single_cell_full(lytdup, b0.cell_index, ly, a1.cell_index)
assert_equal(nc.inspect, "[1, 2, 3]")
assert_equal(mapping_to_s(lytdup, ly, cm), "a0;a1=>b0;a2;a3=>a3;a4=>a4;a5=>a5")
lytdup = ly_target.dup
cm = RBA::CellMapping::new
nc = cm.for_single_cell_full(lytdup.cell(b0.cell_index), a1)
assert_equal(nc.inspect, "[1, 2, 3]")
assert_equal(mapping_to_s(lytdup, ly, cm), "a0;a1=>b0;a2;a3=>a3;a4=>a4;a5=>a5")
end
def test_3
ly = RBA::Layout::new
a0 = ly.create_cell("a0")
a1 = ly.create_cell("a1")
a2 = ly.create_cell("a2")
a3 = ly.create_cell("a3")
a4 = ly.create_cell("a4")
a5 = ly.create_cell("a5")
a3.insert(RBA::CellInstArray::new(a4.cell_index, RBA::Trans::new))
a3.insert(RBA::CellInstArray::new(a5.cell_index, RBA::Trans::new))
a1.insert(RBA::CellInstArray::new(a4.cell_index, RBA::Trans::new))
a1.insert(RBA::CellInstArray::new(a3.cell_index, RBA::Trans::new))
a2.insert(RBA::CellInstArray::new(a4.cell_index, RBA::Trans::new))
ly_target = RBA::Layout::new
b0 = ly_target.create_cell("b0")
b1 = ly_target.create_cell("b1")
@ -231,12 +299,26 @@ class DBCellMapping_TestClass < TestBase
cm = RBA::CellMapping::new
cm.for_multi_cells(ly_target, [ b0, b1, b2 ].collect { |c| c.cell_index }, ly, [ a0, a1, a2 ].collect { |c| c.cell_index })
assert_equal(mapping_to_s(ly_target, ly, cm), "b0=>a0;b1=>a1;b2=>a2")
assert_equal(mapping_to_s(ly_target, ly, cm), "a0=>b0;a1=>b1;a2=>b2;a3;a4;a5")
cm = RBA::CellMapping::new
cm.for_multi_cells_full(ly_target, [ b0, b1, b2 ].collect { |c| c.cell_index }, ly, [ a0, a1, a2 ].collect { |c| c.cell_index })
cm.for_multi_cells([ b0, b1, b2 ], [ a0, a1, a2 ])
assert_equal(mapping_to_s(ly_target, ly, cm), "b0=>a0;b1=>a1;b2=>a2;a3=>a3;a4=>a4;a5=>a5")
assert_equal(mapping_to_s(ly_target, ly, cm), "a0=>b0;a1=>b1;a2=>b2;a3;a4;a5")
lytdup = ly_target.dup
cm = RBA::CellMapping::new
nc = cm.for_multi_cells_full(lytdup, [ b0, b1, b2 ].collect { |c| c.cell_index }, ly, [ a0, a1, a2 ].collect { |c| c.cell_index })
assert_equal(nc.inspect, "[3, 4, 5]")
assert_equal(mapping_to_s(lytdup, ly, cm), "a0=>b0;a1=>b1;a2=>b2;a3=>a3;a4=>a4;a5=>a5")
lytdup = ly_target.dup
cm = RBA::CellMapping::new
cm.for_multi_cells_full([ b0, b1, b2 ].collect { |c| lytdup.cell(c.cell_index) }, [ a0, a1, a2 ])
assert_equal(nc.inspect, "[3, 4, 5]")
assert_equal(mapping_to_s(lytdup, ly, cm), "a0=>b0;a1=>b1;a2=>b2;a3=>a3;a4=>a4;a5=>a5")
end