RecursiveInstanceIterator uses weak pointer to Layout too

This commit is contained in:
Matthias Koefferlein 2022-02-07 22:09:57 +01:00
parent c0b38f3706
commit 79be9aba41
3 changed files with 51 additions and 8 deletions

View File

@ -83,7 +83,6 @@ RecursiveInstanceIterator &RecursiveInstanceIterator::operator= (const Recursive
RecursiveInstanceIterator::RecursiveInstanceIterator ()
{
// anything. Not necessary reasonable.
mp_layout = 0;
mp_top_cell = 0;
mp_cell = 0;
m_overlapping = false;
@ -97,7 +96,7 @@ RecursiveInstanceIterator::RecursiveInstanceIterator ()
RecursiveInstanceIterator::RecursiveInstanceIterator (const layout_type &layout, const cell_type &cell, const box_type &region, bool overlapping)
: m_box_convert (layout)
{
mp_layout = &layout;
mp_layout = const_cast<db::Layout *> (&layout);
mp_top_cell = &cell;
m_overlapping = overlapping;
init ();
@ -107,7 +106,7 @@ RecursiveInstanceIterator::RecursiveInstanceIterator (const layout_type &layout,
RecursiveInstanceIterator::RecursiveInstanceIterator (const layout_type &layout, const cell_type &cell, const region_type &region, bool overlapping)
: m_box_convert (layout)
{
mp_layout = &layout;
mp_layout = const_cast<db::Layout *> (&layout);
mp_top_cell = &cell;
m_overlapping = overlapping;
init ();
@ -117,7 +116,7 @@ RecursiveInstanceIterator::RecursiveInstanceIterator (const layout_type &layout,
RecursiveInstanceIterator::RecursiveInstanceIterator (const layout_type &layout, const cell_type &cell)
: m_box_convert (layout)
{
mp_layout = &layout;
mp_layout = const_cast<db::Layout *> (&layout);
mp_top_cell = &cell;
m_overlapping = false;
init ();
@ -272,6 +271,7 @@ RecursiveInstanceIterator::validate (RecursiveInstanceReceiver *receiver) const
m_inst_array_iterators.clear ();
m_cells.clear ();
m_trans = cplx_trans_type ();
m_target_tree.clear ();
m_local_region_stack.clear ();
m_local_region_stack.push_back (m_region);
@ -300,10 +300,9 @@ RecursiveInstanceIterator::validate (RecursiveInstanceReceiver *receiver) const
}
if (mp_top_cell) {
if (mp_top_cell && mp_layout) {
if (! m_all_targets) {
m_target_tree.clear ();
mp_top_cell->collect_called_cells (m_target_tree);
}
@ -501,6 +500,8 @@ RecursiveInstanceIterator::next_instance (RecursiveInstanceReceiver *receiver) c
void
RecursiveInstanceIterator::down (RecursiveInstanceReceiver *receiver) const
{
tl_assert (mp_layout);
m_trans_stack.push_back (m_trans);
m_cells.push_back (mp_cell);

View File

@ -29,6 +29,7 @@
#include "dbLayout.h"
#include "dbInstElement.h"
#include "tlAssert.h"
#include "tlObject.h"
#include <map>
#include <set>
@ -180,7 +181,7 @@ public:
*/
const layout_type *layout () const
{
return mp_layout;
return mp_layout.get ();
}
/**
@ -544,7 +545,7 @@ private:
std::set<db::cell_index_type> m_targets;
bool m_all_targets;
const layout_type *mp_layout;
tl::weak_ptr<layout_type> mp_layout;
const cell_type *mp_top_cell;
box_type m_region;

View File

@ -619,3 +619,44 @@ TEST(4)
EXPECT_EQ (db::compare_layouts (boxes2layout (selected_boxes), boxes2layout (selected_boxes2), db::layout_diff::f_verbose, 0, 100 /*max diff lines*/), true);
}
TEST(5)
{
std::unique_ptr<db::Layout> g (new db::Layout ());
g->insert_layer (0);
g->insert_layer (1);
g->insert_layer (2);
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::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");
g.reset (new db::Layout ());
// now the layout is gone and the iterator stays silent (weak pointer to layout)
// NOTE: this only works on reset or re-initialization. Not during iteration.
i1.reset ();
x = collect(i1, *g);
EXPECT_EQ (x, "");
}