mirror of https://github.com/KLayout/klayout.git
WIP: Some hardening against internal state changes in RecursiveShapeIterator, tests fixed
This commit is contained in:
parent
1c8442f485
commit
0452e91e8c
|
|
@ -402,10 +402,11 @@ static size_t s_instance_count = 0;
|
||||||
static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si)
|
static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si)
|
||||||
{
|
{
|
||||||
unsigned int layer_index = layout.insert_layer ();
|
unsigned int layer_index = layout.insert_layer ();
|
||||||
|
unsigned int iter_layer = si.multiple_layers () ? si.layers ().front () : si.layer ();
|
||||||
|
|
||||||
if (si.layout () && si.layer () < si.layout ()->layers ()) {
|
if (si.layout () && iter_layer < si.layout ()->layers ()) {
|
||||||
// try to preserve the layer properties
|
// try to preserve the layer properties
|
||||||
layout.set_properties (layer_index, si.layout ()->get_properties (si.layer ()));
|
layout.set_properties (layer_index, si.layout ()->get_properties (iter_layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
return layer_index;
|
return layer_index;
|
||||||
|
|
|
||||||
|
|
@ -190,11 +190,15 @@ OriginalLayerRegion::min_coherence_changed ()
|
||||||
size_t
|
size_t
|
||||||
OriginalLayerRegion::count () const
|
OriginalLayerRegion::count () const
|
||||||
{
|
{
|
||||||
if (m_iter.has_complex_region () || m_iter.region () != db::Box::world () || ! m_iter.enables ().empty () || ! m_iter.disables ().empty ()) {
|
// NOTE: we should to make sure the iterator isn't validated as this would spoil the usability or OriginalLayerRegion upon
|
||||||
|
// layout changes
|
||||||
|
db::RecursiveShapeIterator iter = m_iter;
|
||||||
|
|
||||||
|
if (iter.has_complex_region () || iter.region () != db::Box::world () || ! iter.enables ().empty () || ! iter.disables ().empty ()) {
|
||||||
|
|
||||||
// complex case with a search region - use the iterator to determine the count (expensive)
|
// complex case with a search region - use the iterator to determine the count (expensive)
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (db::RecursiveShapeIterator i = m_iter; ! i.at_end (); ++i) {
|
for (db::RecursiveShapeIterator i = iter; ! i.at_end (); ++i) {
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,11 +210,11 @@ OriginalLayerRegion::count () const
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
|
||||||
const db::Layout &layout = *m_iter.layout ();
|
const db::Layout &layout = *iter.layout ();
|
||||||
|
|
||||||
std::set<db::cell_index_type> cells;
|
std::set<db::cell_index_type> cells;
|
||||||
m_iter.top_cell ()->collect_called_cells (cells);
|
iter.top_cell ()->collect_called_cells (cells);
|
||||||
cells.insert (m_iter.top_cell ()->cell_index ());
|
cells.insert (iter.top_cell ()->cell_index ());
|
||||||
|
|
||||||
db::CellCounter cc (&layout);
|
db::CellCounter cc (&layout);
|
||||||
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
|
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
|
||||||
|
|
@ -218,12 +222,12 @@ OriginalLayerRegion::count () const
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
size_t nn = 0;
|
size_t nn = 0;
|
||||||
if (m_iter.multiple_layers ()) {
|
if (iter.multiple_layers ()) {
|
||||||
for (std::vector<unsigned int>::const_iterator l = m_iter.layers ().begin (); l != m_iter.layers ().end (); ++l) {
|
for (std::vector<unsigned int>::const_iterator l = iter.layers ().begin (); l != iter.layers ().end (); ++l) {
|
||||||
nn += layout.cell (*c).shapes (*l).size (m_iter.shape_flags ());
|
nn += layout.cell (*c).shapes (*l).size (iter.shape_flags ());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nn += layout.cell (*c).shapes (m_iter.layer ()).size (m_iter.shape_flags ());
|
nn += layout.cell (*c).shapes (iter.layer ()).size (iter.shape_flags ());
|
||||||
}
|
}
|
||||||
n += cc.weight (*c) * nn;
|
n += cc.weight (*c) * nn;
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +240,11 @@ OriginalLayerRegion::count () const
|
||||||
size_t
|
size_t
|
||||||
OriginalLayerRegion::hier_count () const
|
OriginalLayerRegion::hier_count () const
|
||||||
{
|
{
|
||||||
if (m_iter.has_complex_region () || m_iter.region () != db::Box::world ()) {
|
// NOTE: we should to make sure the iterator isn't validated as this would spoil the usability or OriginalLayerRegion upon
|
||||||
|
// layout changes
|
||||||
|
db::RecursiveShapeIterator iter = m_iter;
|
||||||
|
|
||||||
|
if (iter.has_complex_region () || iter.region () != db::Box::world ()) {
|
||||||
|
|
||||||
// TODO: how to establish a "hierarchical" interpretation in this case?
|
// TODO: how to establish a "hierarchical" interpretation in this case?
|
||||||
return count ();
|
return count ();
|
||||||
|
|
@ -245,22 +253,22 @@ OriginalLayerRegion::hier_count () const
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
|
||||||
const db::Layout &layout = *m_iter.layout ();
|
const db::Layout &layout = *iter.layout ();
|
||||||
|
|
||||||
std::set<db::cell_index_type> cells;
|
std::set<db::cell_index_type> cells;
|
||||||
m_iter.top_cell ()->collect_called_cells (cells);
|
iter.top_cell ()->collect_called_cells (cells);
|
||||||
cells.insert (m_iter.top_cell ()->cell_index ());
|
cells.insert (iter.top_cell ()->cell_index ());
|
||||||
|
|
||||||
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
|
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
|
||||||
if (cells.find (*c) == cells.end ()) {
|
if (cells.find (*c) == cells.end ()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_iter.multiple_layers ()) {
|
if (iter.multiple_layers ()) {
|
||||||
for (std::vector<unsigned int>::const_iterator l = m_iter.layers ().begin (); l != m_iter.layers ().end (); ++l) {
|
for (std::vector<unsigned int>::const_iterator l = iter.layers ().begin (); l != iter.layers ().end (); ++l) {
|
||||||
n += layout.cell (*c).shapes (*l).size (m_iter.shape_flags ());
|
n += layout.cell (*c).shapes (*l).size (iter.shape_flags ());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n += layout.cell (*c).shapes (m_iter.layer ()).size (m_iter.shape_flags ());
|
n += layout.cell (*c).shapes (iter.layer ()).size (iter.shape_flags ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -550,11 +550,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the layer of the current shape
|
* @brief Gets the layer of the current shape
|
||||||
*/
|
*/
|
||||||
unsigned int layer () const
|
unsigned int layer () const
|
||||||
{
|
{
|
||||||
validate (0);
|
if (m_has_layers) {
|
||||||
|
validate (0);
|
||||||
|
}
|
||||||
return m_layer;
|
return m_layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -562,7 +564,7 @@ public:
|
||||||
* @brief Gets the layers from which the shapes are taken from
|
* @brief Gets the layers from which the shapes are taken from
|
||||||
*
|
*
|
||||||
* The returned layers are useful only if \multiple_layers is
|
* The returned layers are useful only if \multiple_layers is
|
||||||
* true.
|
* true. Otherwise use \layer to get the iterated layer.
|
||||||
*/
|
*/
|
||||||
const std::vector<unsigned int> &layers () const
|
const std::vector<unsigned int> &layers () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue