klayout/src/db/unit_tests/dbRecursiveInstanceIterator...

622 lines
20 KiB
C++
Raw Normal View History

/*
KLayout Layout Viewer
Copyright (C) 2006-2021 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 "dbRecursiveInstanceIterator.h"
#include "dbRegion.h"
#include "dbLayoutDiff.h"
#include "tlString.h"
#include "tlUnitTest.h"
#include <vector>
std::string collect(db::RecursiveInstanceIterator &s, const db::Layout &layout)
{
std::string res;
while (! s.at_end ()) {
if (! res.empty ()) {
res += "/";
}
if (s.cell ()) {
res += std::string ("[") + layout.cell_name (s.cell ()->cell_index ()) + "]";
} else {
res += "[]";
}
res += s->inst_ptr.to_string (true);
++s;
}
return res;
}
std::string collect_with_copy(db::RecursiveInstanceIterator s, const db::Layout &layout)
{
s.reset ();
return collect (s, layout);
}
TEST(1)
{
db::Manager m (true);
db::Layout g (&m);
g.insert_layer (0);
g.insert_layer (1);
g.insert_layer (2);
db::Cell &c0 (g.cell (g.add_cell ()));
db::RecursiveInstanceIterator idef;
EXPECT_EQ (idef.at_end (), true);
EXPECT_EQ (collect (idef, g), "");
EXPECT_EQ (collect_with_copy (idef, g), "");
db::RecursiveInstanceIterator i00 (g, c0, db::Box (0, 0, 100, 100));
EXPECT_EQ (collect (i00, g), "");
EXPECT_EQ (collect_with_copy (i00, g), "");
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::RecursiveInstanceIterator i0 (g, c0, db::Box (0, 0, 100, 100));
EXPECT_EQ (collect (i0, g), "");
EXPECT_EQ (collect_with_copy (i0, g), "");
db::Box b (0, 100, 1000, 1200);
c0.shapes (0).insert (b);
c1.shapes (0).insert (b);
c2.shapes (0).insert (b);
c3.shapes (0).insert (b);
c0.shapes (2).insert (b);
c0.shapes (2).insert (b.moved (db::Vector (50, 50)));
db::Trans tt;
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), tt));
c0.insert (db::CellInstArray (db::CellInst (c2.cell_index ()), db::Trans (db::Vector (100, -100))));
c0.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans (1)));
c2.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans (db::Vector (1100, 0))));
std::string x;
db::RecursiveInstanceIterator i1 (g, c0, db::Box (0, 0, 100, 100));
x = collect(i1, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
x = collect_with_copy(i1, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
db::RecursiveInstanceIterator i1_1inf (g, c0, db::Box (0, 0, 100, 100));
i1_1inf.min_depth(0);
x = collect(i1_1inf, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
x = collect_with_copy(i1_1inf, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
db::RecursiveInstanceIterator i1_11 (g, c0, db::Box (0, 0, 2000, 100));
i1_11.min_depth(0);
i1_11.max_depth(0);
x = collect(i1_11, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
x = collect_with_copy(i1_11, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
db::RecursiveInstanceIterator i1_12 (g, c0, db::Box (0, 0, 2000, 100));
i1_12.min_depth(0);
i1_12.max_depth(1);
x = collect(i1_12, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100");
x = collect_with_copy(i1_12, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100");
db::RecursiveInstanceIterator i1_22 (g, c0, db::Box (0, 0, 2000, 100));
i1_22.min_depth(1);
i1_22.max_depth(1);
x = collect(i1_22, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
x = collect_with_copy(i1_22, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
db::RecursiveInstanceIterator i1o (g, c0, db::Box (0, 0, 100, 100), true);
x = collect(i1o, g);
EXPECT_EQ (x, "");
x = collect_with_copy(i1o, g);
EXPECT_EQ (x, "");
i1o = db::RecursiveInstanceIterator (g, c0, db::Box (0, 0, 100, 101), true);
x = collect(i1o, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0");
x = collect_with_copy(i1o, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0");
i1o = db::RecursiveInstanceIterator (g, c0, db::Box (0, 0, 101, 101), true);
x = collect(i1o, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
x = collect_with_copy(i1o, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100");
db::RecursiveInstanceIterator i2 (g, c0, db::Box (-100, 0, 100, 100));
db::RecursiveInstanceIterator i2c = i2;
x = collect(i2, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i2, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect(i2c, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i2c, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
db::RecursiveInstanceIterator i2o (g, c0, db::Box (-100, 0, 100, 100), true);
x = collect(i2o, g);
EXPECT_EQ (x, "");
x = collect_with_copy(i2o, g);
EXPECT_EQ (x, "");
i2o = db::RecursiveInstanceIterator (g, c0, db::Box (-101, 0, 101, 101), true);
x = collect(i2o, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i2o, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
2021-02-20 17:50:32 +01:00
db::Region r;
r.insert (db::Box (-600, -100, -500, 0));
r.insert (db::Box (1600, 0, 1700, 100));
db::RecursiveInstanceIterator i2r (g, c0, r);
db::RecursiveInstanceIterator i2rc = i2r;
x = collect(i2r, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i2r, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect(i2rc, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i2rc, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
db::RecursiveInstanceIterator i2ro (g, c0, r, true);
x = collect(i2ro, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$3 r0 100,-100");
x = collect_with_copy(i2ro, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$3 r0 100,-100");
db::RecursiveInstanceIterator i4 (g, c0, db::Box (-100, 0, 2000, 100));
db::RecursiveInstanceIterator i4_copy (g, c0, db::Box (-100, 0, 2000, 100));
i4.max_depth (0);
x = collect(i4, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i4, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
EXPECT_EQ (i4 == i4, true);
EXPECT_EQ (i4 != i4, false);
EXPECT_EQ (i4 == i4_copy, false);
EXPECT_EQ (i4 != i4_copy, true);
i4 = i4_copy;
EXPECT_EQ (i4 == i4_copy, true);
EXPECT_EQ (i4 != i4_copy, false);
i4.max_depth (1);
x = collect(i4, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i4, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
i4 = i4_copy;
x = collect(i4, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i4, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
db::RecursiveInstanceIterator i5 (g, c0, db::Box::world ());
x = collect(i5, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(i5, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
std::set<db::cell_index_type> cc;
db::RecursiveInstanceIterator ii;
ii = db::RecursiveInstanceIterator (g, c0, db::Box::world ());
cc.clear ();
cc.insert (c2.cell_index ());
ii.unselect_all_cells ();
ii.select_cells (cc);
x = collect(ii, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
x = collect_with_copy(ii, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
ii.reset ();
x = collect(ii, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
x = collect_with_copy(ii, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
ii.reset_selection ();
x = collect(ii, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(ii, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$3]$4 r0 1100,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
ii.reset_selection ();
cc.clear ();
cc.insert (c0.cell_index ());
cc.insert (c2.cell_index ());
ii.unselect_cells (cc);
cc.clear ();
cc.insert (c2.cell_index ());
ii.select_cells (cc);
x = collect(ii, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
x = collect_with_copy(ii, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0");
ii = db::RecursiveInstanceIterator (g, c0, db::Box::world ());
ii.unselect_all_cells ();
cc.clear ();
cc.insert (c0.cell_index ());
ii.select_cells (cc);
x = collect(ii, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
x = collect_with_copy(ii, g);
EXPECT_EQ (x, "[$1]$2 r0 0,0/[$1]$3 r0 100,-100/[$1]$4 r90 0,0");
db::RecursiveInstanceIterator i1z (g, c0);
2021-02-20 17:50:32 +01:00
EXPECT_EQ (i1z.all_targets_enabled (), true);
std::set<db::cell_index_type> ct;
ct.insert (c3.cell_index ());
2021-02-20 17:50:32 +01:00
i1z.set_targets (ct);
EXPECT_EQ (i1z.all_targets_enabled (), false);
EXPECT_EQ (i1z.targets () == ct, true);
2021-02-20 17:50:32 +01:00
i1z.enable_all_targets ();
EXPECT_EQ (i1z.all_targets_enabled (), true);
2021-02-20 17:50:32 +01:00
i1z.set_targets (ct);
EXPECT_EQ (i1z.all_targets_enabled (), false);
x = collect(i1z, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$4 r90 0,0");
x = collect_with_copy(i1z, g);
EXPECT_EQ (x, "[$3]$4 r0 1100,0/[$1]$4 r90 0,0");
}
static db::Layout boxes2layout (const std::set<db::Box> &boxes)
{
db::Layout l;
l.insert_layer(0, db::LayerProperties (1, 0));
db::Cell &top (l.cell (l.add_cell ()));
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
top.shapes (0).insert (*b);
}
return l;
}
2021-02-21 22:11:33 +01:00
namespace {
2021-02-21 22:11:33 +01:00
class FlatPusher
: public db::RecursiveInstanceReceiver
{
2021-02-21 22:11:33 +01:00
public:
FlatPusher (std::set<db::Box> *boxes) : mp_boxes (boxes) { }
void enter_cell (const db::RecursiveInstanceIterator *iter, const db::Cell *cell, const db::Box & /*region*/, const box_tree_type * /*complex_region*/)
{
mp_boxes->insert (iter->trans () * cell->bbox ());
}
private:
std::set<db::Box> *mp_boxes;
};
2021-02-21 22:11:33 +01:00
}
2021-02-20 17:50:32 +01:00
TEST(2)
{
2021-02-20 17:50:32 +01:00
// Big fun with cells
db::Manager m (true);
db::Layout g (&m);
g.insert_layer(0);
db::Cell &c0 (g.cell (g.add_cell ()));
2021-02-20 17:50:32 +01:00
db::Cell &c1 (g.cell (g.add_cell ()));
db::Box basic_box (0, 0, 10, 10);
c1.shapes (0).insert (basic_box);
std::set<db::Box> boxes;
for (int i = 0; i < 100000; ++i) {
int x = rand () % 10000;
int y = rand () % 10000;
2021-02-20 17:50:32 +01:00
boxes.insert (basic_box.moved (db::Vector (x, y)));
2021-02-20 17:50:32 +01:00
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (x, y))));
}
db::Box search_box (2500, 2500, 7500, 7500);
std::set<db::Box> selected_boxes;
std::set<db::Box> selected_boxes2;
2021-02-20 17:50:32 +01:00
for (db::RecursiveInstanceIterator iter = db::RecursiveInstanceIterator (g, c0, search_box, true); !iter.at_end (); ++iter) {
selected_boxes.insert (iter.trans () * iter->inst_ptr.bbox ());
}
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
if (search_box.overlaps (*b)) {
selected_boxes2.insert (*b);
}
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
// push mode
{
selected_boxes.clear ();
FlatPusher pusher (&selected_boxes);
2021-02-20 17:50:32 +01:00
db::RecursiveInstanceIterator (g, c0, search_box, true).push (&pusher);
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
db::Box search_box2 (500, 500, 1000, 1000);
selected_boxes.clear ();
selected_boxes2.clear ();
db::Region reg;
reg.insert (search_box);
reg.insert (search_box2);
2021-02-20 17:50:32 +01:00
for (db::RecursiveInstanceIterator iter = db::RecursiveInstanceIterator (g, c0, reg, true); !iter.at_end (); ++iter) {
selected_boxes.insert (iter.trans () * iter->bbox (db::box_convert<db::CellInst> (g)));
}
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
if (search_box.overlaps (*b) || search_box2.overlaps (*b)) {
selected_boxes2.insert (*b);
}
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
// push mode
{
selected_boxes.clear ();
FlatPusher pusher (&selected_boxes);
2021-02-20 17:50:32 +01:00
db::RecursiveInstanceIterator (g, c0, reg, true).push (&pusher);
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
}
2021-02-20 17:50:32 +01:00
TEST(3)
{
2021-02-20 17:50:32 +01:00
// Big fun with cells - 2 hierarchy levels
db::Manager m (true);
db::Layout g (&m);
g.insert_layer(0);
db::Cell &c0 (g.cell (g.add_cell ()));
db::Cell &c1 (g.cell (g.add_cell ()));
2021-02-20 17:50:32 +01:00
db::Cell &c2 (g.cell (g.add_cell ()));
db::Box basic_box (0, 0, 10, 10);
2021-02-20 17:50:32 +01:00
c2.shapes (0).insert (basic_box);
c1.insert (db::CellInstArray (c2.cell_index (), db::Trans (db::Vector (1, -1))));
std::set<db::Box> boxes;
2021-02-20 17:50:32 +01:00
int nboxes = 100000;
for (int i = 0; i < nboxes; ++i) {
2021-02-20 17:50:32 +01:00
int x, y;
2021-02-20 17:50:32 +01:00
do {
x = rand () % 10000;
y = rand () % 10000;
} while (boxes.find (basic_box.moved (db::Vector (x + 1, y - 1))) != boxes.end ());
boxes.insert (basic_box.moved (db::Vector (x + 1, y - 1)));
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (x, y))));
}
db::Box search_box (2500, 2500, 7500, 7500);
std::set<db::Box> selected_boxes;
std::set<db::Box> selected_boxes2;
2021-02-20 17:50:32 +01:00
db::RecursiveInstanceIterator iter = db::RecursiveInstanceIterator (g, c0, search_box, true);
std::set<db::cell_index_type> tc;
tc.insert (c2.cell_index ());
iter.set_targets (tc);
int n = 0;
for ( ; !iter.at_end (); ++iter) {
++n;
selected_boxes.insert (iter.trans () * iter->bbox (db::box_convert<db::CellInst> (g)));
}
2021-02-20 17:50:32 +01:00
int nn = 0;
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
if (search_box.overlaps (*b)) {
2021-02-20 17:50:32 +01:00
++nn;
selected_boxes2.insert (*b);
}
}
2021-02-20 17:50:32 +01:00
EXPECT_EQ (n, nn);
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
// push mode
{
selected_boxes.clear ();
FlatPusher pusher (&selected_boxes);
2021-02-20 17:50:32 +01:00
db::RecursiveInstanceIterator (g, c0, search_box, true).push (&pusher);
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
db::Box search_box2 (500, 500, 1000, 1000);
selected_boxes.clear ();
selected_boxes2.clear ();
db::Region reg;
reg.insert (search_box);
reg.insert (search_box2);
2021-02-20 17:50:32 +01:00
for (db::RecursiveInstanceIterator iter = db::RecursiveInstanceIterator (g, c0, reg, true); !iter.at_end (); ++iter) {
selected_boxes.insert (iter.trans () * iter->bbox (db::box_convert<db::CellInst> (g)));
}
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
if (search_box.overlaps (*b) || search_box2.overlaps (*b)) {
selected_boxes2.insert (*b);
}
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
// push mode
{
selected_boxes.clear ();
FlatPusher pusher (&selected_boxes);
2021-02-20 17:50:32 +01:00
db::RecursiveInstanceIterator (g, c0, reg, true).push (&pusher);
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
}
2021-02-20 17:50:32 +01:00
TEST(4)
{
2021-02-20 17:50:32 +01:00
// Big fun with cells - 2 hierarchy levels + touching mode
2021-02-20 17:50:32 +01:00
db::Manager m (true);
db::Layout g (&m);
g.insert_layer(0);
2021-02-20 17:50:32 +01:00
db::Cell &c0 (g.cell (g.add_cell ()));
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
2021-02-20 17:50:32 +01:00
db::Box basic_box (0, 0, 10, 10);
c2.shapes (0).insert (basic_box);
c1.insert (db::CellInstArray (c2.cell_index (), db::Trans (db::Vector (1, -1))));
2021-02-20 17:50:32 +01:00
std::set<db::Box> boxes;
2021-02-20 17:50:32 +01:00
int nboxes = 100000;
for (int i = 0; i < nboxes; ++i) {
2021-02-20 17:50:32 +01:00
int x, y;
2021-02-20 17:50:32 +01:00
do {
x = rand () % 10000;
y = rand () % 10000;
} while (boxes.find (basic_box.moved (db::Vector (x + 1, y - 1))) != boxes.end ());
2021-02-20 17:50:32 +01:00
boxes.insert (basic_box.moved (db::Vector (x + 1, y - 1)));
2021-02-20 17:50:32 +01:00
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (x, y))));
}
2021-02-20 17:50:32 +01:00
db::Box search_box (2500, 2500, 7500, 7500);
2021-02-20 17:50:32 +01:00
std::set<db::Box> selected_boxes;
std::set<db::Box> selected_boxes2;
2021-02-20 17:50:32 +01:00
db::RecursiveInstanceIterator iter = db::RecursiveInstanceIterator (g, c0, search_box);
std::set<db::cell_index_type> tc;
tc.insert (c2.cell_index ());
iter.set_targets (tc);
int n = 0;
for ( ; !iter.at_end (); ++iter) {
++n;
selected_boxes.insert (iter.trans () * iter->bbox (db::box_convert<db::CellInst> (g)));
}
2021-02-20 17:50:32 +01:00
int nn = 0;
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
if (search_box.touches (*b)) {
++nn;
selected_boxes2.insert (*b);
}
}
2021-02-20 17:50:32 +01:00
EXPECT_EQ (n, nn);
2021-02-20 17:50:32 +01:00
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
// push mode
{
2021-02-20 17:50:32 +01:00
selected_boxes.clear ();
FlatPusher pusher (&selected_boxes);
db::RecursiveInstanceIterator (g, c0, search_box).push (&pusher);
}
2021-02-20 17:50:32 +01:00
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
2021-02-20 17:50:32 +01:00
db::Box search_box2 (500, 500, 1000, 1000);
2021-02-20 17:50:32 +01:00
selected_boxes.clear ();
selected_boxes2.clear ();
2021-02-20 17:50:32 +01:00
db::Region reg;
reg.insert (search_box);
reg.insert (search_box2);
2021-02-20 17:50:32 +01:00
for (db::RecursiveInstanceIterator iter = db::RecursiveInstanceIterator (g, c0, reg); !iter.at_end (); ++iter) {
selected_boxes.insert (iter.trans () * iter->bbox (db::box_convert<db::CellInst> (g)));
2021-02-20 17:50:32 +01:00
}
for (std::set<db::Box>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {
if (search_box.touches (*b) || search_box2.touches (*b)) {
selected_boxes2.insert (*b);
}
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
// push mode
{
selected_boxes.clear ();
FlatPusher pusher (&selected_boxes);
db::RecursiveInstanceIterator (g, c0, reg).push (&pusher);
}
EXPECT_EQ (selected_boxes.size () > 100, true);
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
}
2021-02-20 17:50:32 +01:00