From 8ac08778c262d7596de89fdb4662479fee13a84b Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 19 Jan 2023 00:25:07 +0100 Subject: [PATCH] WIP: reworked and implemented a property translation/selection/enabling scheme for the shape containers + GSI binding. --- src/db/db/db.pro | 1 + src/db/db/dbDeepEdgePairs.cc | 5 + src/db/db/dbDeepEdgePairs.h | 1 + src/db/db/dbDeepEdges.cc | 5 + src/db/db/dbDeepEdges.h | 1 + src/db/db/dbDeepRegion.cc | 5 + src/db/db/dbDeepRegion.h | 1 + src/db/db/dbDeepShapeStore.cc | 9 +- src/db/db/dbDeepTexts.cc | 5 + src/db/db/dbDeepTexts.h | 1 + src/db/db/dbEdgePairsDelegate.h | 1 + src/db/db/dbEdgesDelegate.h | 1 + src/db/db/dbEmptyEdgePairs.h | 1 + src/db/db/dbEmptyEdges.h | 1 + src/db/db/dbEmptyRegion.h | 1 + src/db/db/dbEmptyTexts.h | 1 + src/db/db/dbFlatEdgePairs.cc | 7 + src/db/db/dbFlatEdgePairs.h | 1 + src/db/db/dbFlatEdges.cc | 7 + src/db/db/dbFlatEdges.h | 1 + src/db/db/dbFlatRegion.cc | 7 + src/db/db/dbFlatRegion.h | 1 + src/db/db/dbFlatTexts.cc | 7 + src/db/db/dbFlatTexts.h | 1 + src/db/db/dbHierarchyBuilder.cc | 12 +- src/db/db/dbHierarchyBuilder.h | 1 - src/db/db/dbOriginalLayerEdgePairs.cc | 8 +- src/db/db/dbOriginalLayerEdgePairs.h | 1 + src/db/db/dbOriginalLayerEdges.cc | 8 +- src/db/db/dbOriginalLayerEdges.h | 1 + src/db/db/dbOriginalLayerRegion.cc | 8 +- src/db/db/dbOriginalLayerRegion.h | 1 + src/db/db/dbOriginalLayerTexts.cc | 8 +- src/db/db/dbOriginalLayerTexts.h | 1 + src/db/db/dbPropertiesRepository.cc | 130 +++++++++++++++++ src/db/db/dbPropertiesRepository.h | 111 +++++++++++++++ src/db/db/dbRecursiveShapeIterator.cc | 2 + src/db/db/dbRecursiveShapeIterator.h | 51 +++++++ src/db/db/dbRegion.cc | 18 +-- src/db/db/dbRegion.h | 14 -- src/db/db/dbRegionDelegate.h | 2 + src/db/db/dbShapeCollection.cc | 93 ++++++++++++ src/db/db/dbShapeCollection.h | 50 +++++-- src/db/db/dbShapes.h | 1 - src/db/db/dbTextsDelegate.h | 1 + src/db/db/gsiDeclDbContainerHelpers.h | 101 +++++++++++++ src/db/db/gsiDeclDbEdgePairs.cc | 6 +- src/db/db/gsiDeclDbEdges.cc | 6 +- src/db/db/gsiDeclDbRegion.cc | 6 +- src/db/db/gsiDeclDbShapes.cc | 5 - src/db/db/gsiDeclDbTexts.cc | 6 +- src/db/unit_tests/dbAsIfFlatRegionTests.cc | 22 +-- src/db/unit_tests/dbDeepRegionTests.cc | 22 +-- .../unit_tests/dbPropertiesRepositoryTests.cc | 133 ++++++++++++++++++ src/db/unit_tests/dbRegionTests.cc | 4 +- 55 files changed, 809 insertions(+), 96 deletions(-) create mode 100644 src/db/db/gsiDeclDbContainerHelpers.h diff --git a/src/db/db/db.pro b/src/db/db/db.pro index ee55133a2..74c06e0d8 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -375,6 +375,7 @@ HEADERS = \ dbRegionUtils.h \ dbEdgesUtils.h \ dbRegionProcessors.h \ + gsiDeclDbContainerHelpers.h \ gsiDeclDbHelpers.h \ dbNetlistCompare.h \ dbNetlistReader.h \ diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 8ee1c8d41..9b63199cb 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -314,6 +314,11 @@ const db::RecursiveShapeIterator *DeepEdgePairs::iter () const return 0; } +void DeepEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt) +{ + DeepShapeCollectionDelegateBase::apply_property_translator (pt); +} + db::PropertiesRepository *DeepEdgePairs::properties_repository () { return &deep_layer ().layout ().properties_repository (); diff --git a/src/db/db/dbDeepEdgePairs.h b/src/db/db/dbDeepEdgePairs.h index fd5c453e0..ee1076ae2 100644 --- a/src/db/db/dbDeepEdgePairs.h +++ b/src/db/db/dbDeepEdgePairs.h @@ -72,6 +72,7 @@ public: virtual const db::EdgePair *nth (size_t n) const; virtual bool has_valid_edge_pairs () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 06fb10204..ee4a2e336 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -454,6 +454,11 @@ DeepEdges::iter () const return 0; } +void DeepEdges::apply_property_translator (const db::PropertiesTranslator &pt) +{ + DeepShapeCollectionDelegateBase::apply_property_translator (pt); +} + db::PropertiesRepository *DeepEdges::properties_repository () { return &deep_layer ().layout ().properties_repository (); diff --git a/src/db/db/dbDeepEdges.h b/src/db/db/dbDeepEdges.h index 7944e1b57..78fb04935 100644 --- a/src/db/db/dbDeepEdges.h +++ b/src/db/db/dbDeepEdges.h @@ -80,6 +80,7 @@ public: virtual bool has_valid_merged_edges () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 5d74f8dd6..b6fe07871 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -475,6 +475,11 @@ DeepRegion::iter () const return 0; } +void DeepRegion::apply_property_translator (const db::PropertiesTranslator &pt) +{ + DeepShapeCollectionDelegateBase::apply_property_translator (pt); +} + db::PropertiesRepository *DeepRegion::properties_repository () { return &deep_layer ().layout ().properties_repository (); diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index f6f41a481..6f24ff3f4 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -79,6 +79,7 @@ public: virtual bool has_valid_merged_polygons () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 387d401de..e0d22e9a4 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -477,7 +477,6 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n // try to maintain the texts on top level - go through shape iterator std::pair ii = region.begin_iter (); - bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0); db::ICplxTrans ttop = trans * ii.second; // The chain of operators for producing clipped and reduced polygon references @@ -489,7 +488,7 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n if (for_netlist && ii.first->is_text () && ii.first.layout () && ii.first.cell () != ii.first.top_cell ()) { // Skip texts on levels below top cell. For the reasoning see the description of this method. } else { - red.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes); + red.push (*ii.first, ii.first.prop_id (), ttop * ii.first.trans (), world, 0, shapes); } ++ii.first; @@ -518,12 +517,11 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Edges &edges, const db::IC db::Box world = db::Box::world (); std::pair ii = edges.begin_iter (); - bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0); db::ICplxTrans ttop = trans * ii.second; db::EdgeBuildingHierarchyBuilderShapeReceiver eb (&layout (), ii.first.layout (), false); while (! ii.first.at_end ()) { - eb.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes); + eb.push (*ii.first, ii.first.prop_id (), ttop * ii.first.trans (), world, 0, shapes); ++ii.first; } @@ -549,13 +547,12 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Texts &texts, const db::IC db::Box world = db::Box::world (); std::pair ii = texts.begin_iter (); - bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0); db::ICplxTrans ttop = trans * ii.second; db::TextBuildingHierarchyBuilderShapeReceiver tb (&layout (), ii.first.layout ()); while (! ii.first.at_end ()) { - tb.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes); + tb.push (*ii.first, ii.first.prop_id (), ttop * ii.first.trans (), world, 0, shapes); ++ii.first; } diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 412b8ab51..e5e282f87 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -338,6 +338,11 @@ const db::RecursiveShapeIterator *DeepTexts::iter () const return 0; } +void DeepTexts::apply_property_translator (const db::PropertiesTranslator &pt) +{ + DeepShapeCollectionDelegateBase::apply_property_translator (pt); +} + db::PropertiesRepository *DeepTexts::properties_repository () { return &deep_layer ().layout ().properties_repository (); diff --git a/src/db/db/dbDeepTexts.h b/src/db/db/dbDeepTexts.h index f98ba572b..d139147ad 100644 --- a/src/db/db/dbDeepTexts.h +++ b/src/db/db/dbDeepTexts.h @@ -73,6 +73,7 @@ public: virtual const db::Text *nth (size_t n) const; virtual bool has_valid_texts () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbEdgePairsDelegate.h b/src/db/db/dbEdgePairsDelegate.h index 960b01d02..4ea093ede 100644 --- a/src/db/db/dbEdgePairsDelegate.h +++ b/src/db/db/dbEdgePairsDelegate.h @@ -205,6 +205,7 @@ public: virtual bool has_valid_edge_pairs () const = 0; virtual const db::RecursiveShapeIterator *iter () const = 0; + virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0; virtual db::PropertiesRepository *properties_repository () = 0; virtual const db::PropertiesRepository *properties_repository () const = 0; diff --git a/src/db/db/dbEdgesDelegate.h b/src/db/db/dbEdgesDelegate.h index 32ef0dea6..cba4e40f9 100644 --- a/src/db/db/dbEdgesDelegate.h +++ b/src/db/db/dbEdgesDelegate.h @@ -340,6 +340,7 @@ public: virtual bool has_valid_merged_edges () const = 0; virtual const db::RecursiveShapeIterator *iter () const = 0; + virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0; virtual db::PropertiesRepository *properties_repository () = 0; virtual const db::PropertiesRepository *properties_repository () const = 0; diff --git a/src/db/db/dbEmptyEdgePairs.h b/src/db/db/dbEmptyEdgePairs.h index 7034aafdb..dee797a24 100644 --- a/src/db/db/dbEmptyEdgePairs.h +++ b/src/db/db/dbEmptyEdgePairs.h @@ -73,6 +73,7 @@ public: virtual bool has_valid_edge_pairs () const { return true; } virtual const db::RecursiveShapeIterator *iter () const { return 0; } + virtual void apply_property_translator (const db::PropertiesTranslator &) { } virtual db::PropertiesRepository *properties_repository () { return 0; } virtual const db::PropertiesRepository *properties_repository () const { return 0; } diff --git a/src/db/db/dbEmptyEdges.h b/src/db/db/dbEmptyEdges.h index ce5bcaa84..3e1574fe7 100644 --- a/src/db/db/dbEmptyEdges.h +++ b/src/db/db/dbEmptyEdges.h @@ -122,6 +122,7 @@ public: virtual bool has_valid_merged_edges () const { return true; } virtual const db::RecursiveShapeIterator *iter () const { return 0; } + virtual void apply_property_translator (const db::PropertiesTranslator &) { } virtual db::PropertiesRepository *properties_repository () { return 0; } virtual const db::PropertiesRepository *properties_repository () const { return 0; } diff --git a/src/db/db/dbEmptyRegion.h b/src/db/db/dbEmptyRegion.h index 030741bc0..44ef8470c 100644 --- a/src/db/db/dbEmptyRegion.h +++ b/src/db/db/dbEmptyRegion.h @@ -141,6 +141,7 @@ public: virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); } virtual const db::RecursiveShapeIterator *iter () const { return 0; } + virtual void apply_property_translator (const db::PropertiesTranslator &) { } virtual db::PropertiesRepository *properties_repository () { return 0; } virtual const db::PropertiesRepository *properties_repository () const { return 0; } diff --git a/src/db/db/dbEmptyTexts.h b/src/db/db/dbEmptyTexts.h index e401f1dc0..903d58972 100644 --- a/src/db/db/dbEmptyTexts.h +++ b/src/db/db/dbEmptyTexts.h @@ -71,6 +71,7 @@ public: virtual bool has_valid_texts () const { return true; } virtual const db::RecursiveShapeIterator *iter () const { return 0; } + virtual void apply_property_translator (const db::PropertiesTranslator &) { } virtual db::PropertiesRepository *properties_repository () { return 0; } virtual const db::PropertiesRepository *properties_repository () const { return 0; } diff --git a/src/db/db/dbFlatEdgePairs.cc b/src/db/db/dbFlatEdgePairs.cc index 1a0a751e1..2d1a0d3ae 100644 --- a/src/db/db/dbFlatEdgePairs.cc +++ b/src/db/db/dbFlatEdgePairs.cc @@ -188,6 +188,13 @@ const db::RecursiveShapeIterator *FlatEdgePairs::iter () const return 0; } +void FlatEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt) +{ + db::Shapes new_edge_pairs; + new_edge_pairs.assign (*mp_edge_pairs, pt); + mp_edge_pairs->swap (new_edge_pairs); +} + db::PropertiesRepository *FlatEdgePairs::properties_repository () { return mp_properties_repository.get_non_const (); diff --git a/src/db/db/dbFlatEdgePairs.h b/src/db/db/dbFlatEdgePairs.h index 9cd75c52f..f6a9c4d3c 100644 --- a/src/db/db/dbFlatEdgePairs.h +++ b/src/db/db/dbFlatEdgePairs.h @@ -78,6 +78,7 @@ public: virtual bool has_valid_edge_pairs () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbFlatEdges.cc b/src/db/db/dbFlatEdges.cc index e3c9dfa99..a64d71603 100644 --- a/src/db/db/dbFlatEdges.cc +++ b/src/db/db/dbFlatEdges.cc @@ -345,6 +345,13 @@ const db::RecursiveShapeIterator *FlatEdges::iter () const return 0; } +void FlatEdges::apply_property_translator (const db::PropertiesTranslator &pt) +{ + db::Shapes new_edges; + new_edges.assign (*mp_edges, pt); + mp_edges->swap (new_edges); +} + db::PropertiesRepository *FlatEdges::properties_repository () { return mp_properties_repository.get_non_const (); diff --git a/src/db/db/dbFlatEdges.h b/src/db/db/dbFlatEdges.h index ac24652d9..826b4a83b 100644 --- a/src/db/db/dbFlatEdges.h +++ b/src/db/db/dbFlatEdges.h @@ -93,6 +93,7 @@ public: virtual bool has_valid_merged_edges () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbFlatRegion.cc b/src/db/db/dbFlatRegion.cc index ab4a72209..fcc3b083c 100644 --- a/src/db/db/dbFlatRegion.cc +++ b/src/db/db/dbFlatRegion.cc @@ -419,6 +419,13 @@ const db::RecursiveShapeIterator *FlatRegion::iter () const return 0; } +void FlatRegion::apply_property_translator (const db::PropertiesTranslator &pt) +{ + db::Shapes new_polygons; + new_polygons.assign (*mp_polygons, pt); + mp_polygons->swap (new_polygons); +} + db::PropertiesRepository *FlatRegion::properties_repository () { return mp_properties_repository.get_non_const (); diff --git a/src/db/db/dbFlatRegion.h b/src/db/db/dbFlatRegion.h index 9ad4f6e29..f11f20a53 100644 --- a/src/db/db/dbFlatRegion.h +++ b/src/db/db/dbFlatRegion.h @@ -99,6 +99,7 @@ public: virtual bool has_valid_merged_polygons () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbFlatTexts.cc b/src/db/db/dbFlatTexts.cc index a77701c49..3fe27e041 100644 --- a/src/db/db/dbFlatTexts.cc +++ b/src/db/db/dbFlatTexts.cc @@ -188,6 +188,13 @@ const db::RecursiveShapeIterator *FlatTexts::iter () const return 0; } +void FlatTexts::apply_property_translator (const db::PropertiesTranslator &pt) +{ + db::Shapes new_texts; + new_texts.assign (*mp_texts, pt); + mp_texts->swap (new_texts); +} + db::PropertiesRepository *FlatTexts::properties_repository () { return mp_properties_repository.get_non_const (); diff --git a/src/db/db/dbFlatTexts.h b/src/db/db/dbFlatTexts.h index 976f62730..dde68500a 100644 --- a/src/db/db/dbFlatTexts.h +++ b/src/db/db/dbFlatTexts.h @@ -79,6 +79,7 @@ public: virtual bool has_valid_texts () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbHierarchyBuilder.cc b/src/db/db/dbHierarchyBuilder.cc index 8f03feb18..c8a77cbb6 100644 --- a/src/db/db/dbHierarchyBuilder.cc +++ b/src/db/db/dbHierarchyBuilder.cc @@ -152,13 +152,13 @@ static std::pair > compute_clip_variant (const db::Box & } HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe) - : mp_target (target), m_initial_pass (true), m_ignore_properties (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans) + : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans) { set_shape_receiver (pipe); } HierarchyBuilder::HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe) - : mp_target (target), m_initial_pass (true), m_ignore_properties (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans) + : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans) { set_shape_receiver (pipe); } @@ -179,7 +179,6 @@ HierarchyBuilder::reset () { m_initial_pass = true; mp_initial_cell = 0; - m_ignore_properties = true; m_cells_to_be_filled.clear (); m_cell_map.clear (); @@ -245,8 +244,6 @@ HierarchyBuilder::begin (const RecursiveShapeIterator *iter) tl_assert (compare_iterators_with_respect_to_target_hierarchy (m_source, *iter) == 0); } - m_ignore_properties = ((iter->shape_flags () & db::ShapeIterator::RegardProperties) == 0); - m_cell_stack.clear (); m_cells_seen.clear (); @@ -278,7 +275,6 @@ HierarchyBuilder::end (const RecursiveShapeIterator *iter) { tl_assert (! iter->layout () || ! iter->top_cell () || m_cell_stack.size () == 1); - m_ignore_properties = true; m_initial_pass = false; m_cells_seen.clear (); mp_initial_cell = m_cell_stack.empty () ? 0 : m_cell_stack.front ().second.front (); @@ -411,11 +407,11 @@ HierarchyBuilder::new_inst_member (const RecursiveShapeIterator *iter, const db: } void -HierarchyBuilder::shape (const RecursiveShapeIterator * /*iter*/, const db::Shape &shape, const db::ICplxTrans &apply_always, const db::ICplxTrans & /*trans*/, const db::Box ®ion, const box_tree_type *complex_region) +HierarchyBuilder::shape (const RecursiveShapeIterator *iter, const db::Shape &shape, const db::ICplxTrans &apply_always, const db::ICplxTrans & /*trans*/, const db::Box ®ion, const box_tree_type *complex_region) { for (std::vector::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) { db::Shapes &shapes = (*c)->shapes (m_target_layer); - mp_pipe->push (shape, m_ignore_properties ? 0 : shape.prop_id (), m_trans * apply_always, region, complex_region, &shapes); + mp_pipe->push (shape, iter->prop_id (), m_trans * apply_always, region, complex_region, &shapes); } } diff --git a/src/db/db/dbHierarchyBuilder.h b/src/db/db/dbHierarchyBuilder.h index 300aedeb9..4cd47efce 100644 --- a/src/db/db/dbHierarchyBuilder.h +++ b/src/db/db/dbHierarchyBuilder.h @@ -406,7 +406,6 @@ private: tl::weak_ptr mp_target; HierarchyBuilderShapeReceiver *mp_pipe; bool m_initial_pass; - bool m_ignore_properties; db::RecursiveShapeIterator m_source; cell_map_type m_cell_map; original_target_to_variants_map_type m_original_targets_to_variants_map; diff --git a/src/db/db/dbOriginalLayerEdgePairs.cc b/src/db/db/dbOriginalLayerEdgePairs.cc index b160bb522..b1c9ec1b0 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.cc +++ b/src/db/db/dbOriginalLayerEdgePairs.cc @@ -115,7 +115,7 @@ namespace if (! m_rec_iter.at_end ()) { m_rec_iter->edge_pair (m_shape); m_shape.transform (m_iter_trans * m_rec_iter.trans ()); - m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0; + m_prop_id = m_rec_iter.prop_id (); } } @@ -202,6 +202,12 @@ OriginalLayerEdgePairs::iter () const return &m_iter; } +void +OriginalLayerEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt) +{ + m_iter.apply_property_translator (pt); +} + db::PropertiesRepository * OriginalLayerEdgePairs::properties_repository () { diff --git a/src/db/db/dbOriginalLayerEdgePairs.h b/src/db/db/dbOriginalLayerEdgePairs.h index b49494a71..9800c7485 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.h +++ b/src/db/db/dbOriginalLayerEdgePairs.h @@ -56,6 +56,7 @@ public: virtual bool has_valid_edge_pairs () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbOriginalLayerEdges.cc b/src/db/db/dbOriginalLayerEdges.cc index d110f4a17..0dc8ba8ef 100644 --- a/src/db/db/dbOriginalLayerEdges.cc +++ b/src/db/db/dbOriginalLayerEdges.cc @@ -116,7 +116,7 @@ namespace if (! m_rec_iter.at_end ()) { m_rec_iter->edge (m_shape); m_shape.transform (m_iter_trans * m_rec_iter.trans ()); - m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0; + m_prop_id = m_rec_iter.prop_id (); } } @@ -251,6 +251,12 @@ OriginalLayerEdges::iter () const return &m_iter; } +void +OriginalLayerEdges::apply_property_translator (const db::PropertiesTranslator &pt) +{ + m_iter.apply_property_translator (pt); +} + db::PropertiesRepository * OriginalLayerEdges::properties_repository () { diff --git a/src/db/db/dbOriginalLayerEdges.h b/src/db/db/dbOriginalLayerEdges.h index ca8bd4a6f..2136042b2 100644 --- a/src/db/db/dbOriginalLayerEdges.h +++ b/src/db/db/dbOriginalLayerEdges.h @@ -62,6 +62,7 @@ public: virtual bool has_valid_merged_edges () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index 7b7f73dfb..3acfc2012 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -119,7 +119,7 @@ namespace if (! m_rec_iter.at_end ()) { m_rec_iter->polygon (m_polygon); m_polygon.transform (m_iter_trans * m_rec_iter.trans (), false); - m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0; + m_prop_id = m_rec_iter.prop_id (); } } @@ -369,6 +369,12 @@ OriginalLayerRegion::iter () const return &m_iter; } +void +OriginalLayerRegion::apply_property_translator (const db::PropertiesTranslator &pt) +{ + m_iter.apply_property_translator (pt); +} + db::PropertiesRepository * OriginalLayerRegion::properties_repository () { diff --git a/src/db/db/dbOriginalLayerRegion.h b/src/db/db/dbOriginalLayerRegion.h index 79f0fb0c3..8019cc7c8 100644 --- a/src/db/db/dbOriginalLayerRegion.h +++ b/src/db/db/dbOriginalLayerRegion.h @@ -67,6 +67,7 @@ public: virtual bool has_valid_merged_polygons () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbOriginalLayerTexts.cc b/src/db/db/dbOriginalLayerTexts.cc index a60f6e16b..dbc0e068d 100644 --- a/src/db/db/dbOriginalLayerTexts.cc +++ b/src/db/db/dbOriginalLayerTexts.cc @@ -115,7 +115,7 @@ namespace if (! m_rec_iter.at_end ()) { m_rec_iter->text (m_shape); m_shape.transform (m_iter_trans * m_rec_iter.trans ()); - m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::RegardProperties) != 0 ? m_rec_iter->prop_id () : 0; + m_prop_id = m_rec_iter.prop_id (); } } @@ -202,6 +202,12 @@ OriginalLayerTexts::iter () const return &m_iter; } +void +OriginalLayerTexts::apply_property_translator (const db::PropertiesTranslator &pt) +{ + m_iter.apply_property_translator (pt); +} + db::PropertiesRepository * OriginalLayerTexts::properties_repository () { diff --git a/src/db/db/dbOriginalLayerTexts.h b/src/db/db/dbOriginalLayerTexts.h index 1bd1b3ebe..d823e6103 100644 --- a/src/db/db/dbOriginalLayerTexts.h +++ b/src/db/db/dbOriginalLayerTexts.h @@ -56,6 +56,7 @@ public: virtual bool has_valid_texts () const; virtual const db::RecursiveShapeIterator *iter () const; + virtual void apply_property_translator (const db::PropertiesTranslator &pt); virtual db::PropertiesRepository *properties_repository (); virtual const db::PropertiesRepository *properties_repository () const; diff --git a/src/db/db/dbPropertiesRepository.cc b/src/db/db/dbPropertiesRepository.cc index 8f3baff49..99d688d60 100644 --- a/src/db/db/dbPropertiesRepository.cc +++ b/src/db/db/dbPropertiesRepository.cc @@ -213,5 +213,135 @@ PropertiesRepository::translate (const PropertiesRepository &rep, properties_id_ return properties_id (new_pset); } + +// ---------------------------------------------------------------------------------- +// PropertiesRepository implementation + +PropertiesTranslator::PropertiesTranslator () + : m_pass (true), m_null (true) +{ + // .. nothing yet .. +} + +PropertiesTranslator::PropertiesTranslator (bool pass) + : m_pass (pass), m_null (false) +{ + // .. nothing yet .. +} + +PropertiesTranslator::PropertiesTranslator (const std::map &map) + : m_map (map), m_pass (false), m_null (false) +{ + // .. nothing yet .. +} + +PropertiesTranslator +PropertiesTranslator::operator* (const PropertiesTranslator &other) const +{ + if (other.m_pass) { + + // NOTE: by handling this first, "pass_all * null" will give "pass_all" which is desired + // for RecursiveShapeIterator::apply_property_translator. + return *this; + + } else if (m_pass) { + + return other; + + } else { + + std::map new_map; + + for (auto i = other.m_map.begin (); i != other.m_map.end (); ++i) { + auto ii = m_map.find (i->second); + if (ii != m_map.end ()) { + new_map.insert (std::make_pair (i->first, ii->second)); + } + } + + return PropertiesTranslator (new_map); + + } +} + +db::properties_id_type +PropertiesTranslator::operator() (db::properties_id_type id) const +{ + if (m_pass || id == 0) { + return id; + } else { + auto i = m_map.find (id); + return i != m_map.end () ? i->second : 0; + } +} + +PropertiesTranslator +PropertiesTranslator::make_remove_all () +{ + return PropertiesTranslator (false); +} + +PropertiesTranslator +PropertiesTranslator::make_pass_all () +{ + return PropertiesTranslator (true); +} + +PropertiesTranslator +PropertiesTranslator::make_filter (db::PropertiesRepository &repo, const std::set &keys) +{ + std::map map; + std::set names_selected; + + for (auto k = keys.begin (); k != keys.end (); ++k) { + names_selected.insert (repo.prop_name_id (*k)); + } + + db::PropertiesRepository org_repo = repo; + + for (auto p = org_repo.begin (); p != org_repo.end (); ++p) { + db::PropertiesRepository::properties_set new_set; + for (auto i = p->second.begin (); i != p->second.end (); ++i) { + if (names_selected.find (i->first) != names_selected.end ()) { + new_set.insert (*i); + } + } + if (! new_set.empty ()) { + map.insert (std::make_pair (p->first, repo.properties_id (new_set))); + } + } + + return PropertiesTranslator (map); +} + +PropertiesTranslator +PropertiesTranslator::make_key_mapper (db::PropertiesRepository &repo, const std::map &keys) +{ + std::map map; + std::map name_map; + + for (auto k = keys.begin (); k != keys.end (); ++k) { + name_map.insert (std::make_pair (repo.prop_name_id (k->first), repo.prop_name_id (k->second))); + } + + db::PropertiesRepository org_repo = repo; + + for (auto p = org_repo.begin (); p != org_repo.end (); ++p) { + db::PropertiesRepository::properties_set new_set; + for (auto i = p->second.begin (); i != p->second.end (); ++i) { + auto nm = name_map.find (i->first); + if (nm != name_map.end ()) { + new_set.insert (std::make_pair (nm->second, i->second)); + } + } + if (! new_set.empty ()) { + map.insert (std::make_pair (p->first, repo.properties_id (new_set))); + } + } + + return PropertiesTranslator (map); +} + + } // namespace db diff --git a/src/db/db/dbPropertiesRepository.h b/src/db/db/dbPropertiesRepository.h index b17655e3a..1a3a3d11e 100644 --- a/src/db/db/dbPropertiesRepository.h +++ b/src/db/db/dbPropertiesRepository.h @@ -239,6 +239,117 @@ private: db::LayoutStateModel *mp_state_model; }; +/** + * @brief A map for selecting/translating properties + * + * The following rules apply: + * - All non-mapped properties are mapped to 0 (removed) + * - 0 is always mapped to 0 + * - Do not include key or value 0 in the map passed to the constructor + * + * A "pass translator" will pass all IDs unchanged. + * + * Note that a property translator - specifically the filters and + * mappers created by "make_filter" and "make_key_mapper" - are snapshots. + * As creating new filters will generate new property IDs for the mapping + * targets, property translators generated previously may become invalid. + * In general it is safe to concatenate new translators after old ones. + * The old ones will not map the property IDs understood by the new ones, + * but as such IDs cannot become input to the old translator, this should + * not matter. + */ + +class DB_PUBLIC PropertiesTranslator +{ +public: + /** + * @brief Default constructor - this creates a null translator + */ + PropertiesTranslator (); + + /** + * @brief Creates a "pass all" (pass = true) or "remove all" (pass = false) translator + */ + PropertiesTranslator (bool pass); + + /** + * @brief Creates a property ID mapper from a table + */ + PropertiesTranslator (const std::map &map); + + /** + * @brief Gets a value indicating whether the translator is "pass" + */ + bool is_pass () const + { + return m_pass; + } + + /** + * @brief Gets a value indicating whether the translator is "empty" (remove all) + */ + bool is_empty () const + { + return ! m_pass && m_map.empty (); + } + + /** + * @brief Gets a value indicating whether the translator is "null" (default-constructed) + */ + bool is_null () const + { + return m_null; + } + + /** + * @brief Concatenates two translators (the right one first) + */ + PropertiesTranslator operator* (const PropertiesTranslator &other) const; + + /** + * @brief Concatenates two translators (the right one first) - in place version + */ + PropertiesTranslator &operator*= (const PropertiesTranslator &other) + { + *this = this->operator* (other); + return *this; + } + + /** + * @brief Translation of the property ID + */ + db::properties_id_type operator() (db::properties_id_type id) const; + + /** + * @brief Factory: create a "remove all" translator + */ + static PropertiesTranslator make_remove_all (); + + /** + * @brief Factory: create a "pass all" translator + */ + static PropertiesTranslator make_pass_all (); + + /** + * @brief Factory: create a filter translator + * + * The translator delivered by this function will leave only the given keys in the properties. + */ + static PropertiesTranslator make_filter (db::PropertiesRepository &repo, const std::set &keys); + + /** + * @brief Factory: create a key mapper translator + * + * The translator delivered by this function will translate the given keys to new ones + * and remove non-listed keys. + */ + static PropertiesTranslator make_key_mapper (db::PropertiesRepository &repo, const std::map &keys); + +private: + std::map m_map; + bool m_pass, m_null; +}; + /** * @brief Collect memory statistics */ diff --git a/src/db/db/dbRecursiveShapeIterator.cc b/src/db/db/dbRecursiveShapeIterator.cc index aa1ef77eb..af551b6e2 100644 --- a/src/db/db/dbRecursiveShapeIterator.cc +++ b/src/db/db/dbRecursiveShapeIterator.cc @@ -73,6 +73,7 @@ RecursiveShapeIterator &RecursiveShapeIterator::operator= (const RecursiveShapeI m_shape = d.m_shape; m_trans = d.m_trans; m_global_trans = d.m_global_trans; + m_property_translator = d.m_property_translator; m_trans_stack = d.m_trans_stack; m_inst_iterators = d.m_inst_iterators; m_inst_array_iterators = d.m_inst_array_iterators; @@ -284,6 +285,7 @@ RecursiveShapeIterator::init () mp_cell = 0; m_current_layer = 0; m_global_trans = cplx_trans_type (); + m_property_translator = db::PropertiesTranslator (); } void diff --git a/src/db/db/dbRecursiveShapeIterator.h b/src/db/db/dbRecursiveShapeIterator.h index c830c7052..99ffeb1fc 100644 --- a/src/db/db/dbRecursiveShapeIterator.h +++ b/src/db/db/dbRecursiveShapeIterator.h @@ -320,6 +320,41 @@ public: return mp_top_cell; } + /** + * @brief Gets the installed property translator + * + * The property translator is not automatically applied, but available to consumers + * of shapes to perform property translation. + */ + const db::PropertiesTranslator &property_translator () const + { + return m_property_translator; + } + + /** + * @brief Applies a PropertyTranslator + * + * The property translator is available for receivers of the recursive shape + * iterator items. This method will apply an additional property translator + * atop of existing ones. + */ + void apply_property_translator (const db::PropertiesTranslator &pt) + { + m_property_translator = pt * m_property_translator; + } + + /** + * @brief Sets a PropertyTranslator + * + * The property translator is available for receivers of the recursive shape + * iterator items. This method will apply an additional property translator + * atop of existing ones. + */ + void set_property_translator (const db::PropertiesTranslator &pt) + { + m_property_translator = pt; + } + /** * @brief Gets the basic region the iterator is using (will be world if none is set) * In addition to the basic region, a complex region may be defined that is further confining the @@ -648,6 +683,21 @@ public: */ bool at_end () const; + /** + * @brief Gets the translated property ID + * + * This version employs the property translator to deliver the real property ID. + */ + db::properties_id_type prop_id () const + { + if (m_property_translator.is_null ()) { + return 0; + } else { + validate (0); + return m_property_translator (m_shape->prop_id ()); + } + } + /** * @brief Gets the current cell's index */ @@ -765,6 +815,7 @@ private: bool m_overlapping; std::set m_start, m_stop; cplx_trans_type m_global_trans; + db::PropertiesTranslator m_property_translator; tl::weak_ptr mp_layout; const cell_type *mp_top_cell; diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index adf559d88..943e5e137 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -109,22 +109,6 @@ Region::iter () const return *(i ? i : &def_iter); } -const db::PropertiesRepository & -Region::properties_repository () const -{ - static db::PropertiesRepository empty_prop_repo; - const db::PropertiesRepository *r = delegate () ? delegate ()->properties_repository () : 0; - return *(r ? r : &empty_prop_repo); -} - -db::PropertiesRepository & -Region::properties_repository () -{ - db::PropertiesRepository *r = delegate () ? delegate ()->properties_repository () : 0; - tl_assert (r != 0); - return *r; -} - void Region::set_delegate (RegionDelegate *delegate, bool keep_attributes) { @@ -396,6 +380,8 @@ static void fill_texts (const Iter &iter, const std::string &pat, bool pattern, const db::Layout *layout = 0; if (org_deep) { + // NOTE: deep regions can store texts in a special way - as small boxes with a special property attached. + // The property will give the text string. This function can restore these pseudo-texts as Text objects. layout = &org_deep->deep_layer ().layout (); const db::DeepShapeStore *store = org_deep->deep_layer ().store (); if (! store->text_property_name ().is_nil ()) { diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 6812cbe91..eb23d180c 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -1796,20 +1796,6 @@ public: */ const db::RecursiveShapeIterator &iter () const; - /** - * @brief Gets the property repository - * - * Use this object to decode property IDs. - */ - const db::PropertiesRepository &properties_repository () const; - - /** - * @brief Gets the property repository - * - * Use this object to decode and encode property IDs. - */ - db::PropertiesRepository &properties_repository (); - /** * @brief Equality */ diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index 912cc9077..facf84b89 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -316,6 +316,8 @@ public: virtual bool has_valid_merged_polygons () const = 0; virtual const db::RecursiveShapeIterator *iter () const = 0; + + virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0; virtual db::PropertiesRepository *properties_repository () = 0; virtual const db::PropertiesRepository *properties_repository () const = 0; diff --git a/src/db/db/dbShapeCollection.cc b/src/db/db/dbShapeCollection.cc index e69de29bb..948032042 100644 --- a/src/db/db/dbShapeCollection.cc +++ b/src/db/db/dbShapeCollection.cc @@ -0,0 +1,93 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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 "dbShapeCollection.h" +#include "dbPropertiesRepository.h" + +namespace db +{ + +// ------------------------------------------------------------------------------------------------------------- + +DeepShapeCollectionDelegateBase::DeepShapeCollectionDelegateBase () +{ + // .. nothing yet .. +} + +DeepShapeCollectionDelegateBase::DeepShapeCollectionDelegateBase (const DeepShapeCollectionDelegateBase &other) +{ + m_deep_layer = other.m_deep_layer.copy (); +} + +DeepShapeCollectionDelegateBase & +DeepShapeCollectionDelegateBase::operator= (const DeepShapeCollectionDelegateBase &other) +{ + if (this != &other) { + m_deep_layer = other.m_deep_layer.copy (); + } + return *this; +} + +void +DeepShapeCollectionDelegateBase::apply_property_translator (const db::PropertiesTranslator &pt) +{ + db::Layout &layout = m_deep_layer.layout (); + for (auto c = layout.begin (); c != layout.end (); ++c) { + + db::Shapes &shapes = c->shapes (m_deep_layer.layer ()); + + db::Shapes new_shapes; + new_shapes.assign (shapes, pt); + shapes.swap (new_shapes); + + } +} + +// ------------------------------------------------------------------------------------------------------------- +// ShapeCollection implementation + +const db::PropertiesRepository & +ShapeCollection::properties_repository () const +{ + static db::PropertiesRepository empty_prop_repo; + const db::PropertiesRepository *r = get_delegate () ? get_delegate ()->properties_repository () : 0; + return *(r ? r : &empty_prop_repo); +} + +db::PropertiesRepository & +ShapeCollection::properties_repository () +{ + db::PropertiesRepository *r = get_delegate () ? get_delegate ()->properties_repository () : 0; + tl_assert (r != 0); + return *r; +} + +void +ShapeCollection::apply_property_translator (const db::PropertiesTranslator &pt) +{ + if (get_delegate ()) { + get_delegate ()->apply_property_translator (pt); + } +} + +} diff --git a/src/db/db/dbShapeCollection.h b/src/db/db/dbShapeCollection.h index c689db0c9..80005f55e 100644 --- a/src/db/db/dbShapeCollection.h +++ b/src/db/db/dbShapeCollection.h @@ -26,31 +26,25 @@ #include "dbCommon.h" #include "dbDeepShapeStore.h" #include "tlUniqueId.h" +#include "tlVariant.h" #include "gsiObject.h" namespace db { +class PropertiesTranslator; +class PropertiesRepository; + /** * @brief A base class for the deep collection delegates */ class DB_PUBLIC DeepShapeCollectionDelegateBase { public: - DeepShapeCollectionDelegateBase () { } + DeepShapeCollectionDelegateBase (); + DeepShapeCollectionDelegateBase (const DeepShapeCollectionDelegateBase &other); - DeepShapeCollectionDelegateBase (const DeepShapeCollectionDelegateBase &other) - { - m_deep_layer = other.m_deep_layer.copy (); - } - - DeepShapeCollectionDelegateBase &operator= (const DeepShapeCollectionDelegateBase &other) - { - if (this != &other) { - m_deep_layer = other.m_deep_layer.copy (); - } - return *this; - } + DeepShapeCollectionDelegateBase &operator= (const DeepShapeCollectionDelegateBase &other); const db::DeepLayer &deep_layer () const { @@ -62,6 +56,8 @@ public: return m_deep_layer; } + void apply_property_translator (const db::PropertiesTranslator &pt); + protected: virtual void set_deep_layer (const db::DeepLayer &dl) { @@ -83,6 +79,10 @@ public: virtual ~ShapeCollectionDelegateBase () { } virtual DeepShapeCollectionDelegateBase *deep () { return 0; } + + virtual void apply_property_translator (const db::PropertiesTranslator & /*pt*/) = 0; + virtual db::PropertiesRepository *properties_repository () = 0; + virtual const db::PropertiesRepository *properties_repository () const = 0; }; /** @@ -96,6 +96,30 @@ public: virtual ~ShapeCollection () { } virtual ShapeCollectionDelegateBase *get_delegate () const = 0; + + /** + * @brief Applies a PropertyTranslator + * + * This method will translate the property IDs according to the given property translator. + * + * Note that the property translator needs to be built from the PropertiesRepository + * delivered by "properties_repository". + */ + void apply_property_translator (const db::PropertiesTranslator &pt); + + /** + * @brief Gets the property repository + * + * Use this object to decode and encode property IDs. + */ + db::PropertiesRepository &properties_repository (); + + /** + * @brief Gets the property repository (const version) + * + * Use this object to decode property IDs. + */ + const db::PropertiesRepository &properties_repository () const; }; } diff --git a/src/db/db/dbShapes.h b/src/db/db/dbShapes.h index e1c2d0e17..b8114e360 100644 --- a/src/db/db/dbShapes.h +++ b/src/db/db/dbShapes.h @@ -171,7 +171,6 @@ public: Properties = (1 << Null), All = (1 << Null) - 1, AllWithProperties = (1 << (Null + 1)) - 1, - RegardProperties = (1 << (Null + 1)), // special flag, not evaluated on query but in receiver (indicates to regard shapes with different properties as different entities) Nothing = 0 }; diff --git a/src/db/db/dbTextsDelegate.h b/src/db/db/dbTextsDelegate.h index 31a65922f..367ced7f1 100644 --- a/src/db/db/dbTextsDelegate.h +++ b/src/db/db/dbTextsDelegate.h @@ -102,6 +102,7 @@ public: virtual bool has_valid_texts () const = 0; virtual const db::RecursiveShapeIterator *iter () const = 0; + virtual void apply_property_translator (const db::PropertiesTranslator &pt) = 0; virtual db::PropertiesRepository *properties_repository () = 0; virtual const db::PropertiesRepository *properties_repository () const = 0; diff --git a/src/db/db/gsiDeclDbContainerHelpers.h b/src/db/db/gsiDeclDbContainerHelpers.h new file mode 100644 index 000000000..34416353b --- /dev/null +++ b/src/db/db/gsiDeclDbContainerHelpers.h @@ -0,0 +1,101 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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 + +*/ + + +#ifndef HDR_gsiDeclDbContainerHelpers +#define HDR_gsiDeclDbContainerHelpers + +#include "dbPropertiesRepository.h" +#include "tlVariant.h" +#include "gsiDecl.h" + +#include +#include + +namespace gsi +{ + +template +static void enable_properties (Container *c) +{ + c->apply_property_translator (db::PropertiesTranslator::make_pass_all ()); +} + +template +static void remove_properties (Container *c) +{ + c->apply_property_translator (db::PropertiesTranslator::make_remove_all ()); +} + +template +static void filter_properties (Container *c, const std::vector &keys) +{ + std::set kf; + kf.insert (keys.begin (), keys.end ()); + c->apply_property_translator (db::PropertiesTranslator::make_filter (c->properties_repository (), kf)); +} + +template +static void map_properties (Container *c, const std::map &map) +{ + c->apply_property_translator (db::PropertiesTranslator::make_key_mapper (c->properties_repository (), map)); +} + +template +static gsi::Methods +make_property_methods () +{ + return + gsi::method_ext ("enable_properties", &enable_properties, + "@brief Enables properties for the given container.\n" + "This method has an effect mainly on original layers and will import properties from such layers. " + "By default, properties are not enabled on original layers. Alternatively you can apply \\filter_properties " + "or \\map_properties to enable properties with a specific name key.\n" + "\n" + "This method has been introduced in version 0.28.4." + ) + + gsi::method_ext ("remove_properties", &remove_properties, + "@brief Removes properties for the given container.\n" + "This will remove all properties on the given container.\n" + "\n" + "This method has been introduced in version 0.28.4." + ) + + gsi::method_ext ("filter_properties", &filter_properties, gsi::arg ("keys"), + "@brief Filters properties by certain keys.\n" + "Calling this method on a container will reduce the properties to values with name keys from the 'keys' list.\n" + "As a side effect, this method enables properties on original layers.\n" + "\n" + "This method has been introduced in version 0.28.4." + ) + + gsi::method_ext ("map_properties", &map_properties, gsi::arg ("key_map"), + "@brief Maps properties by name key.\n" + "Calling this method on a container will reduce the properties to values with name keys from the 'keys' hash and " + "renames the properties. Properties not listed in the key map will be removed.\n" + "As a side effect, this method enables properties on original layers.\n" + "\n" + "This method has been introduced in version 0.28.4." + ); +} + +} + +#endif diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc index 2610d1bca..3f4c64032 100644 --- a/src/db/db/gsiDeclDbEdgePairs.cc +++ b/src/db/db/gsiDeclDbEdgePairs.cc @@ -31,6 +31,8 @@ #include "dbEdgesUtils.h" #include "dbEdgePairFilters.h" +#include "gsiDeclDbContainerHelpers.h" + namespace gsi { @@ -912,7 +914,9 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs", method_ext ("to_s", &to_string1, gsi::arg ("max_count"), "@brief Converts the edge pair collection to a string\n" "This version allows specification of the maximum number of edge pairs contained in the string." - ), + ) + + gsi::make_property_methods () + , "@brief EdgePairs (a collection of edge pairs)\n" "\n" "Edge pairs are used mainly in the context of the DRC functions (width_check, space_check etc.) of \\Region and \\Edges. " diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index 67cecfaaa..9f68150f6 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -32,6 +32,8 @@ #include "dbOriginalLayerRegion.h" #include "dbLayoutUtils.h" +#include "gsiDeclDbContainerHelpers.h" + namespace gsi { @@ -1750,7 +1752,9 @@ Class decl_Edges (decl_dbShapeCollection, "db", "Edges", method ("disable_progress", &db::Edges::disable_progress, "@brief Disable progress reporting\n" "Calling this method will disable progress reporting. See \\enable_progress.\n" - ), + ) + + gsi::make_property_methods () + , "@brief A collection of edges (Not necessarily describing closed contours)\n" "\n\n" "This class was introduced to simplify operations on edges sets. " diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 3b4407815..747d0527b 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -37,6 +37,8 @@ #include "dbCompoundOperation.h" #include "tlGlobPattern.h" +#include "gsiDeclDbContainerHelpers.h" + #include #include #include @@ -3030,7 +3032,9 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "This method is equivalent to \\Cell#fill_region, but is based on Region (with the cell being the first parameter).\n" "\n" "This method has been introduced in version 0.27.\n" - ), + ) + + gsi::make_property_methods () + , "@brief A region (a potentially complex area consisting of multiple polygons)\n" "\n\n" "This class was introduced to simplify operations on polygon sets like boolean or sizing operations. " diff --git a/src/db/db/gsiDeclDbShapes.cc b/src/db/db/gsiDeclDbShapes.cc index dcc24a0fd..e711fe0c6 100644 --- a/src/db/db/gsiDeclDbShapes.cc +++ b/src/db/db/gsiDeclDbShapes.cc @@ -448,7 +448,6 @@ static db::Layout *layout (db::Shapes *sh) static unsigned int s_all () { return db::ShapeIterator::All; } static unsigned int s_all_with_properties () { return db::ShapeIterator::AllWithProperties; } -static unsigned int s_regard_properties () { return db::ShapeIterator::RegardProperties; } static unsigned int s_properties () { return db::ShapeIterator::Properties; } static unsigned int s_polygons () { return db::ShapeIterator::Polygons; } static unsigned int s_regions () { return db::ShapeIterator::Regions; } @@ -1336,10 +1335,6 @@ Class decl_Shapes ("db", "Shapes", gsi::method ("SProperties|#s_properties", &s_properties, "@brief Indicates that only shapes with properties shall be retrieved" ) + - gsi::method ("SRegardProperties|#s_regard_properties", &s_regard_properties, - "@brief Special option to regard shapes with different properties as different entities (used by \\Region for example).\n" - "This option has been introduced in version 0.28.4.\n" - ) + gsi::method_ext ("dump_mem_statistics", &dump_mem_statistics, gsi::arg ("detailed", false), "@hide" ), diff --git a/src/db/db/gsiDeclDbTexts.cc b/src/db/db/gsiDeclDbTexts.cc index a85853908..7a4801bf2 100644 --- a/src/db/db/gsiDeclDbTexts.cc +++ b/src/db/db/gsiDeclDbTexts.cc @@ -28,6 +28,8 @@ #include "dbDeepTexts.h" #include "dbTextsUtils.h" +#include "gsiDeclDbContainerHelpers.h" + namespace gsi { @@ -506,7 +508,9 @@ Class decl_Texts (decl_dbShapeCollection, "db", "Texts", method_ext ("to_s", &to_string1, gsi::arg ("max_count"), "@brief Converts the text collection to a string\n" "This version allows specification of the maximum number of texts contained in the string." - ), + ) + + gsi::make_property_methods () + , "@brief Texts (a collection of texts)\n" "\n" "Text objects are useful as labels for net names, to identify certain regions and to specify specific locations in general. " diff --git a/src/db/unit_tests/dbAsIfFlatRegionTests.cc b/src/db/unit_tests/dbAsIfFlatRegionTests.cc index 056aabcae..bbc8f0c7d 100644 --- a/src/db/unit_tests/dbAsIfFlatRegionTests.cc +++ b/src/db/unit_tests/dbAsIfFlatRegionTests.cc @@ -1660,15 +1660,15 @@ TEST(40_BoolWithProperties) unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2); db::RecursiveShapeIterator si3 (ly, top_cell, l3); - si3.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si3.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r3 (si3); db::Layout target; @@ -1735,7 +1735,7 @@ TEST(41_EdgesWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1wp (si1); db::Region r1wp_nomerge = r1wp; r1wp_nomerge.set_merged_semantics (false); @@ -1744,7 +1744,7 @@ TEST(41_EdgesWithProperties) db::Region r1 (si1); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2wp (si2); db::Region r2wp_nomerge = r2wp; r2wp_nomerge.set_merged_semantics (false); @@ -1788,13 +1788,13 @@ TEST(42_DRCWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1); db::Region r1_nomerge (r1); r1_nomerge.set_merged_semantics (false); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2); db::Region r2_nomerge (r2); r2_nomerge.set_merged_semantics (false); @@ -1857,11 +1857,11 @@ TEST(43_ComplexOpsWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2); db::Layout target; @@ -1922,11 +1922,11 @@ TEST(44_SizeWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2); db::Layout target; diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index 295714c7d..e936bddda 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -2148,15 +2148,15 @@ TEST(40_BoolWithProperties) unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1, dss); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2, dss); db::RecursiveShapeIterator si3 (ly, top_cell, l3); - si3.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si3.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r3 (si3, dss); db::Layout target; @@ -2225,7 +2225,7 @@ TEST(41_EdgesWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1wp (si1, dss); db::Region r1wp_nomerge = r1wp; r1wp_nomerge.set_merged_semantics (false); @@ -2234,7 +2234,7 @@ TEST(41_EdgesWithProperties) db::Region r1 (si1, dss); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2wp (si2, dss); db::Region r2wp_nomerge = r2wp; r2wp_nomerge.set_merged_semantics (false); @@ -2280,13 +2280,13 @@ TEST(42_DRCWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1, dss); db::Region r1_nomerge (r1); r1_nomerge.set_merged_semantics (false); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2, dss); db::Region r2_nomerge (r2); r2_nomerge.set_merged_semantics (false); @@ -2351,11 +2351,11 @@ TEST(43_ComplexOpsWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1, dss); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2, dss); db::Layout target; @@ -2418,11 +2418,11 @@ TEST(44_SizeWithProperties) unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); db::RecursiveShapeIterator si1 (ly, top_cell, l1); - si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r1 (si1, dss); db::RecursiveShapeIterator si2 (ly, top_cell, l2); - si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + si2.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); db::Region r2 (si2, dss); db::Layout target; diff --git a/src/db/unit_tests/dbPropertiesRepositoryTests.cc b/src/db/unit_tests/dbPropertiesRepositoryTests.cc index 1a8ba974c..018ef9ae1 100644 --- a/src/db/unit_tests/dbPropertiesRepositoryTests.cc +++ b/src/db/unit_tests/dbPropertiesRepositoryTests.cc @@ -22,6 +22,7 @@ #include "dbPropertiesRepository.h" +#include "dbTestSupport.h" #include "tlString.h" #include "tlUnitTest.h" @@ -259,3 +260,135 @@ TEST(6) EXPECT_EQ (pid2, size_t (2)); } + +TEST(10_PropertiesTranslator) +{ + EXPECT_EQ (db::PropertiesTranslator ().is_null (), true); + EXPECT_EQ (db::PropertiesTranslator ().is_pass (), true); + EXPECT_EQ (db::PropertiesTranslator ().is_empty (), false); + EXPECT_EQ (db::PropertiesTranslator::make_pass_all ().is_null (), false); + EXPECT_EQ (db::PropertiesTranslator::make_pass_all ().is_pass (), true); + EXPECT_EQ (db::PropertiesTranslator::make_pass_all ().is_empty (), false); + EXPECT_EQ (db::PropertiesTranslator::make_remove_all ().is_null (), false); + EXPECT_EQ (db::PropertiesTranslator::make_remove_all ().is_pass (), false); + EXPECT_EQ (db::PropertiesTranslator::make_remove_all ().is_empty (), true); + + db::PropertiesRepository rp; + db::property_names_id_type key1 = rp.prop_name_id (1); + db::property_names_id_type key2 = rp.prop_name_id (2); + db::property_names_id_type key3 = rp.prop_name_id (3); + + db::PropertiesRepository::properties_set ps; + ps.insert (std::make_pair (key1, 100)); + ps.insert (std::make_pair (key2, 101)); + db::properties_id_type prop1a = rp.properties_id (ps); + EXPECT_EQ (prop2string (rp, prop1a), "1=100\n2=101"); + + ps.clear (); + ps.insert (std::make_pair (key1, 0)); + ps.insert (std::make_pair (key2, 101)); + db::properties_id_type prop1b = rp.properties_id (ps); + EXPECT_EQ (prop2string (rp, prop1b), "1=0\n2=101"); + + ps.clear (); + ps.insert (std::make_pair (key1, 100)); + ps.insert (std::make_pair (key3, 102)); + db::properties_id_type prop2 = rp.properties_id (ps); + EXPECT_EQ (prop2string (rp, prop2), "1=100\n3=102"); + + ps.clear (); + ps.insert (std::make_pair (key1, 100)); + db::properties_id_type prop3 = rp.properties_id (ps); + EXPECT_EQ (prop2string (rp, prop3), "1=100"); + + db::PropertiesRepository rp_org = rp; + + db::PropertiesTranslator t; + EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100\n2=101"); + EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0\n2=101"); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102"); + EXPECT_EQ (prop2string (rp, t (prop3)), "1=100"); + + t = db::PropertiesTranslator::make_pass_all (); + EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100\n2=101"); + EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0\n2=101"); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102"); + EXPECT_EQ (prop2string (rp, t (prop3)), "1=100"); + + t = db::PropertiesTranslator::make_remove_all (); + EXPECT_EQ (prop2string (rp, t (prop1a)), ""); + EXPECT_EQ (prop2string (rp, t (prop1b)), ""); + EXPECT_EQ (prop2string (rp, t (prop2)), ""); + EXPECT_EQ (prop2string (rp, t (prop3)), ""); + + std::set kf; + kf.insert (1); + t = db::PropertiesTranslator::make_filter (rp, kf); + EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100"); + EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0"); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=100"); + EXPECT_EQ (prop2string (rp, t (prop3)), "1=100"); + + kf.insert (3); + t = db::PropertiesTranslator::make_filter (rp, kf); + EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100"); + EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0"); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102"); + EXPECT_EQ (prop2string (rp, t (prop3)), "1=100"); + + std::map km; + km[1] = 4; + km[3] = 1; + + t = db::PropertiesTranslator::make_key_mapper (rp, km); + EXPECT_EQ (prop2string (rp, t (prop1a)), "4=100"); + EXPECT_EQ (prop2string (rp, t (prop1b)), "4=0"); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=102\n4=100"); + EXPECT_EQ (prop2string (rp, t (prop3)), "4=100"); + + kf.clear (); + kf.insert (4); + t = db::PropertiesTranslator::make_filter (rp, kf) * db::PropertiesTranslator::make_key_mapper (rp, km); + EXPECT_EQ (t.is_empty (), false); + EXPECT_EQ (prop2string (rp, t (prop1a)), "4=100"); + EXPECT_EQ (prop2string (rp, t (prop1b)), "4=0"); + EXPECT_EQ (prop2string (rp, t (prop2)), "4=100"); + EXPECT_EQ (prop2string (rp, t (prop3)), "4=100"); + + kf.clear (); + kf.insert (3); + + t = db::PropertiesTranslator::make_filter (rp, kf) * db::PropertiesTranslator::make_key_mapper (rp, km); + EXPECT_EQ (t.is_empty (), true); + EXPECT_EQ (prop2string (rp, t (prop1a)), ""); + EXPECT_EQ (prop2string (rp, t (prop1b)), ""); + EXPECT_EQ (prop2string (rp, t (prop2)), ""); + EXPECT_EQ (prop2string (rp, t (prop3)), ""); + + t = db::PropertiesTranslator::make_key_mapper (rp, km) * db::PropertiesTranslator::make_filter (rp, kf); + EXPECT_EQ (t.is_empty (), false); + EXPECT_EQ (prop2string (rp, t (prop1a)), ""); + EXPECT_EQ (prop2string (rp, t (prop1b)), ""); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=102"); + EXPECT_EQ (prop2string (rp, t (prop3)), ""); + + rp = rp_org; + + t = db::PropertiesTranslator::make_key_mapper (rp, km); + t = db::PropertiesTranslator::make_filter (rp, kf) * t; + EXPECT_EQ (t.is_empty (), true); + EXPECT_EQ (prop2string (rp, t (prop1a)), ""); + EXPECT_EQ (prop2string (rp, t (prop1b)), ""); + EXPECT_EQ (prop2string (rp, t (prop2)), ""); + EXPECT_EQ (prop2string (rp, t (prop3)), ""); + + rp = rp_org; + + t = db::PropertiesTranslator::make_filter (rp, kf); + t = db::PropertiesTranslator::make_key_mapper (rp, km) * t; + EXPECT_EQ (t.is_empty (), false); + EXPECT_EQ (prop2string (rp, t (prop1a)), ""); + EXPECT_EQ (prop2string (rp, t (prop1b)), ""); + EXPECT_EQ (prop2string (rp, t (prop2)), "1=102"); + EXPECT_EQ (prop2string (rp, t (prop3)), ""); +} diff --git a/src/db/unit_tests/dbRegionTests.cc b/src/db/unit_tests/dbRegionTests.cc index 619b36812..07b8b4339 100644 --- a/src/db/unit_tests/dbRegionTests.cc +++ b/src/db/unit_tests/dbRegionTests.cc @@ -2153,7 +2153,7 @@ TEST(51_PropertiesFlatFromLayout) // NOTE: now with regarding properties rsi = db::RecursiveShapeIterator (ly, top, li); - rsi.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + rsi.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); r = db::Region (rsi); EXPECT_EQ (r.count (), size_t (4)); @@ -2340,7 +2340,7 @@ TEST(53_PropertiesDeepFromLayout) // NOTE: now with regarding properties rsi = db::RecursiveShapeIterator (ly, top, li); - rsi.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + rsi.apply_property_translator (db::PropertiesTranslator::make_pass_all ()); r = db::Region (rsi, dss); EXPECT_EQ (r.count (), size_t (4));