diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index a62894e47..9005de616 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1298,7 +1298,7 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const // simplified handling for a box db::Box b = bbox ().enlarged (db::Vector (dx, dy)); - return region_from_box (b, properties_repository (), begin ()->prop_id ()); + return region_from_box (b, properties_repository (), db::RegionIterator (begin ()).prop_id ()); } else if (! merged_semantics () || is_merged ()) { @@ -1478,13 +1478,13 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const } else if (is_box () && other.is_box ()) { - if (pc_skip (property_constraint) || pc_match (property_constraint, begin ()->prop_id (), other.begin ().prop_id ())) { + if (pc_skip (property_constraint) || pc_match (property_constraint, db::RegionIterator (begin ()).prop_id (), other.begin ().prop_id ())) { // Simplified handling for boxes db::Box b = bbox (); b &= other.bbox (); - db::properties_id_type prop_id_out = pc_norm (property_constraint, begin ()->prop_id ()); + db::properties_id_type prop_id_out = pc_norm (property_constraint, db::RegionIterator (begin ()).prop_id ()); return region_from_box (b, properties_repository (), prop_id_out); @@ -1494,7 +1494,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const } else if (is_box () && ! other.strict_handling ()) { - db::properties_id_type self_prop_id = pc_skip (property_constraint) ? 0 : begin ()->prop_id (); + db::properties_id_type self_prop_id = pc_skip (property_constraint) ? 0 : db::RegionIterator (begin ()).prop_id (); // map AND with box to clip .. db::Box b = bbox (); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 5acb010f8..b9b954408 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -784,7 +784,6 @@ RegionDelegate * DeepRegion::and_with (const Region &other, PropertyConstraint property_constraint) const { const DeepRegion *other_deep = dynamic_cast (other.delegate ()); - if (empty ()) { return clone ()->remove_properties (pc_remove (property_constraint)); diff --git a/src/db/db/dbGenericShapeIterator.h b/src/db/db/dbGenericShapeIterator.h index c4abf65a7..0867dc009 100644 --- a/src/db/db/dbGenericShapeIterator.h +++ b/src/db/db/dbGenericShapeIterator.h @@ -31,6 +31,9 @@ namespace db { +template +class generic_shape_iterator; + template class DB_PUBLIC generic_shape_iterator_delegate_base { @@ -40,6 +43,9 @@ class DB_PUBLIC generic_shape_iterator_delegate_base generic_shape_iterator_delegate_base () { } virtual ~generic_shape_iterator_delegate_base () { } +protected: + friend class generic_shape_iterator; + virtual void do_reset (const db::Box & /*region*/, bool /*overlapping*/) { } virtual db::Box bbox () const { return db::Box::world (); } virtual bool is_addressable () const = 0; @@ -62,6 +68,7 @@ class DB_PUBLIC generic_shape_iterator_delegate2 : m_iter (from), m_from (from), m_to (to) { } +protected: virtual bool is_addressable () const { return addressable; @@ -122,6 +129,7 @@ class DB_PUBLIC generic_shape_iterator_delegate1 : m_iter (from), m_from (from) { } +protected: virtual bool is_addressable () const { return addressable; @@ -185,6 +193,7 @@ class DB_PUBLIC generic_shapes_iterator_delegate set (); } +protected: virtual bool is_addressable () const { return m_is_addressable; diff --git a/testdata/ruby/dbRegionTest.rb b/testdata/ruby/dbRegionTest.rb index 149c23171..a59478a11 100644 --- a/testdata/ruby/dbRegionTest.rb +++ b/testdata/ruby/dbRegionTest.rb @@ -1498,6 +1498,36 @@ def test_extended_iter end + # issue #1955 (locking of layout object inside DSS) + def test_issue1955 + + ly = RBA::Layout::new + top = ly.create_cell("TOP") + l1 = ly.layer(1, 0) + + dss = RBA::DeepShapeStore::new + + rr = RBA::Region::new(RBA::Box::new(100, 100, 1100, 1100)) + + r = RBA::Region::new(top.begin_shapes_rec(l1), dss) + r += RBA::Region::new(RBA::Box::new(0, 0, 1000, 1000)) + + # this spoils the dss object, if + # 1. the first region is a deep region + # 2. the second region is a flat region + # 3. both regions are boxes + # after this operation, bounding boxes are no + # longer updated inside the DSS. + randrr = r & rr + assert_equal(randrr.to_s, "(100,100;100,1000;1000,1000;1000,100)") + + r += RBA::Region::new(RBA::Box::new(1000, 1000, 2000, 2000)) + + assert_equal(r.to_s, "(0,0;0,1000;1000,1000;1000,0);(1000,1000;1000,2000;2000,2000;2000,1000)") + assert_equal(r.bbox.to_s, "(0,0;2000,2000)") + + end + end load("test_epilogue.rb")