2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
KLayout Layout Viewer
|
2023-01-01 22:27:09 +01:00
|
|
|
Copyright (C) 2006-2023 Matthias Koefferlein
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
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 "dbLayout.h"
|
|
|
|
|
#include "tlString.h"
|
2017-09-03 01:54:11 +02:00
|
|
|
#include "tlUnitTest.h"
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
TEST(1)
|
|
|
|
|
{
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (0).insert (b);
|
|
|
|
|
EXPECT_EQ (c1.bbox (), b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c1.shapes (1).insert (bb);
|
|
|
|
|
EXPECT_EQ (c1.bbox (), b + bb);
|
|
|
|
|
EXPECT_EQ (c1.bbox (0), b);
|
|
|
|
|
EXPECT_EQ (c1.bbox (1), bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
EXPECT_EQ (c2.bbox (), t * (b + bb));
|
|
|
|
|
EXPECT_EQ (c2.bbox (0), t * b);
|
|
|
|
|
EXPECT_EQ (c2.bbox (1), t * bb);
|
|
|
|
|
EXPECT_EQ (c1.bbox (), (b + bb));
|
|
|
|
|
|
|
|
|
|
// some basic testing of the instance trees
|
|
|
|
|
int n;
|
|
|
|
|
n = 0;
|
|
|
|
|
for (db::Cell::touching_iterator r = c2.begin_touching (t * db::Box (-100, 0, 0, 100));
|
|
|
|
|
! r.at_end (); ++r) ++n;
|
|
|
|
|
EXPECT_EQ (n, 1);
|
|
|
|
|
n = 0;
|
|
|
|
|
for (db::Cell::overlapping_iterator r = c2.begin_overlapping (t * db::Box (-100, 0, 0, 100));
|
|
|
|
|
! r.at_end (); ++r) ++n;
|
|
|
|
|
EXPECT_EQ (n, 0);
|
|
|
|
|
n = 0;
|
|
|
|
|
for (db::Cell::overlapping_iterator r = c2.begin_overlapping (t * db::Box (-100, 0, 1, 100));
|
|
|
|
|
! r.at_end (); ++r) ++n;
|
|
|
|
|
EXPECT_EQ (n, 1);
|
|
|
|
|
n = 0;
|
|
|
|
|
for (db::Cell::touching_iterator r = c2.begin_touching (t * db::Box (-100, 0, -1, 100));
|
|
|
|
|
! r.at_end (); ++r) ++n;
|
|
|
|
|
EXPECT_EQ (n, 0);
|
|
|
|
|
|
|
|
|
|
// try adding a new instance into c2
|
|
|
|
|
db::FTrans ff (2, true);
|
|
|
|
|
db::Vector pp (10, -20);
|
|
|
|
|
db::Trans tt (ff.rot (), pp);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
|
|
|
EXPECT_EQ (c2.bbox (), t * (b + bb) + tt * (b + bb));
|
|
|
|
|
EXPECT_EQ (c2.bbox (0), t * b + tt * b);
|
|
|
|
|
EXPECT_EQ (c2.bbox (1), t * bb + tt * bb);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct p2s_compare
|
|
|
|
|
{
|
|
|
|
|
bool operator() (const db::Cell::parent_inst_iterator &p1, const db::Cell::parent_inst_iterator &p2)
|
|
|
|
|
{
|
|
|
|
|
if (p1->inst ().object ().cell_index () != p2->inst ().object ().cell_index ()) {
|
|
|
|
|
return p1->inst ().object ().cell_index () < p2->inst ().object ().cell_index ();
|
|
|
|
|
}
|
|
|
|
|
if (p1->inst ().complex_trans () != p2->inst ().complex_trans ()) {
|
|
|
|
|
return p1->inst ().complex_trans () < p2->inst ().complex_trans ();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string p2s (const db::Cell &c)
|
|
|
|
|
{
|
|
|
|
|
std::vector<db::Cell::parent_inst_iterator> pp;
|
|
|
|
|
for (db::Cell::parent_inst_iterator p = c.begin_parent_insts (); ! p.at_end (); ++p) {
|
|
|
|
|
pp.push_back (p);
|
|
|
|
|
}
|
|
|
|
|
std::sort (pp.begin (), pp.end (), p2s_compare ());
|
|
|
|
|
std::string r;
|
|
|
|
|
for (std::vector<db::Cell::parent_inst_iterator>::const_iterator ppp = pp.begin (); ppp != pp.end (); ++ppp) {
|
|
|
|
|
db::Cell::parent_inst_iterator p = *ppp;
|
|
|
|
|
if (! r.empty ()) {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (p->inst ().object ().cell_index ()) + "[" + p->inst ().complex_trans ().to_string () + "]" + "#" + tl::to_string (p->child_inst ().prop_id ());
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct pc2s_compare
|
|
|
|
|
{
|
|
|
|
|
bool operator() (const db::Cell::parent_cell_iterator &p1, const db::Cell::parent_cell_iterator &p2)
|
|
|
|
|
{
|
|
|
|
|
return *p1 < *p2;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string pc2s (const db::Cell &c)
|
|
|
|
|
{
|
|
|
|
|
std::vector<db::Cell::parent_cell_iterator> pp;
|
|
|
|
|
for (db::Cell::parent_cell_iterator p = c.begin_parent_cells (); p != c.end_parent_cells (); ++p) {
|
|
|
|
|
pp.push_back (p);
|
|
|
|
|
}
|
|
|
|
|
std::sort (pp.begin (), pp.end (), pc2s_compare ());
|
|
|
|
|
std::string r;
|
|
|
|
|
for (std::vector<db::Cell::parent_cell_iterator>::const_iterator ppp = pp.begin (); ppp != pp.end (); ++ppp) {
|
|
|
|
|
db::Cell::parent_cell_iterator p = *ppp;
|
|
|
|
|
if (! r.empty ()) {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (*p);
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct c2s_compare
|
|
|
|
|
{
|
|
|
|
|
bool operator() (const db::Cell::const_iterator &p1, const db::Cell::const_iterator &p2)
|
|
|
|
|
{
|
|
|
|
|
if (p1->cell_index () != p2->cell_index ()) {
|
|
|
|
|
return p1->cell_index () < p2->cell_index ();
|
|
|
|
|
}
|
|
|
|
|
if (p1->complex_trans () != p2->complex_trans ()) {
|
|
|
|
|
return p1->complex_trans () < p2->complex_trans ();
|
|
|
|
|
}
|
|
|
|
|
if (p1->prop_id () != p2->prop_id ()) {
|
|
|
|
|
return p1->prop_id () < p2->prop_id ();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string c2s (const db::Cell &c)
|
|
|
|
|
{
|
|
|
|
|
std::vector<db::Cell::const_iterator> pp;
|
|
|
|
|
for (db::Cell::const_iterator p = c.begin (); ! p.at_end (); ++p) {
|
|
|
|
|
pp.push_back (p);
|
|
|
|
|
}
|
|
|
|
|
std::sort (pp.begin (), pp.end (), c2s_compare ());
|
|
|
|
|
std::string r;
|
|
|
|
|
for (std::vector<db::Cell::const_iterator>::const_iterator ppp = pp.begin (); ppp != pp.end (); ++ppp) {
|
|
|
|
|
db::Cell::const_iterator p = *ppp;
|
|
|
|
|
if (! r.empty ()) {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (p->cell_index ()) + "[" + p->complex_trans ().to_string () + "]" + "#" + tl::to_string (p->prop_id ());
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string c2s_unsorted (const db::Cell &c)
|
|
|
|
|
{
|
|
|
|
|
std::string r;
|
|
|
|
|
for (db::Cell::const_iterator p = c.begin (); ! p.at_end (); ++p) {
|
|
|
|
|
if (! r.empty ()) {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (p->cell_index ()) + "[" + p->complex_trans ().to_string () + "]" + "#" + tl::to_string (p->prop_id ());
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ct2s_compare
|
|
|
|
|
{
|
|
|
|
|
bool operator() (const db::Cell::touching_iterator &p1, const db::Cell::touching_iterator &p2)
|
|
|
|
|
{
|
|
|
|
|
if (p1->cell_index () != p2->cell_index ()) {
|
|
|
|
|
return p1->cell_index () < p2->cell_index ();
|
|
|
|
|
}
|
|
|
|
|
if (p1->complex_trans () != p2->complex_trans ()) {
|
|
|
|
|
return p1->complex_trans () < p2->complex_trans ();
|
|
|
|
|
}
|
|
|
|
|
if (p1->prop_id () != p2->prop_id ()) {
|
|
|
|
|
return p1->prop_id () < p2->prop_id ();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string ct2s (const db::Cell &c)
|
|
|
|
|
{
|
|
|
|
|
std::vector<db::Cell::touching_iterator> pp;
|
|
|
|
|
for (db::Cell::touching_iterator p = c.begin_touching (db::Box (-10000, -10000, 10000, 10000)); ! p.at_end (); ++p) {
|
|
|
|
|
pp.push_back (p);
|
|
|
|
|
}
|
|
|
|
|
std::sort (pp.begin (), pp.end (), ct2s_compare ());
|
|
|
|
|
std::string r;
|
|
|
|
|
for (std::vector<db::Cell::touching_iterator>::const_iterator ppp = pp.begin (); ppp != pp.end (); ++ppp) {
|
|
|
|
|
db::Cell::touching_iterator p = *ppp;
|
|
|
|
|
if (! r.empty ()) {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (p->cell_index ()) + "[" + p->complex_trans ().to_string () + "]" + "#" + tl::to_string (p->prop_id ());
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct cc2s_compare
|
|
|
|
|
{
|
|
|
|
|
bool operator() (const db::Cell::child_cell_iterator &p1, const db::Cell::child_cell_iterator &p2)
|
|
|
|
|
{
|
|
|
|
|
return *p1 < *p2;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string cc2s (const db::Cell &c)
|
|
|
|
|
{
|
|
|
|
|
std::vector<db::Cell::child_cell_iterator> pp;
|
|
|
|
|
for (db::Cell::child_cell_iterator p = c.begin_child_cells (); ! p.at_end (); ++p) {
|
|
|
|
|
pp.push_back (p);
|
|
|
|
|
}
|
|
|
|
|
std::sort (pp.begin (), pp.end (), cc2s_compare ());
|
|
|
|
|
std::string r;
|
|
|
|
|
for (std::vector<db::Cell::child_cell_iterator>::const_iterator ppp = pp.begin (); ppp != pp.end (); ++ppp) {
|
|
|
|
|
db::Cell::child_cell_iterator p = *ppp;
|
|
|
|
|
if (! r.empty ()) {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (*p);
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int pi = 0;
|
|
|
|
|
|
|
|
|
|
void insert_ci (db::Cell &c, size_t ci, const db::Trans &t)
|
|
|
|
|
{
|
|
|
|
|
if (pi == 0) {
|
2018-08-29 01:46:18 +02:00
|
|
|
c.insert (db::CellInstArray (db::CellInst (db::cell_index_type (ci)), t));
|
2017-02-12 13:21:08 +01:00
|
|
|
} else {
|
2018-08-29 01:46:18 +02:00
|
|
|
c.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (db::cell_index_type (ci)), t), pi));
|
2017-02-12 13:21:08 +01:00
|
|
|
}
|
|
|
|
|
pi = (pi + 1) % 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(2)
|
|
|
|
|
{
|
|
|
|
|
::pi = 0;
|
|
|
|
|
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
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::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c5 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c0.shapes (0).insert (b);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
c2.shapes (2).insert (b);
|
|
|
|
|
c3.shapes (3).insert (b);
|
|
|
|
|
c4.shapes (4).insert (b);
|
|
|
|
|
c5.shapes (5).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Trans t;
|
|
|
|
|
insert_ci (c0, c1.cell_index (), t);
|
|
|
|
|
insert_ci (c1, c2.cell_index (), t);
|
|
|
|
|
insert_ci (c2, c3.cell_index (), t);
|
|
|
|
|
insert_ci (c3, c4.cell_index (), t);
|
|
|
|
|
insert_ci (c4, c5.cell_index (), t);
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (p2s(c0), "");
|
|
|
|
|
EXPECT_EQ (p2s(c1), "0[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c2), "1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c3), "2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c4), "3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c5), "4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (pc2s(c0), "");
|
|
|
|
|
EXPECT_EQ (pc2s(c1), "0");
|
|
|
|
|
EXPECT_EQ (pc2s(c2), "1");
|
|
|
|
|
EXPECT_EQ (pc2s(c3), "2");
|
|
|
|
|
EXPECT_EQ (pc2s(c4), "3");
|
|
|
|
|
EXPECT_EQ (pc2s(c5), "4");
|
|
|
|
|
EXPECT_EQ (c2s(c0), "1[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (c2s(c1), "2[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c2), "3[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c3), "4[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (c2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c5), "");
|
|
|
|
|
EXPECT_EQ (ct2s(c0), "1[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (ct2s(c1), "2[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c2), "3[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c3), "4[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (ct2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c5), "");
|
|
|
|
|
EXPECT_EQ (cc2s(c0), "1");
|
|
|
|
|
EXPECT_EQ (cc2s(c1), "2");
|
|
|
|
|
EXPECT_EQ (cc2s(c2), "3");
|
|
|
|
|
EXPECT_EQ (cc2s(c3), "4");
|
|
|
|
|
EXPECT_EQ (cc2s(c4), "5");
|
|
|
|
|
EXPECT_EQ (cc2s(c5), "");
|
|
|
|
|
|
|
|
|
|
insert_ci (c0, c2.cell_index (), t);
|
|
|
|
|
insert_ci (c1, c3.cell_index (), t);
|
|
|
|
|
insert_ci (c2, c4.cell_index (), t);
|
|
|
|
|
insert_ci (c3, c5.cell_index (), t);
|
|
|
|
|
EXPECT_EQ (p2s(c0), "");
|
|
|
|
|
EXPECT_EQ (p2s(c1), "0[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c2), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c3), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c4), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c5), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (pc2s(c0), "");
|
|
|
|
|
EXPECT_EQ (pc2s(c1), "0");
|
|
|
|
|
EXPECT_EQ (pc2s(c2), "0,1");
|
|
|
|
|
EXPECT_EQ (pc2s(c3), "1,2");
|
|
|
|
|
EXPECT_EQ (pc2s(c4), "2,3");
|
|
|
|
|
EXPECT_EQ (pc2s(c5), "3,4");
|
|
|
|
|
EXPECT_EQ (c2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (c2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c5), "");
|
|
|
|
|
EXPECT_EQ (ct2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (ct2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c5), "");
|
|
|
|
|
EXPECT_EQ (cc2s(c0), "1,2");
|
|
|
|
|
EXPECT_EQ (cc2s(c1), "2,3");
|
|
|
|
|
EXPECT_EQ (cc2s(c2), "3,4");
|
|
|
|
|
EXPECT_EQ (cc2s(c3), "4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c4), "5");
|
|
|
|
|
EXPECT_EQ (cc2s(c5), "");
|
|
|
|
|
|
|
|
|
|
insert_ci (c0, c3.cell_index (), t);
|
|
|
|
|
insert_ci (c1, c4.cell_index (), t);
|
|
|
|
|
insert_ci (c2, c5.cell_index (), t);
|
|
|
|
|
EXPECT_EQ (p2s(c0), "");
|
|
|
|
|
EXPECT_EQ (p2s(c1), "0[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c2), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c3), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c4), "1[r0 *1 0,0]#1,2[r0 *1 0,0]#1,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c5), "2[r0 *1 0,0]#2,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (pc2s(c0), "");
|
|
|
|
|
EXPECT_EQ (pc2s(c1), "0");
|
|
|
|
|
EXPECT_EQ (pc2s(c2), "0,1");
|
|
|
|
|
EXPECT_EQ (pc2s(c3), "0,1,2");
|
|
|
|
|
EXPECT_EQ (pc2s(c4), "1,2,3");
|
|
|
|
|
EXPECT_EQ (pc2s(c5), "2,3,4");
|
|
|
|
|
EXPECT_EQ (c2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (c2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c5), "");
|
|
|
|
|
EXPECT_EQ (ct2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (ct2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c5), "");
|
|
|
|
|
EXPECT_EQ (cc2s(c0), "1,2,3");
|
|
|
|
|
EXPECT_EQ (cc2s(c1), "2,3,4");
|
|
|
|
|
EXPECT_EQ (cc2s(c2), "3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c3), "4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c4), "5");
|
|
|
|
|
EXPECT_EQ (cc2s(c5), "");
|
|
|
|
|
|
|
|
|
|
insert_ci (c0, c4.cell_index (), t);
|
|
|
|
|
insert_ci (c1, c5.cell_index (), t);
|
|
|
|
|
EXPECT_EQ (p2s(c0), "");
|
|
|
|
|
EXPECT_EQ (p2s(c1), "0[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c2), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c3), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c4), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 0,0]#1,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c5), "1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (pc2s(c0), "");
|
|
|
|
|
EXPECT_EQ (pc2s(c1), "0");
|
|
|
|
|
EXPECT_EQ (pc2s(c2), "0,1");
|
|
|
|
|
EXPECT_EQ (pc2s(c3), "0,1,2");
|
|
|
|
|
EXPECT_EQ (pc2s(c4), "0,1,2,3");
|
|
|
|
|
EXPECT_EQ (pc2s(c5), "1,2,3,4");
|
|
|
|
|
EXPECT_EQ (c2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (c2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c5), "");
|
|
|
|
|
EXPECT_EQ (ct2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (ct2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c5), "");
|
|
|
|
|
EXPECT_EQ (cc2s(c0), "1,2,3,4");
|
|
|
|
|
EXPECT_EQ (cc2s(c1), "2,3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c2), "3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c3), "4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c4), "5");
|
|
|
|
|
EXPECT_EQ (cc2s(c5), "");
|
|
|
|
|
|
|
|
|
|
insert_ci (c0, c5.cell_index (), t);
|
|
|
|
|
EXPECT_EQ (p2s(c0), "");
|
|
|
|
|
EXPECT_EQ (p2s(c1), "0[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c2), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c3), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c4), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 0,0]#1,3[r0 *1 0,0]#0");
|
|
|
|
|
EXPECT_EQ (p2s(c5), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (pc2s(c0), "");
|
|
|
|
|
EXPECT_EQ (pc2s(c1), "0");
|
|
|
|
|
EXPECT_EQ (pc2s(c2), "0,1");
|
|
|
|
|
EXPECT_EQ (pc2s(c3), "0,1,2");
|
|
|
|
|
EXPECT_EQ (pc2s(c4), "0,1,2,3");
|
|
|
|
|
EXPECT_EQ (pc2s(c5), "0,1,2,3,4");
|
|
|
|
|
EXPECT_EQ (c2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c5), "");
|
|
|
|
|
EXPECT_EQ (ct2s(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c1), "2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c2), "3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c4), "5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c5), "");
|
|
|
|
|
EXPECT_EQ (cc2s(c0), "1,2,3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c1), "2,3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c2), "3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c3), "4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c4), "5");
|
|
|
|
|
EXPECT_EQ (cc2s(c5), "");
|
|
|
|
|
|
|
|
|
|
::pi = 1;
|
|
|
|
|
insert_ci (c0, c1.cell_index (), t);
|
|
|
|
|
insert_ci (c1, c2.cell_index (), t);
|
|
|
|
|
insert_ci (c2, c3.cell_index (), t);
|
|
|
|
|
insert_ci (c3, c4.cell_index (), t);
|
|
|
|
|
insert_ci (c4, c5.cell_index (), t);
|
|
|
|
|
EXPECT_EQ (p2s(c0), "");
|
|
|
|
|
EXPECT_EQ (p2s(c1), "0[r0 *1 0,0]#0,0[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c2), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1,1[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c3), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#0,2[r0 *1 0,0]#0,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (p2s(c4), "0[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 0,0]#1,3[r0 *1 0,0]#0,3[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (p2s(c5), "0[r0 *1 0,0]#2,1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,4[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (pc2s(c0), "");
|
|
|
|
|
EXPECT_EQ (pc2s(c1), "0");
|
|
|
|
|
EXPECT_EQ (pc2s(c2), "0,1");
|
|
|
|
|
EXPECT_EQ (pc2s(c3), "0,1,2");
|
|
|
|
|
EXPECT_EQ (pc2s(c4), "0,1,2,3");
|
|
|
|
|
EXPECT_EQ (pc2s(c5), "0,1,2,3,4");
|
|
|
|
|
EXPECT_EQ (c2s(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c1), "2[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s(c2), "3[r0 *1 0,0]#0,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c3), "4[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c4), "5[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s(c5), "");
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,2[r0 *1 0,0]#2,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c1), "3[r0 *1 0,0]#0,2[r0 *1 0,0]#1,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1,2[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c2), "3[r0 *1 0,0]#0,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c3), "4[r0 *1 0,0]#0,5[r0 *1 0,0]#2,4[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c4), "5[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c5), "");
|
|
|
|
|
EXPECT_EQ (ct2s(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c1), "2[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (ct2s(c2), "3[r0 *1 0,0]#0,3[r0 *1 0,0]#2,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c3), "4[r0 *1 0,0]#0,4[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c4), "5[r0 *1 0,0]#1,5[r0 *1 0,0]#2");
|
|
|
|
|
EXPECT_EQ (ct2s(c5), "");
|
|
|
|
|
EXPECT_EQ (cc2s(c0), "1,2,3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c1), "2,3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c2), "3,4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c3), "4,5");
|
|
|
|
|
EXPECT_EQ (cc2s(c4), "5");
|
|
|
|
|
EXPECT_EQ (cc2s(c5), "");
|
|
|
|
|
|
|
|
|
|
db::Cell::const_iterator inst = c0.begin ();
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,2[r0 *1 0,0]#2,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
db::Trans t1 (1, db::Vector (100, -200));
|
|
|
|
|
c0.replace (*inst, db::CellInstArray (db::CellInst (c2.cell_index ()), t1));
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "2[r90 *1 100,-200]#0,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,2[r0 *1 0,0]#2,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
++inst;
|
|
|
|
|
++inst;
|
|
|
|
|
++inst;
|
|
|
|
|
c0.replace (*inst, db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c3.cell_index ()), t1), 17));
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "2[r90 *1 100,-200]#0,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,3[r90 *1 100,-200]#17,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
c0.replace_prop_id (*inst, 11);
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "2[r90 *1 100,-200]#0,3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,3[r90 *1 100,-200]#11,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
inst = c0.begin ();
|
|
|
|
|
|
|
|
|
|
// replace a non-property array with one with properties:
|
|
|
|
|
c0.replace (*inst, db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans ()), 13));
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "3[r0 *1 0,0]#0,4[r0 *1 0,0]#0,3[r90 *1 100,-200]#11,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1,3[r0 *1 0,0]#13");
|
|
|
|
|
|
|
|
|
|
db::Cell &cx = g.cell (g.add_cell (g.cell_name (c0.cell_index ())));
|
|
|
|
|
|
|
|
|
|
// erase from iterator
|
|
|
|
|
inst = c0.begin ();
|
|
|
|
|
db::Instance i0 = *inst;
|
|
|
|
|
c0.erase (inst);
|
|
|
|
|
// HINT: doing a c2s_unsorted on c0 would disturb the index order of c0, because it uses a flat
|
|
|
|
|
// iterator. Therefore we make a copy in order to prevent that problem. See bug #120.
|
|
|
|
|
cx = c0;
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(cx), "4[r0 *1 0,0]#0,3[r90 *1 100,-200]#11,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1,3[r0 *1 0,0]#13");
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (5));
|
2017-02-12 13:21:08 +01:00
|
|
|
// not yet: EXPECT_EQ (c0.empty (), false);
|
|
|
|
|
inst = c0.begin ();
|
|
|
|
|
db::Instance i1 = *inst;
|
|
|
|
|
c0.erase (inst);
|
|
|
|
|
cx = c0;
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(cx), "3[r90 *1 100,-200]#11,5[r0 *1 0,0]#2,1[r0 *1 0,0]#1,3[r0 *1 0,0]#13");
|
|
|
|
|
inst = c0.begin ();
|
|
|
|
|
db::Instance i2 = *inst;
|
|
|
|
|
c0.erase (inst);
|
|
|
|
|
cx = c0;
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(cx), "5[r0 *1 0,0]#2,1[r0 *1 0,0]#1,3[r0 *1 0,0]#13");
|
|
|
|
|
inst = c0.begin ();
|
|
|
|
|
db::Instance i3 = *inst;
|
|
|
|
|
db::Instance i4 = *++inst;
|
|
|
|
|
db::Instance i5 = *++inst;
|
|
|
|
|
|
|
|
|
|
// note: double delete is not supported in non-editable mode
|
|
|
|
|
if (db::default_editable_mode ()) {
|
|
|
|
|
|
|
|
|
|
/* currently does not issue an exception:
|
|
|
|
|
caught = false;
|
|
|
|
|
bool caught;
|
|
|
|
|
try {
|
|
|
|
|
c0.erase (i0); // already deleted
|
|
|
|
|
} catch (...) {
|
|
|
|
|
caught = true;
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ (caught, true);
|
|
|
|
|
*/
|
|
|
|
|
c0.erase (i0); // already deleted
|
|
|
|
|
|
|
|
|
|
/* currently does not issue an exception:
|
|
|
|
|
caught = false;
|
|
|
|
|
try {
|
|
|
|
|
c0.erase (i1); // already deleted
|
|
|
|
|
} catch (...) {
|
|
|
|
|
caught = true;
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ (caught, true);
|
|
|
|
|
*/
|
|
|
|
|
c0.erase (i1); // already deleted
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c0.erase (i5);
|
2017-12-31 01:46:49 +01:00
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (2));
|
|
|
|
|
c0.erase (i4);
|
2017-02-12 13:21:08 +01:00
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "5[r0 *1 0,0]#2");
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
2017-12-31 01:46:49 +01:00
|
|
|
// Not yet: EXPECT_EQ (c0.empty (), false);
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
// note: double delete is not supported in non-editable mode
|
|
|
|
|
if (db::default_editable_mode ()) {
|
|
|
|
|
|
|
|
|
|
/* currently does not issue an exception:
|
|
|
|
|
caught = false;
|
|
|
|
|
try {
|
|
|
|
|
c0.erase (i2); // already deleted
|
|
|
|
|
} catch (...) {
|
|
|
|
|
caught = true;
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ (caught, true);
|
|
|
|
|
*/
|
|
|
|
|
c0.erase (i2); // already deleted
|
|
|
|
|
|
|
|
|
|
/* currently does not issue an exception:
|
|
|
|
|
caught = false;
|
|
|
|
|
try {
|
|
|
|
|
c0.erase (i5); // already deleted
|
|
|
|
|
} catch (...) {
|
|
|
|
|
caught = true;
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ (caught, true);
|
|
|
|
|
*/
|
|
|
|
|
c0.erase (i5); // already deleted
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c0.erase (i3);
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "");
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (0));
|
2017-12-31 01:46:49 +01:00
|
|
|
// Not yet: EXPECT_EQ (c0.empty (), true);
|
2017-02-12 13:21:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(3)
|
|
|
|
|
{
|
|
|
|
|
::pi = 0;
|
|
|
|
|
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c0.shapes (0).insert (b);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Trans t1;
|
|
|
|
|
db::Trans t2 (db::Vector (100, -100));
|
|
|
|
|
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), t1));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t1), 1));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t2), 10));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,1[r0 *1 100,-100]#10");
|
|
|
|
|
|
|
|
|
|
db::Cell::const_iterator i = c0.begin ();
|
|
|
|
|
++i; ++i;
|
|
|
|
|
db::Cell::const_iterator i2 = i;
|
|
|
|
|
++i;
|
|
|
|
|
EXPECT_EQ (i.at_end (), true);
|
|
|
|
|
|
|
|
|
|
c0.erase (i2);
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1");
|
|
|
|
|
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t2), 17));
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,1[r0 *1 100,-100]#17");
|
|
|
|
|
|
|
|
|
|
i = c0.begin ();
|
|
|
|
|
++i; ++i;
|
|
|
|
|
db::Instance inst2 = *i;
|
|
|
|
|
++i;
|
|
|
|
|
|
|
|
|
|
c0.erase (inst2);
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1");
|
|
|
|
|
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t2), 18));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t2), 21));
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,1[r0 *1 100,-100]#18,1[r0 *1 100,-100]#21");
|
|
|
|
|
|
|
|
|
|
i = c0.begin ();
|
|
|
|
|
std::vector<db::Instance> insts;
|
|
|
|
|
insts.push_back (*i);
|
|
|
|
|
++i; ++i;
|
|
|
|
|
insts.push_back (*i);
|
|
|
|
|
std::swap (insts[0], insts[1]);
|
|
|
|
|
std::sort (insts.begin (), insts.end ());
|
|
|
|
|
|
|
|
|
|
c0.erase_insts (insts);
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#1,1[r0 *1 100,-100]#21");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(3a)
|
|
|
|
|
{
|
|
|
|
|
::pi = 0;
|
|
|
|
|
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Trans t (db::Vector (100, -100));
|
|
|
|
|
db::Instance inst = c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 r0 100,-100");
|
|
|
|
|
|
|
|
|
|
inst = c0.transform (inst, db::Trans (5));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 -100,100");
|
|
|
|
|
|
|
|
|
|
inst = c0.transform (inst, db::ICplxTrans (2.5));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 *2.5 -250,250");
|
|
|
|
|
|
|
|
|
|
inst = c0.replace (inst, db::CellInstArray (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 r0 100,-100");
|
|
|
|
|
|
|
|
|
|
inst = c0.transform_into (inst, db::Trans (5));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 r0 -100,100");
|
|
|
|
|
|
|
|
|
|
inst = c0.transform_into (inst, db::ICplxTrans (2.5));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 r0 -250,250");
|
|
|
|
|
|
|
|
|
|
t = db::Trans (5, db::Vector (100, -100));
|
|
|
|
|
inst = c0.replace (inst, db::CellInstArray (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 100,-100");
|
|
|
|
|
|
|
|
|
|
inst = c0.transform_into (inst, db::Trans (5));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 -100,100");
|
|
|
|
|
|
|
|
|
|
db::CplxTrans ti (2.5, 45.0, false, db::DVector (10, 20));
|
|
|
|
|
|
|
|
|
|
// NOTE: even a ICPlxTrans carries a float displacement as accuracy reserve.
|
|
|
|
|
EXPECT_EQ ((ti * inst.complex_trans () * ti.inverted ()).to_string (), "m90 *1 -333.553390593,0");
|
|
|
|
|
|
|
|
|
|
inst = c0.transform_into (inst, db::ICplxTrans (ti));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m90 -334,0");
|
|
|
|
|
|
|
|
|
|
t = db::Trans (5, db::Vector (100, -100));
|
|
|
|
|
inst = c0.replace (inst, db::CellInstArray (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 100,-100");
|
|
|
|
|
|
|
|
|
|
c0.transform_into (db::Trans (5));
|
|
|
|
|
inst = *c0.begin ();
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 -100,100");
|
|
|
|
|
|
|
|
|
|
c0.transform_into (db::ICplxTrans (ti));
|
|
|
|
|
inst = *c0.begin ();
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 m90 -334,0");
|
2020-07-03 23:41:09 +02:00
|
|
|
|
|
|
|
|
c0.transform (db::Trans (5));
|
|
|
|
|
inst = *c0.begin ();
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 r270 0,-334");
|
|
|
|
|
|
|
|
|
|
c0.transform (db::ICplxTrans (ti));
|
|
|
|
|
inst = *c0.begin ();
|
|
|
|
|
EXPECT_EQ (inst.to_string (), "cell_index=1 r315 *2.5 600,-570");
|
2017-02-12 13:21:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(3b)
|
|
|
|
|
{
|
|
|
|
|
::pi = 0;
|
|
|
|
|
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Trans t (db::Vector (100, -100));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t), 5));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c0.shapes (0).insert (db::BoxWithProperties (b, 17));
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
// Note: this requires editable mode since db::Shapes::erase is permitted in editable mode only
|
|
|
|
|
// (erase is triggered by undo)
|
|
|
|
|
if (db::default_editable_mode ()) {
|
|
|
|
|
|
|
|
|
|
m.transaction ("t");
|
|
|
|
|
g.transform (db::ICplxTrans (2.5));
|
|
|
|
|
m.commit ();
|
|
|
|
|
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c1.cell_instances (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
2017-02-12 13:21:08 +01:00
|
|
|
EXPECT_EQ (c0.begin ()->to_string (), "cell_index=1 r0 250,-250 prop_id=5");
|
|
|
|
|
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c0.shapes (0).size (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.shapes (1).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (0).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).size (), size_t (1));
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).begin (db::ShapeIterator::All)->to_string (), "box (0,250;2500,3000) prop_id=17");
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).begin (db::ShapeIterator::All)->to_string (), "box (0,250;2500,3000)");
|
|
|
|
|
|
|
|
|
|
m.undo ();
|
|
|
|
|
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c1.cell_instances (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
2017-02-12 13:21:08 +01:00
|
|
|
EXPECT_EQ (c0.begin ()->to_string (), "cell_index=1 r0 100,-100 prop_id=5");
|
|
|
|
|
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c0.shapes (0).size (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.shapes (1).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (0).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).size (), size_t (1));
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).begin (db::ShapeIterator::All)->to_string (), "box (0,100;1000,1200) prop_id=17");
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).begin (db::ShapeIterator::All)->to_string (), "box (0,100;1000,1200)");
|
|
|
|
|
|
|
|
|
|
m.redo ();
|
|
|
|
|
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c1.cell_instances (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
2017-02-12 13:21:08 +01:00
|
|
|
EXPECT_EQ (c0.begin ()->to_string (), "cell_index=1 r0 250,-250 prop_id=5");
|
|
|
|
|
|
2017-04-01 23:18:04 +02:00
|
|
|
EXPECT_EQ (c0.shapes (0).size (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.shapes (1).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (0).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).size (), size_t (1));
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).begin (db::ShapeIterator::All)->to_string (), "box (0,250;2500,3000) prop_id=17");
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).begin (db::ShapeIterator::All)->to_string (), "box (0,250;2500,3000)");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 23:41:09 +02:00
|
|
|
TEST(3c)
|
|
|
|
|
{
|
|
|
|
|
::pi = 0;
|
|
|
|
|
|
|
|
|
|
db::Manager m (true);
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Trans t (db::Vector (100, -100));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t), 5));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c0.shapes (0).insert (db::BoxWithProperties (b, 17));
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
// Note: this requires editable mode since db::Shapes::erase is permitted in editable mode only
|
|
|
|
|
// (erase is triggered by undo)
|
|
|
|
|
if (db::default_editable_mode ()) {
|
|
|
|
|
|
|
|
|
|
m.transaction ("t");
|
|
|
|
|
c0.transform (db::ICplxTrans (2.5));
|
|
|
|
|
m.commit ();
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c1.cell_instances (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.begin ()->to_string (), "cell_index=1 r0 *2.5 250,-250 prop_id=5");
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).size (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.shapes (1).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (0).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).size (), size_t (1));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).begin (db::ShapeIterator::All)->to_string (), "box (0,250;2500,3000) prop_id=17");
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).begin (db::ShapeIterator::All)->to_string (), "box (0,100;1000,1200)");
|
|
|
|
|
|
|
|
|
|
m.undo ();
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c1.cell_instances (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.begin ()->to_string (), "cell_index=1 r0 100,-100 prop_id=5");
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).size (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.shapes (1).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (0).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).size (), size_t (1));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).begin (db::ShapeIterator::All)->to_string (), "box (0,100;1000,1200) prop_id=17");
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).begin (db::ShapeIterator::All)->to_string (), "box (0,100;1000,1200)");
|
|
|
|
|
|
|
|
|
|
m.redo ();
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c1.cell_instances (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c0.cell_instances (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.begin ()->to_string (), "cell_index=1 r0 *2.5 250,-250 prop_id=5");
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).size (), size_t (1));
|
|
|
|
|
EXPECT_EQ (c0.shapes (1).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (0).size (), size_t (0));
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).size (), size_t (1));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c0.shapes (0).begin (db::ShapeIterator::All)->to_string (), "box (0,250;2500,3000) prop_id=17");
|
|
|
|
|
EXPECT_EQ (c1.shapes (1).begin (db::ShapeIterator::All)->to_string (), "box (0,100;1000,1200)");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-12 13:21:08 +01:00
|
|
|
struct map1
|
|
|
|
|
{
|
|
|
|
|
db::cell_index_type operator() (db::cell_index_type i) const { return 3-i; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct map2
|
|
|
|
|
{
|
|
|
|
|
db::Layout::properties_id_type operator() (db::Layout::properties_id_type i) const { return 3+i; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST(4)
|
|
|
|
|
{
|
|
|
|
|
::pi = 0;
|
|
|
|
|
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c0.shapes (0).insert (b);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
c2.shapes (2).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Trans t1;
|
|
|
|
|
db::Trans t2 (db::Vector (100, -100));
|
|
|
|
|
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), t1));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), t1), 1));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c2.cell_index ()), t2), 10));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 100,-100]#10");
|
|
|
|
|
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
for (db::Cell::const_iterator i = c0.begin (); ! i.at_end (); ++i) {
|
|
|
|
|
c3.insert (*i);
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c3), "1[r0 *1 0,0]#0,1[r0 *1 0,0]#1,2[r0 *1 100,-100]#10");
|
|
|
|
|
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
for (db::Cell::const_iterator i = c0.begin (); ! i.at_end (); ++i) {
|
|
|
|
|
map1 m1;
|
|
|
|
|
map2 m2;
|
|
|
|
|
c4.insert (*i, m1, m2);
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c4), "2[r0 *1 0,0]#0,2[r0 *1 0,0]#4,1[r0 *1 100,-100]#13");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(5)
|
|
|
|
|
{
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
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::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
c4.shapes (0).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Cell *cells[] = { &c1, &c2, &c3, &c4 };
|
|
|
|
|
|
|
|
|
|
db::Trans trans [] = { db::Trans (),
|
|
|
|
|
db::Trans (1, db::Vector (100, -200)),
|
|
|
|
|
db::Trans (6, db::Vector (-20, 1000)) };
|
|
|
|
|
|
|
|
|
|
db::Trans tt;
|
|
|
|
|
for (unsigned int p = 0; p < 1000; ++p) {
|
|
|
|
|
if ((p % 17) == 0) {
|
|
|
|
|
c0.insert (db::CellInstArray (db::CellInst (cells[(p * 23) % (sizeof (cells) / sizeof (cells [0]))]->cell_index ()), tt));
|
|
|
|
|
} else {
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (cells[(p * 23) % (sizeof (cells) / sizeof (cells [0]))]->cell_index ()), tt), p % 17));
|
|
|
|
|
}
|
|
|
|
|
tt *= trans[p % (sizeof (trans) / sizeof (trans [0]))];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g.update ();
|
|
|
|
|
|
|
|
|
|
std::string r;
|
|
|
|
|
for (db::Cell::child_cell_iterator cc = c0.begin_child_cells (); ! cc.at_end (); ++cc) {
|
|
|
|
|
if (r != "") {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (*cc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (r, "1,2,3,4");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(6)
|
|
|
|
|
{
|
2020-02-04 20:50:46 +01:00
|
|
|
db::Manager m (true);
|
2017-02-12 13:21:08 +01:00
|
|
|
db::Layout g (&m);
|
|
|
|
|
db::Cell &c0 (g.cell (g.add_cell ()));
|
|
|
|
|
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::Trans tt;
|
|
|
|
|
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), tt));
|
|
|
|
|
c0.insert (db::CellInstArray (db::CellInst (c2.cell_index ()), tt));
|
|
|
|
|
c0.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), tt));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c1.cell_index ()), tt), 0));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c2.cell_index ()), tt), 1));
|
|
|
|
|
c0.insert (db::CellInstArrayWithProperties (db::CellInstArray (db::CellInst (c3.cell_index ()), tt), 2));
|
|
|
|
|
|
|
|
|
|
g.update ();
|
|
|
|
|
|
|
|
|
|
std::string r;
|
|
|
|
|
for (db::Cell::child_cell_iterator cc = c0.begin_child_cells (); ! cc.at_end (); ++cc) {
|
|
|
|
|
if (r != "") {
|
|
|
|
|
r += ",";
|
|
|
|
|
}
|
|
|
|
|
r += tl::to_string (*cc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#0,3[r0 *1 0,0]#0,1[r0 *1 0,0]#0,2[r0 *1 0,0]#1,3[r0 *1 0,0]#2");
|
|
|
|
|
|
|
|
|
|
db::Cell &cc (g.cell (g.add_cell ()));
|
|
|
|
|
cc = c0;
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(cc), "1[r0 *1 0,0]#0,2[r0 *1 0,0]#0,3[r0 *1 0,0]#0,1[r0 *1 0,0]#0,2[r0 *1 0,0]#1,3[r0 *1 0,0]#2");
|
|
|
|
|
|
|
|
|
|
// Note: iterating and replace does not work in non-editable mode
|
|
|
|
|
if (db::default_editable_mode ()) {
|
|
|
|
|
|
|
|
|
|
for (db::Cell::const_iterator i = cc.begin (); ! i.at_end (); ++i) {
|
|
|
|
|
cc.replace_prop_id (*i, i->prop_id () + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(cc), "1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#3,1[r0 *1 0,0]#1,2[r0 *1 0,0]#1,3[r0 *1 0,0]#1");
|
|
|
|
|
|
|
|
|
|
for (db::Cell::const_iterator i = c0.begin (); ! i.at_end (); ++i) {
|
|
|
|
|
c0.replace (*i, db::CellInstArrayWithProperties (i->cell_inst (), i->prop_id () + 1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (c2s_unsorted(c0), "1[r0 *1 0,0]#1,2[r0 *1 0,0]#2,3[r0 *1 0,0]#3,1[r0 *1 0,0]#1,2[r0 *1 0,0]#1,3[r0 *1 0,0]#1");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 00:38:08 +02:00
|
|
|
TEST(10_HasShapesTouching)
|
|
|
|
|
{
|
|
|
|
|
db::Layout ly;
|
|
|
|
|
unsigned int l1 = ly.insert_layer (db::LayerProperties (1, 0));
|
|
|
|
|
|
|
|
|
|
db::Cell &a = ly.cell (ly.add_cell ("A"));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
|
|
|
|
|
|
|
|
|
a.shapes (l1).insert (db::Box (-100, -100, 0, 0));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 100, 100)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 1, 100, 100)), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, -1, 100, 100)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (-1, -1, -1, -1)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (1, 1, 1, 1)), false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(11_HasShapesTouchingWithHier)
|
|
|
|
|
{
|
|
|
|
|
db::Layout ly;
|
|
|
|
|
unsigned int l1 = ly.insert_layer (db::LayerProperties (1, 0));
|
|
|
|
|
unsigned int l2 = ly.insert_layer (db::LayerProperties (2, 0));
|
|
|
|
|
|
|
|
|
|
db::Cell &a = ly.cell (ly.add_cell ("A"));
|
|
|
|
|
db::Cell &b = ly.cell (ly.add_cell ("B"));
|
|
|
|
|
|
|
|
|
|
a.insert (db::CellInstArray (b.cell_index (), db::Trans (db::Vector (100, 100)), db::Vector (0, 200), db::Vector (200, 0), 2, 2));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l2, db::Box ()), false);
|
|
|
|
|
|
|
|
|
|
b.shapes (l1).insert (db::Box (0, 0, 10, 10));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box ()), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 100, 100)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l2, db::Box (0, 0, 100, 100)), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 99, 100)), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (0, 0, 100, 99)), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (100, 100, 110, 110)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (150, 150, 160, 160)), false);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (300, 300, 310, 310)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (300, 100, 310, 110)), true);
|
|
|
|
|
EXPECT_EQ (a.has_shapes_touching (l1, db::Box (300, 400, 310, 410)), false);
|
|
|
|
|
}
|