From dd7aa9b84fb154ff3a69083c4a9da44d23af449a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 23 Dec 2024 23:40:36 +0100 Subject: [PATCH] WIP: massive refactoring of properties repo and OASIS reader Target is to reduce the properties repository to a singleton. Hence, there is no need to translate property IDs and it is possible to retrieve properties everywhere. The OASIS reader is refactored to avoid property renaming and change of property definitions per ID. --- src/buddies/src/bd/strmclip.cc | 1 - src/db/db/dbPropertiesRepository.cc | 137 +--- src/db/db/dbPropertiesRepository.h | 129 ++-- src/edt/edt/edtPartialService.cc | 30 +- src/edt/edt/edtService.cc | 24 +- src/edt/edt/edtUtils.cc | 27 +- .../gds2/db_plugin/dbGDS2ReaderBase.cc | 36 +- .../gds2/db_plugin/dbGDS2ReaderBase.h | 2 +- .../gds2/db_plugin/dbGDS2WriterBase.cc | 6 +- .../lefdef/db_plugin/dbDEFImporter.cc | 32 +- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 6 +- .../lefdef/db_plugin/dbLEFImporter.cc | 6 +- .../oasis/db_plugin/dbOASISReader.cc | 683 +++++++++++------- .../streamers/oasis/db_plugin/dbOASISReader.h | 19 +- .../oasis/db_plugin/dbOASISWriter.cc | 18 +- .../oasis/unit_tests/dbOASISReaderTests.cc | 16 +- .../oasis/unit_tests/dbOASISWriterTests.cc | 40 +- .../diff/lay_plugin/layDiffToolDialog.cc | 36 +- 18 files changed, 660 insertions(+), 588 deletions(-) diff --git a/src/buddies/src/bd/strmclip.cc b/src/buddies/src/bd/strmclip.cc index ea7bb2cfc..df64d0e9f 100644 --- a/src/buddies/src/bd/strmclip.cc +++ b/src/buddies/src/bd/strmclip.cc @@ -82,7 +82,6 @@ void clip (ClipData &data) } // copy the properties repository in order to have the same ID mapping - target_layout.properties_repository () = layout.properties_repository (); target_layout.dbu (layout.dbu ()); // look for the clip layer diff --git a/src/db/db/dbPropertiesRepository.cc b/src/db/db/dbPropertiesRepository.cc index 11373b44e..e574bab0b 100644 --- a/src/db/db/dbPropertiesRepository.cc +++ b/src/db/db/dbPropertiesRepository.cc @@ -117,6 +117,12 @@ PropertiesSet::has_value (const tl::Variant &name) const return m_map.find (nid) != m_map.end (); } +bool +PropertiesSet::has_value (db::property_names_id_type nid) const +{ + return m_map.find (nid) != m_map.end (); +} + const tl::Variant & PropertiesSet::value (const tl::Variant &name) const { @@ -130,6 +136,18 @@ PropertiesSet::value (const tl::Variant &name) const } } +const tl::Variant & +PropertiesSet::value (db::property_names_id_type nid) const +{ + auto i = m_map.find (nid); + if (i == m_map.end () || i->second != nid) { + static tl::Variant nil; + return nil; + } else { + return property_value (i->second); + } +} + void PropertiesSet::clear () { @@ -169,6 +187,12 @@ PropertiesSet::insert (db::property_names_id_type nid, const tl::Variant &value) m_map.insert (std::make_pair (nid, db::property_values_id (value))); } +void +PropertiesSet::merge (const db::PropertiesSet &other) +{ + m_map.insert (other.m_map.begin (), other.m_map.end ()); +} + std::multimap PropertiesSet::to_map () const { @@ -203,39 +227,15 @@ PropertiesSet::to_list_var () const return var; } -void -PropertiesSet::change_name (property_names_id_type from, property_names_id_type to) -{ - map_type org_map; - org_map.swap (m_map); - - for (auto i = org_map.begin (); i != org_map.end (); ++i) { - if (i->first == from) { - m_map.insert (std::make_pair (to, i->second)); - } else { - m_map.insert (*i); - } - } -} - -void -PropertiesSet::change_value (property_values_id_type from, property_values_id_type to) -{ - map_type org_map; - org_map.swap (m_map); - - for (auto i = org_map.begin (); i != org_map.end (); ++i) { - if (i->second == from) { - m_map.insert (std::make_pair (i->first, to)); - } else { - m_map.insert (*i); - } - } -} - // ---------------------------------------------------------------------------------- // PropertiesRepository implementation +PropertiesRepository &PropertiesRepository::instance () +{ + static PropertiesRepository s_instance; + return s_instance; +} + PropertiesRepository::PropertiesRepository () { // .. nothing yet .. @@ -300,55 +300,7 @@ PropertiesRepository::prop_value_id (const tl::Variant &value) } -void -PropertiesRepository::change_name (property_names_id_type id, const tl::Variant &new_name) -{ - db::property_names_id_type new_id = property_names_id (new_name); - if (new_id == id) { - return; - } - - auto &new_pids = m_properties_by_name_table [new_id]; - - auto pids = m_properties_by_name_table.find (id); - if (pids != m_properties_by_name_table.end ()) { - for (auto pid = pids->second.begin (); pid != pids->second.end (); ++pid) { - PropertiesSet *ps = reinterpret_cast (*pid); - m_properties.erase (ps); - ps->change_name (id, new_id); - m_properties.insert (ps); - new_pids.insert (*pid); - } - } - - m_properties_by_name_table.erase (id); -} - -void -PropertiesRepository::change_value (property_values_id_type id, const tl::Variant &new_value) -{ - db::property_values_id_type new_id = property_values_id (new_value); - if (new_id == id) { - return; - } - - auto &new_pids = m_properties_by_value_table [new_id]; - - auto pids = m_properties_by_value_table.find (id); - if (pids != m_properties_by_value_table.end ()) { - for (auto pid = pids->second.begin (); pid != pids->second.end (); ++pid) { - PropertiesSet *ps = reinterpret_cast (*pid); - m_properties.erase (ps); - ps->change_value (id, new_id); - m_properties.insert (ps); - new_pids.insert (*pid); - } - } - - m_properties_by_value_table.erase (id); -} - -properties_id_type +properties_id_type PropertiesRepository::properties_id (const PropertiesSet &props) { if (props.empty ()) { @@ -452,33 +404,6 @@ PropertiesRepository::properties_ids_by_name_value (db::property_names_id_type n return result; } -properties_id_type -PropertiesRepository::allocate_properties () -{ - tl::MutexLocker locker (&m_lock); - - m_properties_heap.push_back (PropertiesSet ()); - return db::properties_id_type (& m_properties_heap.back ()); -} - -property_names_id_type -PropertiesRepository::allocate_property_names_id () -{ - tl::MutexLocker locker (&m_lock); - - m_property_names_heap.push_back (tl::Variant ()); - return db::property_names_id_type (& m_property_names_heap.back ()); -} - -property_names_id_type -PropertiesRepository::allocate_property_values_id () -{ - tl::MutexLocker locker (&m_lock); - - m_property_values_heap.push_back (tl::Variant ()); - return db::property_values_id_type (& m_property_values_heap.back ()); -} - // ---------------------------------------------------------------------------------- // PropertiesRepository implementation diff --git a/src/db/db/dbPropertiesRepository.h b/src/db/db/dbPropertiesRepository.h index 06d5fa6e2..7d7155a6f 100644 --- a/src/db/db/dbPropertiesRepository.h +++ b/src/db/db/dbPropertiesRepository.h @@ -42,22 +42,22 @@ namespace db /** * @brief Gets a name entry from the property name ID */ -const tl::Variant &property_name (db::property_names_id_type id); +DB_PUBLIC const tl::Variant &property_name (db::property_names_id_type id); /** * @brief Gets the property name ID from a property name */ -db::property_names_id_type property_names_id (const tl::Variant &pn); +DB_PUBLIC db::property_names_id_type property_names_id (const tl::Variant &pn); /** * @brief Gets a value entry from the property value ID */ -const tl::Variant &property_value (db::property_values_id_type id); +DB_PUBLIC const tl::Variant &property_value (db::property_values_id_type id); /** * @brief Gets the property value ID from a property value */ -db::property_values_id_type property_values_id (const tl::Variant &pv); +DB_PUBLIC db::property_values_id_type property_values_id (const tl::Variant &pv); /** @@ -71,6 +71,7 @@ class DB_PUBLIC PropertiesSet public: typedef std::multimap map_type; typedef map_type::const_iterator iterator; + typedef map_type::iterator non_const_iterator; /** * @brief The default constructor @@ -117,6 +118,14 @@ public: */ bool operator< (const PropertiesSet &other) const; + /** + * @brief Swaps with another properties set + */ + void swap (PropertiesSet &other) + { + m_map.swap (other.m_map); + } + /** * @brief Gets a value indicating whether the properties set is empty */ @@ -125,16 +134,34 @@ public: return m_map.empty (); } + /** + * @brief Gets the size of the properties set + */ + size_t size () const + { + return m_map.size (); + } + /** * @brief Gets a value indicating whether the given name is contained in the set */ bool has_value (const tl::Variant &name) const; + /** + * @brief Gets a value indicating whether the given name is contained in the set + */ + bool has_value (db::property_names_id_type name_id) const; + /** * @brief Gets the value for the given name or a nil variant if there is no value for this name */ const tl::Variant &value (const tl::Variant &name) const; + /** + * @brief Gets the value for the given name or a nil variant if there is no value for this name + */ + const tl::Variant &value (db::property_names_id_type name_id) const; + /** * @brief operator[] as alias for "value" */ @@ -143,6 +170,14 @@ public: return value (name); } + /** + * @brief operator[] as alias for "value" + */ + const tl::Variant &operator[] (db::property_names_id_type name_id) const + { + return value (name_id); + } + /** * @brief Clears the properties set */ @@ -168,6 +203,11 @@ public: */ void insert (db::property_names_id_type name_id, const tl::Variant &value); + /** + * @brief Merge another properties set into self + */ + void merge (const db::PropertiesSet &other); + /** * @brief Gets the properties as a map */ @@ -205,24 +245,38 @@ public: return m_map.end (); } + /** + * @brief Non-const iterator (begin) + * + * This iterator delivers key/value pairs in the ID form. + * The order is basically undefined. + */ + non_const_iterator begin_non_const () + { + return m_map.begin (); + } + + /** + * @brief Non-const iterator (end) + */ + non_const_iterator end_non_const () + { + return m_map.end (); + } + private: map_type m_map; - - friend class PropertiesRepository; - - void change_name (property_names_id_type from, property_names_id_type to); - void change_value (property_values_id_type from, property_values_id_type to); }; /** * @brief Gets the properties set from a properties set ID */ -const PropertiesSet &properties (db::properties_id_type id); +DB_PUBLIC const PropertiesSet &properties (db::properties_id_type id); /** * @brief Gets the properties ID from a properties set */ -db::properties_id_type properties_id (const PropertiesSet &ps); +DB_PUBLIC db::properties_id_type properties_id (const PropertiesSet &ps); /** * @brief The properties repository @@ -259,32 +313,6 @@ public: */ property_names_id_type prop_value_id (const tl::Variant &name); - /** - * @brief Change the name associated with a given name ID to another name - * - * All properties with the given name ID will get the new name. This method is - * particular useful for the OASIS reader, which may associate a name with an Id - * at a late stage. The ID must have been obtained by "allocate_name". - * - * This method will change the definition of property sets. The ID of the - * sets will stay the same. Basically this can lead to a situation where - * identical property sets have different IDs. In other words, ID identity - * is a guarantee for property set identity, but different IDs do not - * mean different property sets. - * - * The original ID is still valid, but not associated with the new name. - */ - void change_name (property_names_id_type id, const tl::Variant &new_name); - - /** - * @brief Change the name associated with a given name Id to another name - * - * See "change_name" for more details. This method will change the definition - * of the value behind ID to the new value. The ID must have been obtained - * through "allocate_value". - */ - void change_value (property_values_id_type id, const tl::Variant &new_value); - /** * @brief Get the ID for a name * @@ -341,33 +369,6 @@ public: */ bool is_valid_property_values_id (property_values_id_type id) const; - /** - * @brief Allocates a new properties ID - * - * This method is intended for filling the properties later, i.e. with "change_properties". - * Only after using "change_properties", the properties ID will be found when - * looking it up. - */ - properties_id_type allocate_properties (); - - /** - * @brief Allocates a new properties name ID - * - * This method is intended for filling the properties later, i.e. with "change_name". - * Only after using "change_name", a property names ID will be found when - * looking up the name. - */ - property_names_id_type allocate_property_names_id (); - - /** - * @brief Allocates a new properties value ID - * - * This method is intended for filling the properties later, i.e. with "change_value". - * Only after using "change_value", the property value ID will be found when - * looking up the value. - */ - property_names_id_type allocate_property_values_id (); - /** * @brief Lookup a table of properties id's by a name value pair * diff --git a/src/edt/edt/edtPartialService.cc b/src/edt/edt/edtPartialService.cc index 4c35f62df..89258d416 100644 --- a/src/edt/edt/edtPartialService.cc +++ b/src/edt/edt/edtPartialService.cc @@ -3406,15 +3406,14 @@ PartialService::handle_guiding_shape_changes () parent_inst = s->first.back ().inst_ptr; } - db::property_names_id_type pn = layout->properties_repository ().prop_name_id ("name"); - - const db::PropertiesRepository::properties_set &input_props = layout->properties_repository ().properties (s->first.shape ().prop_id ()); - db::PropertiesRepository::properties_set::const_iterator input_pv = input_props.find (pn); - if (input_pv == input_props.end ()) { + // @@@ name by id, don't repeat key + const db::PropertiesSet &input_props = db::properties (s->first.shape ().prop_id ()); + tl::Variant name_value = input_props.value (tl::Variant ("name")); + if (name_value.is_nil ()) { return false; } - std::string shape_name = input_pv->second.to_string (); + std::string shape_name = name_value.to_string (); // Hint: get_parameters_from_pcell_and_guiding_shapes invalidates the shapes because it resets the changed // guiding shapes. We must not access s->shape after that. @@ -3431,17 +3430,14 @@ PartialService::handle_guiding_shape_changes () // try to identify the selected shape in the new shapes and select this one db::Shapes::shape_iterator sh = layout->cell (new_inst.cell_index ()).shapes (layout->guiding_shape_layer ()).begin (db::ShapeIterator::All); while (! sh.at_end ()) { - const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (sh->prop_id ()); - db::PropertiesRepository::properties_set::const_iterator pv = props.find (pn); - if (pv != props.end ()) { - if (pv->second.to_string () == shape_name) { - lay::ObjectInstPath inst_path = s->first; - inst_path.back ().inst_ptr = new_inst; - inst_path.back ().array_inst = new_inst.begin (); - inst_path.set_shape (*sh); - new_sel.insert (std::make_pair (inst_path, s->second)); - break; - } + const db::PropertiesSet &props = db::properties (sh->prop_id ()); + if (props.value (tl::Variant ("name")) == shape_name) { + lay::ObjectInstPath inst_path = s->first; + inst_path.back ().inst_ptr = new_inst; + inst_path.back ().array_inst = new_inst.begin (); + inst_path.set_shape (*sh); + new_sel.insert (std::make_pair (inst_path, s->second)); + break; } ++sh; } diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index f5a11c505..51db4341c 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -1898,15 +1898,14 @@ Service::handle_guiding_shape_changes (const lay::ObjectInstPath &obj) const parent_inst = obj.back ().inst_ptr; } - db::property_names_id_type pn = layout->properties_repository ().prop_name_id ("name"); + db::property_names_id_type pn = db::property_names_id ("name"); - const db::PropertiesRepository::properties_set &input_props = layout->properties_repository ().properties (obj.shape ().prop_id ()); - db::PropertiesRepository::properties_set::const_iterator input_pv = input_props.find (pn); - if (input_pv == input_props.end ()) { + const db::PropertiesSet &input_props = db::properties (obj.shape ().prop_id ()); + if (! input_props.has_value (pn)) { return std::make_pair (false, lay::ObjectInstPath ()); } - std::string shape_name = input_pv->second.to_string (); + std::string shape_name = input_props.value (pn).to_string (); // Hint: get_parameters_from_pcell_and_guiding_shapes invalidates the shapes because it resets the changed // guiding shapes. We must not access s->shape after that. @@ -1924,15 +1923,12 @@ Service::handle_guiding_shape_changes (const lay::ObjectInstPath &obj) const // try to identify the selected shape in the new shapes and select this one db::Shapes::shape_iterator sh = layout->cell (new_inst.cell_index ()).shapes (layout->guiding_shape_layer ()).begin (db::ShapeIterator::All); while (! sh.at_end () && !found) { - const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (sh->prop_id ()); - db::PropertiesRepository::properties_set::const_iterator pv = props.find (pn); - if (pv != props.end ()) { - if (pv->second.to_string () == shape_name) { - new_obj.back ().inst_ptr = new_inst; - new_obj.back ().array_inst = new_inst.begin (); - new_obj.set_shape (*sh); - found = true; - } + const db::PropertiesSet &props = db::properties (sh->prop_id ()); + if (props.has_value (pn) && props.value (pn).to_string () == shape_name) { + new_obj.back ().inst_ptr = new_inst; + new_obj.back ().array_inst = new_inst.begin (); + new_obj.set_shape (*sh); + found = true; } ++sh; } diff --git a/src/edt/edt/edtUtils.cc b/src/edt/edt/edtUtils.cc index 1aac2097f..589a03dc6 100644 --- a/src/edt/edt/edtUtils.cc +++ b/src/edt/edt/edtUtils.cc @@ -176,8 +176,8 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index pname_map.insert (std::make_pair (pcp [i].get_name (), i)); } - db::property_names_id_type pn = layout->properties_repository ().prop_name_id ("name"); - db::property_names_id_type dn = layout->properties_repository ().prop_name_id (tl::Variant ("description")); + db::property_names_id_type pn = db::property_names_id ("name"); + db::property_names_id_type dn = db::property_names_id ("description"); db::Shapes &guiding_shapes = layout->cell (cell_index).shapes (layout->guiding_shape_layer ()); @@ -186,11 +186,10 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index if (sh->has_prop_id ()) { - const db::PropertiesRepository::properties_set &props = layout->properties_repository ().properties (sh->prop_id ()); - db::PropertiesRepository::properties_set::const_iterator pv = props.find (pn); - if (pv != props.end ()) { + const db::PropertiesSet &props = db::properties (sh->prop_id ()); + if (props.has_value (pn)) { - std::map ::const_iterator pnm = pname_map.find (pv->second.to_string ()); + std::map ::const_iterator pnm = pname_map.find (props.value (pn).to_string ()); if (pnm != pname_map.end ()) { db::CplxTrans dbu_trans (layout->dbu ()); @@ -230,37 +229,37 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index if (pd.get_type () == db::PCellParameterDeclaration::t_shape && ! pd.is_hidden ()) { // use property with name "name" to indicate the parameter name - db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (pn, tl::Variant (pd.get_name ()))); + db::PropertiesSet props; + props.insert (pn, tl::Variant (pd.get_name ())); if (! pd.get_description ().empty ()) { - props.insert (std::make_pair (dn, tl::Variant (pd.get_description ()))); + props.insert (dn, tl::Variant (pd.get_description ())); } if (org_parameters[i].is_user ()) { - guiding_shapes.insert (db::BoxWithProperties(db::Box (org_parameters[i].to_user () * (1.0 / layout->dbu ())), layout->properties_repository ().properties_id (props))); + guiding_shapes.insert (db::BoxWithProperties (db::Box (org_parameters[i].to_user () * (1.0 / layout->dbu ())), db::properties_id (props))); } else if (org_parameters[i].is_user ()) { - guiding_shapes.insert (db::EdgeWithProperties(db::Edge (org_parameters[i].to_user () * (1.0 / layout->dbu ())), layout->properties_repository ().properties_id (props))); + guiding_shapes.insert (db::EdgeWithProperties (db::Edge (org_parameters[i].to_user () * (1.0 / layout->dbu ())), db::properties_id (props))); } else if (org_parameters[i].is_user ()) { db::DPoint p = org_parameters[i].to_user (); - guiding_shapes.insert (db::PointWithProperties(db::Point (p * (1.0 / layout->dbu ())), layout->properties_repository ().properties_id (props))); + guiding_shapes.insert (db::PointWithProperties (db::Point (p * (1.0 / layout->dbu ())), db::properties_id (props))); } else if (org_parameters[i].is_user ()) { db::complex_trans dbu_trans (1.0 / layout->dbu ()); // Hint: we don't compress the polygon since we don't want to loose information db::Polygon poly = org_parameters[i].to_user ().transformed (dbu_trans, false); - guiding_shapes.insert (db::PolygonWithProperties(poly, layout->properties_repository ().properties_id (props))); + guiding_shapes.insert (db::PolygonWithProperties (poly, db::properties_id (props))); } else if (org_parameters[i].is_user ()) { db::complex_trans dbu_trans (1.0 / layout->dbu ()); - guiding_shapes.insert (db::PathWithProperties(dbu_trans * org_parameters[i].to_user (), layout->properties_repository ().properties_id (props))); + guiding_shapes.insert (db::PathWithProperties (dbu_trans * org_parameters[i].to_user (), db::properties_id (props))); } diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc index 2edd16847..0e0432f99 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc @@ -95,12 +95,12 @@ GDS2ReaderBase::finish_element () std::pair -GDS2ReaderBase::finish_element (db::PropertiesRepository &rep) +GDS2ReaderBase::finish_element_with_props () { bool any = false; long attr = 0; - db::PropertiesRepository::properties_set properties; + db::PropertiesSet properties; while (true) { @@ -114,9 +114,7 @@ GDS2ReaderBase::finish_element (db::PropertiesRepository &rep) const char *value = get_string (); if (m_read_properties) { - properties.insert (std::make_pair (rep.prop_name_id (tl::Variant (attr)), - tl::Variant (value))); - + properties.insert (tl::Variant (attr), tl::Variant (value)); any = true; } @@ -132,7 +130,7 @@ GDS2ReaderBase::finish_element (db::PropertiesRepository &rep) } if (any) { - return std::make_pair (true, rep.properties_id (properties)); + return std::make_pair (true, db::properties_id (properties)); } else { return std::make_pair (false, 0); } @@ -189,7 +187,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) layout.add_meta_info ("access_time", MetaInfo (tl::to_string (tr ("Access Time")), tl::sprintf ("%d/%d/%d %d:%02d:%02d", access_time[1], access_time[2], access_time[0], access_time[3], access_time[4], access_time[5]))); long attr = 0; - db::PropertiesRepository::properties_set layout_properties; + db::PropertiesSet layout_properties; // read until short rec_id = 0; @@ -225,7 +223,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) const char *value = get_string (); if (m_read_properties) { - layout_properties.insert (std::make_pair (layout.properties_repository ().prop_name_id (tl::Variant (attr)), tl::Variant (value))); + layout_properties.insert (tl::Variant (attr), tl::Variant (value)); } } else if (rec_id == sUNITS) { @@ -250,7 +248,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) // set the layout properties if (! layout_properties.empty ()) { - layout.prop_id (layout.properties_repository ().properties_id (layout_properties)); + layout.prop_id (db::properties_id (layout_properties)); } // this container has been found to grow quite a lot. @@ -314,7 +312,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) } long attr = 0; - db::PropertiesRepository::properties_set cell_properties; + db::PropertiesSet cell_properties; // read cell content while ((rec_id = get_record ()) != sENDSTR) { @@ -333,7 +331,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) const char *value = get_string (); if (m_read_properties) { - cell_properties.insert (std::make_pair (layout.properties_repository ().prop_name_id (tl::Variant (attr)), tl::Variant (value))); + cell_properties.insert (tl::Variant (attr), tl::Variant (value)); } } else if (rec_id == sBOUNDARY) { @@ -386,7 +384,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) // set the cell properties if (! cell_properties.empty ()) { - cell->prop_id (layout.properties_repository ().properties_id (cell_properties)); + cell->prop_id (db::properties_id (cell_properties)); } } @@ -603,7 +601,7 @@ GDS2ReaderBase::read_boundary (db::Layout &layout, db::Cell &cell, bool from_box } } - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); if (pp.first) { cell.shapes (ll.second).insert (db::BoxWithProperties (db::Box (p1, p2), pp.second)); } else { @@ -662,7 +660,7 @@ GDS2ReaderBase::read_boundary (db::Layout &layout, db::Cell &cell, bool from_box finish_element (); } else { // this will copy the polyon: - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); if (pp.first) { cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (db::SimplePolygonRef (poly, layout.shape_repository ()), pp.second)); } else { @@ -799,7 +797,7 @@ GDS2ReaderBase::read_path (db::Layout &layout, db::Cell &cell) if (path.points () < 2 && type != 1) { warn (tl::to_string (tr ("PATH with less than two points encountered - interpretation may be different in other tools"))); } - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); if (pp.first) { cell.shapes (ll.second).insert (db::PathRefWithProperties (db::PathRef (path, layout.shape_repository ()), pp.second)); } else { @@ -935,7 +933,7 @@ GDS2ReaderBase::read_text (db::Layout &layout, db::Cell &cell) // Create the text db::Text text (get_string (), t, size, font, ha, va); - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); if (pp.first) { cell.shapes (ll.second).insert (db::TextRefWithProperties (db::TextRef (text, layout.shape_repository ()), pp.second)); } else { @@ -982,7 +980,7 @@ GDS2ReaderBase::read_box (db::Layout &layout, db::Cell &cell) box += pt_conv (*xy++); } - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); if (! box.empty ()) { if (pp.first) { cell.shapes (ll.second).insert (db::BoxWithProperties (box, pp.second)); @@ -1095,7 +1093,7 @@ GDS2ReaderBase::read_ref (db::Layout &layout, db::Cell & /*cell*/, bool array, t rows = 1; } - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); bool split_cols = false, split_rows = false; @@ -1234,7 +1232,7 @@ GDS2ReaderBase::read_ref (db::Layout &layout, db::Cell & /*cell*/, bool array, t inst = db::CellInstArray (db::CellInst (ci), db::Trans (angle, mirror, xy)); } - std::pair pp = finish_element (layout.properties_repository ()); + std::pair pp = finish_element_with_props (); if (pp.first) { instances_with_props.push_back (db::CellInstArrayWithProperties (inst, pp.second)); } else { diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.h b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.h index 0a1a30ee2..2375a4ada 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.h +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.h @@ -97,7 +97,7 @@ private: void read_box (db::Layout &layout, db::Cell &cell); void read_ref (db::Layout &layout, db::Cell &cell, bool array, tl::vector &instances, tl::vector &insts_wp); - std::pair finish_element (db::PropertiesRepository &rep); + std::pair finish_element_with_props (); void finish_element (); virtual void common_reader_error (const std::string &msg) { error (msg); } diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc index ef05cd65c..70c850af5 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc @@ -1090,10 +1090,10 @@ GDS2WriterBase::write_polygon (int layer, int datatype, double sf, const db::Sha void GDS2WriterBase::write_properties (const db::Layout &layout, db::properties_id_type prop_id) { - const db::PropertiesRepository::properties_set &props = layout.properties_repository ().properties (prop_id); - for (db::PropertiesRepository::properties_set::const_iterator p = props.begin (); p != props.end (); ++p) { + auto props = db::properties (prop_id).to_map (); + for (auto p = props.begin (); p != props.end (); ++p) { - const tl::Variant &name = layout.properties_repository ().prop_name (p->first); + const tl::Variant &name = p->first; long attr = -1; if (name.can_convert_to_long ()) { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 31223d969..b6057aa52 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -827,9 +827,9 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool db::properties_id_type prop_id = 0; if (produce_net_props ()) { - db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (net_prop_name_id (), tl::Variant (net))); - prop_id = layout.properties_repository ().properties_id (props); + db::PropertiesSet props; + props.insert (net_prop_name_id (), tl::Variant (net)); + prop_id = db::properties_id (props); } while (test ("(")) { @@ -865,9 +865,9 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool net = stored_netname + "/" + subnetname; if (produce_net_props ()) { - db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (net_prop_name_id (), tl::Variant (net))); - prop_id = layout.properties_repository ().properties_id (props); + db::PropertiesSet props; + props.insert (net_prop_name_id (), tl::Variant (net)); + prop_id = db::properties_id (props); } } else if (! specialnets && test ("NONDEFAULTRULE")) { @@ -1371,14 +1371,14 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) db::properties_id_type prop_id = 0; if (produce_pin_props () || produce_net_props ()) { - db::PropertiesRepository::properties_set props; + db::PropertiesSet props; if (produce_pin_props ()) { - props.insert (std::make_pair (pin_prop_name_id (), tl::Variant (label))); + props.insert (pin_prop_name_id (), tl::Variant (label)); } if (produce_net_props ()) { - props.insert (std::make_pair (net_prop_name_id (), tl::Variant (net))); + props.insert (net_prop_name_id (), tl::Variant (net)); } - prop_id = layout.properties_repository ().properties_id (props); + prop_id = db::properties_id (props); } for (std::vector::const_iterator p = g->second.begin (); p != g->second.end (); ++p) { @@ -1944,9 +1944,9 @@ DEFImporter::do_read (db::Layout &layout) if (g->comp_matches (ii->first)) { if (produce_inst_props ()) { - db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (inst_prop_name_id (), tl::Variant (ii->first))); - group_cell->insert (db::CellInstArrayWithProperties (ii->second, layout.properties_repository ().properties_id (props))); + db::PropertiesSet props; + props.insert (inst_prop_name_id (), tl::Variant (ii->first)); + group_cell->insert (db::CellInstArrayWithProperties (ii->second, db::properties_id (props))); } else { group_cell->insert (ii->second); } @@ -1993,9 +1993,9 @@ DEFImporter::do_read (db::Layout &layout) for (std::list >::iterator ii = instances.begin (); ii != instances.end (); ++ii) { if (produce_inst_props ()) { - db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (inst_prop_name_id (), tl::Variant (ii->first))); - others_cell->insert (db::CellInstArrayWithProperties (ii->second, layout.properties_repository ().properties_id (props))); + db::PropertiesSet props; + props.insert (inst_prop_name_id (), tl::Variant (ii->first)); + others_cell->insert (db::CellInstArrayWithProperties (ii->second, db::properties_id (props))); } else { others_cell->insert (ii->second); } diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 0b19845a1..f65bb3da4 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -2032,7 +2032,7 @@ LEFDEFImporter::read (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderS if (m_options.produce_net_names ()) { m_produce_net_props = true; - m_net_prop_name_id = layout.properties_repository ().prop_name_id (m_options.net_property_name ()); + m_net_prop_name_id = db::property_names_id (m_options.net_property_name ()); } m_produce_inst_props = false; @@ -2040,7 +2040,7 @@ LEFDEFImporter::read (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderS if (m_options.produce_inst_names ()) { m_produce_inst_props = true; - m_inst_prop_name_id = layout.properties_repository ().prop_name_id (m_options.inst_property_name ()); + m_inst_prop_name_id = db::property_names_id (m_options.inst_property_name ()); } m_produce_pin_props = false; @@ -2048,7 +2048,7 @@ LEFDEFImporter::read (tl::InputStream &stream, db::Layout &layout, LEFDEFReaderS if (m_options.produce_pin_names ()) { m_produce_pin_props = true; - m_pin_prop_name_id = layout.properties_repository ().prop_name_id (m_options.pin_property_name ()); + m_pin_prop_name_id = db::property_names_id (m_options.pin_property_name ()); } try { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 1311b0b6d..e82ce640e 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -956,9 +956,9 @@ LEFImporter::read_macro (Layout &layout) db::properties_id_type prop_id = 0; if (produce_pin_props ()) { - db::PropertiesRepository::properties_set props; - props.insert (std::make_pair (pin_prop_name_id (), tl::Variant (label))); - prop_id = layout.properties_repository ().properties_id (props); + db::PropertiesSet props; + props.insert (pin_prop_name_id (), tl::Variant (label)); + prop_id = db::properties_id (props); } std::map boxes_for_labels; diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc index ebd42a6fb..902893422 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc @@ -629,8 +629,8 @@ OASISReader::do_read (db::Layout &layout) char *mb; // prepare - m_s_gds_property_name_id = layout.properties_repository ().prop_name_id (s_gds_property_propname); - m_klayout_context_property_name_id = layout.properties_repository ().prop_name_id (klayout_context_propname); + m_s_gds_property_name_id = db::property_names_id (s_gds_property_propname); + m_klayout_context_property_name_id = db::property_names_id (klayout_context_propname); // read magic bytes mb = (char *) m_stream.get (sizeof (magic_bytes) - 1); @@ -705,11 +705,14 @@ OASISReader::do_read (db::Layout &layout) m_propname_forward_references.clear (); m_propvalue_forward_references.clear (); + m_forward_properties_for_shapes.clear (); + m_forward_properties_for_instances.clear (); + m_future_cell_properties.clear (); + m_fwd_properties.clear (); m_text_forward_references.clear (); - m_prop_ids.clear (); - db::PropertiesRepository::properties_set layout_properties; - std::vector context_properties; + db::PropertiesSet layout_properties; + std::vector context_strings; mark_start_table (); @@ -760,7 +763,7 @@ OASISReader::do_read (db::Layout &layout) reset_modal_variables (); - std::pair pp = read_element_properties (layout.properties_repository (), true); + std::pair pp = read_element_properties (true); if (pp.first) { m_cellname_properties.insert (std::make_pair (id, pp.second)); } @@ -801,7 +804,7 @@ OASISReader::do_read (db::Layout &layout) reset_modal_variables (); // ignore properties attached to this name item - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 7 || r == 8 /*PROPNAME*/) { @@ -835,132 +838,10 @@ OASISReader::do_read (db::Layout &layout) error (tl::sprintf (tl::to_string (tr ("A PROPNAME with id %ld is present already")), id)); } - // resolve forward references to property names - std::map ::iterator pf = m_propname_forward_references.find (id); - if (pf != m_propname_forward_references.end ()) { - - bool is_s_gds_property = false; - bool is_klayout_context_property = false; - - if (name == s_gds_property_propname) { - is_s_gds_property = true; - } else if (name == klayout_context_propname) { - is_klayout_context_property = true; - } - - // handle special case of forward references to S_GDS_PROPERTY and KLAYOUT_CONTEXT - if (is_s_gds_property || is_klayout_context_property) { - - db::PropertiesRepository &rep = layout.properties_repository (); - - // exchange properties in layout_properties - db::PropertiesRepository::properties_set new_set; - - for (db::PropertiesRepository::properties_set::const_iterator s = layout_properties.begin (); s != layout_properties.end (); ++s) { - if (s->first == pf->second && is_s_gds_property) { - - // S_GDS_PROPERTY translation - if (!s->second.is_list () || s->second.get_list ().size () != 2) { - error (tl::to_string (tr ("S_GDS_PROPERTY must have a value list with exactly two elements"))); - } - - new_set.insert (std::make_pair (rep.prop_name_id (s->second.get_list () [0]), s->second.get_list () [1])); - - } else if (s->first == pf->second && is_klayout_context_property) { - - // feed context strings from klayout context property - if (s->second.is_list ()) { - for (auto l = s->second.begin (); l != s->second.end (); ++l) { - context_properties.push_back (*l); - } - } else { - context_properties.push_back (s->second); - } - - } else { - new_set.insert (*s); - } - } - - new_set.swap (layout_properties); - - // exchange the properties in the repository - - std::map > cells_by_pid; - - if (is_klayout_context_property) { - - // need a table of cells by prop_id in that case - - for (auto pid = m_prop_ids.begin (); pid != m_prop_ids.end (); ++pid) { - cells_by_pid.insert (std::make_pair (*pid, std::vector ())); - } - - for (auto i = layout.begin (); i != layout.end (); ++i) { - auto pid2c = cells_by_pid.find (i->prop_id ()); - if (pid2c != cells_by_pid.end ()) { - pid2c->second.push_back (i->cell_index ()); - } - } - - } - - // create new property sets for the ones where a name needs substitution - - for (auto pid = m_prop_ids.begin (); pid != m_prop_ids.end (); ++pid) { - - const db::PropertiesRepository::properties_set &old_set = rep.properties (*pid); - db::PropertiesRepository::properties_set new_set; - - for (auto s = old_set.begin (); s != old_set.end (); ++s) { - if (is_s_gds_property && s->first == pf->second) { - - // S_GDS_PROPERTY translation - if (!s->second.is_list () || s->second.get_list ().size () != 2) { - error (tl::to_string (tr ("S_GDS_PROPERTY must have a value list with exactly two elements"))); - } - - new_set.insert (std::make_pair (rep.prop_name_id (s->second.get_list () [0]), s->second.get_list () [1])); - - } else if (is_klayout_context_property && s->first == pf->second) { - - auto pid2c = cells_by_pid.find (*pid); - tl_assert (pid2c != cells_by_pid.end ()); - - // feed cell-specific context strings from klayout context property - for (auto c = pid2c->second.begin (); c != pid2c->second.end (); ++c) { - std::vector &vl = m_context_strings_per_cell [*c]; - if (s->second.is_list ()) { - for (auto l = s->second.begin (); l != s->second.end (); ++l) { - vl.push_back (*l); - } - } else { - vl.push_back (s->second); - } - } - - } else { - new_set.insert (*s); - } - } - - if (old_set != new_set) { - rep.change_properties (*pid, new_set); - } - - } - - } - - layout.properties_repository ().change_name (pf->second, tl::Variant (name)); - m_propname_forward_references.erase (pf); - - } - reset_modal_variables (); // ignore properties attached to this name item - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 9 || r == 10 /*PROPSTRING*/) { @@ -1002,7 +883,7 @@ OASISReader::do_read (db::Layout &layout) reset_modal_variables (); // ignore properties attached to this name item - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 11 || r == 12 /*LAYERNAME*/) { @@ -1070,21 +951,17 @@ OASISReader::do_read (db::Layout &layout) reset_modal_variables (); // ignore properties attached to this name item - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 28 || r == 29 /*PROPERTY*/) { // unrecognized property: store in layout properties if (r == 28) { - read_properties (layout.properties_repository ()); + read_properties (); } - if (! mm_last_property_is_sprop.get () && mm_last_property_name.get () == m_klayout_context_property_name_id) { - context_properties.insert (context_properties.end (), mm_last_value_list.get ().begin (), mm_last_value_list.get ().end ()); - } else { - // store cell properties - store_last_properties (layout.properties_repository (), layout_properties, true); - } + // store layout properties + store_last_properties (layout_properties, true, true); mark_start_table (); @@ -1100,7 +977,7 @@ OASISReader::do_read (db::Layout &layout) reset_modal_variables (); // ignore properties attached to this name item - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 13 || r == 14 /*CELL*/) { @@ -1170,12 +1047,64 @@ OASISReader::do_read (db::Layout &layout) } + // Resolve forward references for stored shape and instance prop_ids. + // This makes these shape and instance property IDs valid + + for (auto p = m_forward_properties_for_instances.begin (); p != m_forward_properties_for_instances.end (); ++p) { + + db::PropertiesSet props = forward_properties (p->first); + resolve_forward_references (props); + + db::properties_id_type pid = db::properties_id (props); + for (auto i = p->second.begin (); i != p->second.end (); ++i) { + if (i->instances ()) { + i->instances ()->replace_prop_id (*i, pid); + } + } + + } + + for (auto p = m_forward_properties_for_shapes.begin (); p != m_forward_properties_for_shapes.end (); ++p) { + + db::PropertiesSet props = forward_properties (p->first); + resolve_forward_references (props); + + db::properties_id_type pid = db::properties_id (props); + for (auto i = p->second.begin (); i != p->second.end (); ++i) { + if (i->shapes ()) { + i->shapes ()-> replace_prop_id (*i, pid); + } + } + + } + + // Resolve forward cell properties and extract context strings + + for (auto p = m_future_cell_properties.begin (); p != m_future_cell_properties.end (); ++p) { + + db::PropertiesSet props = p->second; + resolve_forward_references (props); + + std::vector context_strings; + extract_context_strings (props, context_strings); + if (context_strings.empty ()) { + m_context_strings_per_cell [p->first].swap (context_strings); + } + + layout.cell (p->first).prop_id (db::properties_id (props)); + + } + // store file (layout) level properties if (! layout_properties.empty ()) { - db::properties_id_type prop_id = layout.properties_repository ().properties_id (layout_properties); - m_prop_ids.insert (prop_id); + + resolve_forward_references (layout_properties); + extract_context_strings (layout_properties, context_strings); + + db::properties_id_type prop_id = db::properties_id (layout_properties); layout.prop_id (prop_id); layout_properties.clear (); + } size_t pt = m_stream.pos (); @@ -1210,50 +1139,29 @@ OASISReader::do_read (db::Layout &layout) error (tl::sprintf (tl::to_string (tr ("No property name defined for property name id %ld")), fw->first)); } - // resolve all propvalue forward references - if (! m_propvalue_forward_references.empty ()) { - - for (auto i = context_properties.begin (); i != context_properties.end (); ++i) { - replace_forward_references_in_variant (*i); - } - for (auto c = m_context_strings_per_cell.begin (); c != m_context_strings_per_cell.end (); ++c) { - for (auto i = c->second.begin (); i != c->second.end (); ++i) { - replace_forward_references_in_variant (*i); - } - } - - for (auto pid = m_prop_ids.begin (); pid != m_prop_ids.end (); ++pid) { - const db::PropertiesRepository::properties_set &prop_set_org = layout.properties_repository ().properties (*pid); - db::PropertiesRepository::properties_set prop_set_new = prop_set_org; - for (auto ps = prop_set_new.begin (); ps != prop_set_new.end (); ++ps) { - replace_forward_references_in_variant (ps->second); - } - if (prop_set_org != prop_set_new) { - layout.properties_repository ().change_properties (*pid, prop_set_new); - } - } - - m_propvalue_forward_references.clear (); - - } - // attach the properties found in CELLNAME to the cells (which may have other properties) for (std::map::const_iterator p = m_cellname_properties.begin (); p != m_cellname_properties.end (); ++p) { + // The cellname properties ID may be a forward properties ID, resolve it first + std::pair c = cell_by_id (p->first); if (c.first) { - db::PropertiesRepository::properties_set cnp = layout.properties_repository ().properties (p->second); + db::PropertiesSet cnp; + if (is_forward_properties_id (p->second)) { + cnp = forward_properties (p->second); + resolve_forward_references (cnp); + } else { + cnp = db::properties (p->second); + } // Merge existing properties with the ones from CELLNAME db::Cell &cell = layout.cell (c.second); if (cell.prop_id () != 0) { - db::PropertiesRepository::properties_set cp = layout.properties_repository ().properties (cell.prop_id ()); - cnp.insert (cp.begin (), cp.end ()); + cnp.merge (db::properties (cell.prop_id ())); } - db::properties_id_type prop_id = layout.properties_repository ().properties_id (cnp); - m_prop_ids.insert (prop_id); + db::properties_id_type prop_id = db::properties_id (cnp); cell.prop_id (prop_id); } @@ -1261,8 +1169,8 @@ OASISReader::do_read (db::Layout &layout) } // Restore layout meta info - if (! context_properties.empty ()) { - LayoutOrCellContextInfo info = make_context_info (context_properties); + if (! context_strings.empty ()) { + LayoutOrCellContextInfo info = make_context_info (context_strings); layout.fill_meta_info_from_context (info); } @@ -1296,6 +1204,144 @@ OASISReader::do_read (db::Layout &layout) } } +bool +OASISReader::has_forward_refs (const db::PropertiesSet &properties) +{ + // A properties set is a forward referenced set if one of the components is an ID + // NOTE: we assume there is a single level of lists max. + + for (auto p = properties.begin (); p != properties.end (); ++p) { + + const tl::Variant &name = db::property_name (p->first); + if (name.is_id ()) { + return true; + } + + const tl::Variant &value = db::property_value (p->second); + if (value.is_list ()) { + for (auto l = value.begin (); l != value.end (); ++l) { + if (l->is_id ()) { + return true; + } + } + } else if (value.is_id ()) { + return true; + } + + } + + return false; +} + +properties_id_type OASISReader::make_forward_properties_id (const db::PropertiesSet &properties) +{ + // NOTE: the forward properties ID scheme makes use of the fact that IDs + // are basically pointers and aligned to words. So the bit 0 is always 0 + // for true properties IDs. + + m_fwd_properties.push_back (properties); + return db::properties_id_type (& m_fwd_properties.back ()) + 1; +} + +bool +OASISReader::is_forward_properties_id (properties_id_type id) const +{ + return (id & 1) != 0; +} + +const db::PropertiesSet & +OASISReader::forward_properties (properties_id_type id) const +{ + id = id & ~db::properties_id_type (1); + return *reinterpret_cast (id); +} + +void +OASISReader::register_forward_property_for_shape (const db::Shape &shape) +{ + m_forward_properties_for_shapes [shape.prop_id ()].push_back (shape); +} + +void +OASISReader::register_forward_property_for_instance (const db::Instance &instance) +{ + m_forward_properties_for_instances [instance.prop_id ()].push_back (instance); +} + +void +OASISReader::extract_context_strings (db::PropertiesSet &properties, std::vector &context_strings) +{ + db::PropertiesSet new_set; + + for (auto p = properties.begin (); p != properties.end (); ++p) { + + const tl::Variant &value = db::property_value (p->second); + + // name ID 0 is reserved for context property strings + if (p->first == 0) { + // feed context strings from klayout context property + if (value.is_list ()) { + for (auto l = value.begin (); l != value.end (); ++l) { + context_strings.push_back (*l); + } + } else { + context_strings.push_back (value); + } + } else { + new_set.insert (p->first, value); + } + + } + + properties.swap (new_set); +} + +void +OASISReader::resolve_forward_references (db::PropertiesSet &properties) +{ + db::PropertiesSet new_props; + + for (auto p = properties.begin (); p != properties.end (); ++p) { + + tl::Variant value = db::property_value (p->second); + replace_forward_references_in_variant (value); + + // NOTE: property names ID 0 is reserved for context strings + if (! p->first) { + new_props.insert (p->first, value); + continue; + } + + const tl::Variant &name = db::property_name (p->first); + if (name.is_id ()) { + + std::map ::iterator pf = m_propname_forward_references.find (name.to_id ()); + if (pf != m_propname_forward_references.end ()) { + + if (pf->second == m_s_gds_property_name_id) { + + // S_GDS_PROPERTY translation + if (value.is_list () && value.get_list ().size () >= 2) { + new_props.insert (value.get_list () [0], value.get_list () [1]); + } + + } else if (pf->second == m_klayout_context_property_name_id) { + // NOTE: property names ID 0 is reserved for context strings + new_props.insert (property_names_id (0), value); + } else { + new_props.insert (pf->second, value); + } + + } + + } else { + new_props.insert (p->first, value); + } + } + + properties.swap (new_props); +} + void OASISReader::replace_forward_references_in_variant (tl::Variant &v) { @@ -1343,9 +1389,15 @@ OASISReader::replace_forward_references_in_variant (tl::Variant &v) } void -OASISReader::store_last_properties (db::PropertiesRepository &rep, db::PropertiesRepository::properties_set &properties, bool ignore_special) +OASISReader::store_last_properties (db::PropertiesSet &properties, bool ignore_special, bool with_context_props) { - if (! m_read_properties) { + if (with_context_props && mm_last_property_is_sprop.get () && mm_last_property_name.get () == m_klayout_context_property_name_id) { + + // Context properties are stored with a special property name ID of 0 + + properties.insert (db::property_names_id (0), tl::Variant (mm_last_value_list.get ().begin (), mm_last_value_list.get ().end ())); + + } else if (! m_read_properties) { // All properties are ignored @@ -1355,7 +1407,7 @@ OASISReader::store_last_properties (db::PropertiesRepository &rep, db::Propertie error (tl::to_string (tr ("S_GDS_PROPERTY must have a value list with exactly two elements"))); } - properties.insert (std::make_pair (rep.prop_name_id (mm_last_value_list.get () [0]), mm_last_value_list.get () [1])); + properties.insert (mm_last_value_list.get () [0], mm_last_value_list.get () [1]); } else if (ignore_special && ! m_read_all_properties && mm_last_property_is_sprop.get ()) { @@ -1364,18 +1416,18 @@ OASISReader::store_last_properties (db::PropertiesRepository &rep, db::Propertie // For shapes we need to keep the special ones since they may be forward-references S_GDS_PROPERTY names. } else if (mm_last_value_list.get ().size () == 0) { - properties.insert (std::make_pair (mm_last_property_name.get (), tl::Variant ())); + properties.insert (mm_last_property_name.get (), tl::Variant ()); } else if (mm_last_value_list.get ().size () == 1) { - properties.insert (std::make_pair (mm_last_property_name.get (), tl::Variant (mm_last_value_list.get () [0]))); + properties.insert (mm_last_property_name.get (), tl::Variant (mm_last_value_list.get () [0])); } else if (mm_last_value_list.get ().size () > 1) { - properties.insert (std::make_pair (mm_last_property_name.get (), tl::Variant (mm_last_value_list.get ().begin (), mm_last_value_list.get ().end ()))); + properties.insert (mm_last_property_name.get (), tl::Variant (mm_last_value_list.get ().begin (), mm_last_value_list.get ().end ())); } } std::pair -OASISReader::read_element_properties (db::PropertiesRepository &rep, bool ignore_special) +OASISReader::read_element_properties (bool ignore_special) { - db::PropertiesRepository::properties_set properties; + db::PropertiesSet properties; mark_start_table (); @@ -1404,14 +1456,14 @@ OASISReader::read_element_properties (db::PropertiesRepository &rep, bool ignore } else if (m == 28 /*PROPERTY*/) { - read_properties (rep); - store_last_properties (rep, properties, ignore_special); + read_properties (); + store_last_properties (properties, ignore_special); mark_start_table (); } else if (m == 29 /*PROPERTY*/) { - store_last_properties (rep, properties, ignore_special); + store_last_properties (properties, ignore_special); mark_start_table (); @@ -1425,19 +1477,24 @@ OASISReader::read_element_properties (db::PropertiesRepository &rep, bool ignore } if (! properties.empty ()) { - db::properties_id_type prop_id = rep.properties_id (properties); - m_prop_ids.insert (prop_id); - return std::make_pair (true, prop_id); + if (has_forward_refs (properties)) { + return std::make_pair (true, make_forward_properties_id (properties)); + } else { + return std::make_pair (true, db::properties_id (properties)); + } } else { return std::make_pair (false, 0); } } void -OASISReader::read_properties (db::PropertiesRepository &rep) +OASISReader::read_properties () { unsigned char m = get_byte (); + bool is_sprop = ((m & 0x01) != 0); + mm_last_property_is_sprop = is_sprop; + if (m & 0x04) { if (m & 0x02) { @@ -1446,10 +1503,10 @@ OASISReader::read_properties (db::PropertiesRepository &rep) std::map ::const_iterator cid = m_propnames.find (id); if (cid == m_propnames.end ()) { - mm_last_property_name = rep.prop_name_id (tl::Variant (id, true /*dummy for id type*/)); + mm_last_property_name = db::property_names_id (tl::Variant (id, true /*dummy for id type*/)); m_propname_forward_references.insert (std::make_pair (id, mm_last_property_name.get ())); } else { - mm_last_property_name = rep.prop_name_id (tl::Variant (cid->second)); + mm_last_property_name = db::property_names_id (tl::Variant (cid->second)); } } else { @@ -1458,13 +1515,11 @@ OASISReader::read_properties (db::PropertiesRepository &rep) warn (tl::to_string (tr ("PROPERTY names must be references to PROPNAME ids in strict mode"))); } - mm_last_property_name = rep.prop_name_id (tl::Variant (get_str ())); + mm_last_property_name = db::property_names_id (tl::Variant (get_str ())); } } - mm_last_property_is_sprop = ((m & 0x01) != 0); - if (! (m & 0x08)) { unsigned long n = ((unsigned long) (m >> 4)) & 0x0f; @@ -1868,7 +1923,7 @@ OASISReader::do_read_placement (unsigned char r, if ((m & 0x8) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); db::Vector a, b; size_t na, nb; @@ -1953,7 +2008,7 @@ OASISReader::do_read_placement (unsigned char r, } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); db::CellInstArray inst; @@ -2058,7 +2113,7 @@ OASISReader::do_read_text (bool xy_absolute, if ((m & 0x4) && read_repetition ()) { // TODO: should not read properties if layer is not enabled! - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2082,7 +2137,10 @@ OASISReader::do_read_text (bool xy_absolute, db::TextPtr text_ptr (text, layout.shape_repository ()); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::text_ptr_array_type (text_ptr, db::Disp (pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::text_ptr_array_type (text_ptr, db::Disp (pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::text_ptr_array_type (text_ptr, db::Disp (pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -2099,7 +2157,10 @@ OASISReader::do_read_text (bool xy_absolute, array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::text_ptr_array_type (text_ptr, db::Disp (pos), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::text_ptr_array_type (text_ptr, db::Disp (pos), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::text_ptr_array_type (text_ptr, db::Disp (pos), layout.array_repository ().insert (array))); } @@ -2110,7 +2171,10 @@ OASISReader::do_read_text (bool xy_absolute, db::TextRef text_ref (text, layout.shape_repository ()); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::TextRefWithProperties (text_ref.transformed (db::Disp (pos + *p)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::TextRefWithProperties (text_ref.transformed (db::Disp (pos + *p)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (text_ref.transformed (db::Disp (pos + *p))); } @@ -2123,7 +2187,7 @@ OASISReader::do_read_text (bool xy_absolute, } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2135,7 +2199,10 @@ OASISReader::do_read_text (bool xy_absolute, } if (pp.first) { - layout.cell (cell_index).shapes (ll.second).insert (db::TextRefWithProperties (db::TextRef (text, layout.shape_repository ()), pp.second)); + auto shape = layout.cell (cell_index).shapes (ll.second).insert (db::TextRefWithProperties (db::TextRef (text, layout.shape_repository ()), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { layout.cell (cell_index).shapes (ll.second).insert (db::TextRef (text, layout.shape_repository ())); } @@ -2198,7 +2265,7 @@ OASISReader::do_read_rectangle (bool xy_absolute, if ((m & 0x4) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2214,7 +2281,10 @@ OASISReader::do_read_rectangle (bool xy_absolute, // Create a box array if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::box_array_type (box, db::UnitTrans (), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::box_array_type (box, db::UnitTrans (), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::box_array_type (box, db::UnitTrans (), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -2229,7 +2299,10 @@ OASISReader::do_read_rectangle (bool xy_absolute, array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::box_array_type (box, db::UnitTrans (), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::box_array_type (box, db::UnitTrans (), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::box_array_type (box, db::UnitTrans (), layout.array_repository ().insert (array))); } @@ -2240,7 +2313,10 @@ OASISReader::do_read_rectangle (bool xy_absolute, RepetitionIterator p = mm_repetition.get ().begin (); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::BoxWithProperties (box.moved (*p), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::BoxWithProperties (box.moved (*p), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (box.moved (*p)); } @@ -2253,13 +2329,16 @@ OASISReader::do_read_rectangle (bool xy_absolute, } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { db::Cell &cell = layout.cell (cell_index); if (pp.first) { - cell.shapes (ll.second).insert (db::BoxWithProperties (box, pp.second)); + auto shape = cell.shapes (ll.second).insert (db::BoxWithProperties (box, pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (box); } @@ -2312,7 +2391,7 @@ OASISReader::do_read_polygon (bool xy_absolute, db::cell_index_type cell_index, if ((m & 0x4) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2340,7 +2419,10 @@ OASISReader::do_read_polygon (bool xy_absolute, db::cell_index_type cell_index, db::SimplePolygonPtr poly_ptr (poly, layout.shape_repository ()); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties > (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties > (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -2359,7 +2441,10 @@ OASISReader::do_read_polygon (bool xy_absolute, db::cell_index_type cell_index, array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array))); } @@ -2371,7 +2456,10 @@ OASISReader::do_read_polygon (bool xy_absolute, db::cell_index_type cell_index, RepetitionIterator p = mm_repetition.get ().begin (); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos + *p)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos + *p)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (poly_ref.transformed (db::Disp (pos + *p))); } @@ -2386,7 +2474,7 @@ OASISReader::do_read_polygon (bool xy_absolute, db::cell_index_type cell_index, } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2400,7 +2488,10 @@ OASISReader::do_read_polygon (bool xy_absolute, db::cell_index_type cell_index, db::SimplePolygonRef poly_ref (poly, layout.shape_repository ()); if (pp.first) { - layout.cell (cell_index).shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos)), pp.second)); + auto shape = layout.cell (cell_index).shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { layout.cell (cell_index).shapes (ll.second).insert (poly_ref.transformed (db::Disp (pos))); } @@ -2479,7 +2570,7 @@ OASISReader::do_read_path (bool xy_absolute, db::cell_index_type cell_index, db: if ((m & 0x4) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2509,7 +2600,10 @@ OASISReader::do_read_path (bool xy_absolute, db::cell_index_type cell_index, db: db::PathPtr path_ptr (path, layout.shape_repository ()); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties > (db::array (path_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties > (db::array (path_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::array (path_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -2528,7 +2622,10 @@ OASISReader::do_read_path (bool xy_absolute, db::cell_index_type cell_index, db: array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::path_ptr_array_type (path_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::path_ptr_array_type (path_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::path_ptr_array_type (path_ptr, db::Disp (d + pos), layout.array_repository ().insert (array))); } @@ -2540,7 +2637,10 @@ OASISReader::do_read_path (bool xy_absolute, db::cell_index_type cell_index, db: RepetitionIterator p = mm_repetition.get ().begin (); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos + *p)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos + *p)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (path_ref.transformed (db::Disp (pos + *p))); } @@ -2555,7 +2655,7 @@ OASISReader::do_read_path (bool xy_absolute, db::cell_index_type cell_index, db: } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2571,7 +2671,10 @@ OASISReader::do_read_path (bool xy_absolute, db::cell_index_type cell_index, db: db::PathRef path_ref (path, layout.shape_repository ()); if (pp.first) { - layout.cell (cell_index).shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos)), pp.second)); + auto shape = layout.cell (cell_index).shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { layout.cell (cell_index).shapes (ll.second).insert (path_ref.transformed (db::Disp (pos))); } @@ -2654,7 +2757,7 @@ OASISReader::do_read_trapezoid (unsigned char r, bool xy_absolute,db::cell_index if ((m & 0x4) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2678,7 +2781,10 @@ OASISReader::do_read_trapezoid (unsigned char r, bool xy_absolute,db::cell_index db::SimplePolygonPtr poly_ptr (poly, layout.shape_repository ()); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties > (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties > (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -2697,7 +2803,10 @@ OASISReader::do_read_trapezoid (unsigned char r, bool xy_absolute,db::cell_index array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array))); } @@ -2709,7 +2818,10 @@ OASISReader::do_read_trapezoid (unsigned char r, bool xy_absolute,db::cell_index RepetitionIterator p = mm_repetition.get ().begin (); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos + *p)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos + *p)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (poly_ref.transformed (db::Disp (pos + *p))); } @@ -2722,7 +2834,7 @@ OASISReader::do_read_trapezoid (unsigned char r, bool xy_absolute,db::cell_index } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -2732,7 +2844,10 @@ OASISReader::do_read_trapezoid (unsigned char r, bool xy_absolute,db::cell_index db::SimplePolygonRef poly_ref (poly, layout.shape_repository ()); if (pp.first) { - layout.cell (cell_index).shapes (ll.second).insert (SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos)), pp.second)); + auto shape = layout.cell (cell_index).shapes (ll.second).insert (SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { layout.cell (cell_index).shapes (ll.second).insert (poly_ref.transformed (db::Disp (pos))); } @@ -3014,7 +3129,7 @@ OASISReader::do_read_ctrapezoid (bool xy_absolute,db::cell_index_type cell_index if ((m & 0x4) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -3037,7 +3152,10 @@ OASISReader::do_read_ctrapezoid (bool xy_absolute,db::cell_index_type cell_index db::SimplePolygonPtr poly_ptr (poly, layout.shape_repository ()); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties > (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties > (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::array (poly_ptr, db::Disp (d + pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -3056,7 +3174,10 @@ OASISReader::do_read_ctrapezoid (bool xy_absolute,db::cell_index_type cell_index array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::simple_polygon_ptr_array_type (poly_ptr, db::Disp (d + pos), layout.array_repository ().insert (array))); } @@ -3068,7 +3189,10 @@ OASISReader::do_read_ctrapezoid (bool xy_absolute,db::cell_index_type cell_index RepetitionIterator p = mm_repetition.get ().begin (); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos + *p)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos + *p)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (poly_ref.transformed (db::Disp (pos + *p))); } @@ -3081,7 +3205,7 @@ OASISReader::do_read_ctrapezoid (bool xy_absolute,db::cell_index_type cell_index } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -3091,7 +3215,10 @@ OASISReader::do_read_ctrapezoid (bool xy_absolute,db::cell_index_type cell_index db::SimplePolygonRef poly_ref (poly, layout.shape_repository ()); if (pp.first) { - layout.cell (cell_index).shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos)), pp.second)); + auto shape = layout.cell (cell_index).shapes (ll.second).insert (db::SimplePolygonRefWithProperties (poly_ref.transformed (db::Disp (pos)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { layout.cell (cell_index).shapes (ll.second).insert (poly_ref.transformed (db::Disp (pos))); } @@ -3149,7 +3276,7 @@ OASISReader::do_read_circle (bool xy_absolute, db::cell_index_type cell_index, d if ((m & 0x4) && read_repetition ()) { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -3175,7 +3302,10 @@ OASISReader::do_read_circle (bool xy_absolute, db::cell_index_type cell_index, d db::PathPtr path_ptr (path, layout.shape_repository ()); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties > (db::array (path_ptr, db::Disp (pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties > (db::array (path_ptr, db::Disp (pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::array (path_ptr, db::Disp (pos), layout.array_repository (), a, b, (unsigned long) na, (unsigned long) nb)); } @@ -3192,7 +3322,10 @@ OASISReader::do_read_circle (bool xy_absolute, db::cell_index_type cell_index, d array.sort (); if (pp.first) { - cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::path_ptr_array_type (path_ptr, db::Disp (pos), layout.array_repository ().insert (array)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::object_with_properties (db::Shape::path_ptr_array_type (path_ptr, db::Disp (pos), layout.array_repository ().insert (array)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (db::Shape::path_ptr_array_type (path_ptr, db::Disp (pos), layout.array_repository ().insert (array))); } @@ -3204,7 +3337,10 @@ OASISReader::do_read_circle (bool xy_absolute, db::cell_index_type cell_index, d RepetitionIterator p = mm_repetition.get ().begin (); while (! p.at_end ()) { if (pp.first) { - cell.shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos + *p)), pp.second)); + auto shape = cell.shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos + *p)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { cell.shapes (ll.second).insert (path_ref.transformed (db::Disp (pos + *p))); } @@ -3217,7 +3353,7 @@ OASISReader::do_read_circle (bool xy_absolute, db::cell_index_type cell_index, d } else { - std::pair pp = read_element_properties (layout.properties_repository (), false); + std::pair pp = read_element_properties (false); if (ll.first) { @@ -3231,7 +3367,10 @@ OASISReader::do_read_circle (bool xy_absolute, db::cell_index_type cell_index, d db::PathRef path_ref (path, layout.shape_repository ()); if (pp.first) { - layout.cell (cell_index).shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos)), pp.second)); + auto shape = layout.cell (cell_index).shapes (ll.second).insert (db::PathRefWithProperties (path_ref.transformed (db::Disp (pos)), pp.second)); + if (is_forward_properties_id (pp.second)) { + register_forward_property_for_shape (shape); + } } else { layout.cell (cell_index).shapes (ll.second).insert (path_ref.transformed (db::Disp (pos))); } @@ -3284,9 +3423,7 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) bool xy_absolute = true; - bool has_context = false; - std::vector context_strings; - db::PropertiesRepository::properties_set cell_properties; + db::PropertiesSet cell_properties; // read next record while (true) { @@ -3349,19 +3486,10 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) } else if (r == 28 || r == 29 /*PROPERTY*/) { if (r == 28 /*PROPERTY*/) { - read_properties (layout.properties_repository ()); + read_properties (); } - if (! mm_last_property_is_sprop.get () && mm_last_property_name.get () == m_klayout_context_property_name_id) { - has_context = true; - context_strings.reserve (mm_last_value_list.get ().size ()); - for (std::vector::const_iterator v = mm_last_value_list.get ().begin (); v != mm_last_value_list.get ().end (); ++v) { - context_strings.push_back (*v); - } - } else { - // store layout properties - store_last_properties (layout.properties_repository (), cell_properties, true); - } + store_last_properties (cell_properties, true, true); mark_start_table (); @@ -3371,7 +3499,7 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) get_ulong (); get_str (); - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 33 /*XGEOMETRY*/) { @@ -3415,7 +3543,7 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) // later: handle XGEOMETRY with repetition } - read_element_properties (layout.properties_repository (), true); + read_element_properties (true); } else if (r == 34 /*CBLOCK*/) { @@ -3440,28 +3568,49 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) } if (! cell_properties.empty ()) { - db::properties_id_type prop_id = layout.properties_repository ().properties_id (cell_properties); - m_prop_ids.insert (prop_id); - layout.cell (cell_index).prop_id (prop_id); + + if (has_forward_refs (cell_properties)) { + + m_future_cell_properties [cell_index] = cell_properties; + + } else { + + std::vector context_strings; + extract_context_strings (cell_properties, context_strings); + // store the context strings for later + if (context_strings.empty ()) { + m_context_strings_per_cell [cell_index].swap (context_strings); + } + + layout.cell (cell_index).prop_id (db::properties_id (cell_properties)); + + } } // insert all instances collected (inserting them once is // more effective than doing this every time) if (! m_instances.empty ()) { + layout.cell (cell_index).insert (m_instances.begin (), m_instances.end ()); + // clear immediately, because if the cell is cleared before the instances are deleted, the // array pointers (living in the repository) may no longer be valid m_instances.clear (); - } - if (! m_instances_with_props.empty ()) { - layout.cell (cell_index).insert (m_instances_with_props.begin (), m_instances_with_props.end ()); - // see above. - m_instances_with_props.clear (); + } - // store the context strings for later - if (has_context) { - m_context_strings_per_cell [cell_index].swap (context_strings); + if (! m_instances_with_props.empty ()) { + + for (auto i = m_instances_with_props.begin (); i != m_instances_with_props.end (); ++i) { + auto instance = layout.cell (cell_index).insert (*i); + if (is_forward_properties_id (i->properties_id ())) { + register_forward_property_for_instance (instance); + } + } + + // see above. + m_instances_with_props.clear (); + } m_cellname = ""; diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.h b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.h index 5961773f5..674ac150a 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.h +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.h @@ -180,7 +180,10 @@ private: std::map m_propname_forward_references; std::map m_propvalue_forward_references; - std::set m_prop_ids; + std::map > m_forward_properties_for_shapes; + std::map > m_forward_properties_for_instances; + std::map m_future_cell_properties; + std::list m_fwd_properties; db::property_names_id_type m_s_gds_property_name_id; db::property_names_id_type m_klayout_context_property_name_id; @@ -207,10 +210,18 @@ private: void read_offset_table (); bool read_repetition (); void read_pointlist (modal_variable > &pointlist, bool for_polygon); - void read_properties (db::PropertiesRepository &rep); - void store_last_properties (db::PropertiesRepository &rep, db::PropertiesRepository::properties_set &properties, bool ignore_special); - std::pair read_element_properties (db::PropertiesRepository &rep, bool ignore_special); + void read_properties (); + void store_last_properties (db::PropertiesSet &properties, bool ignore_special, bool with_context_props = false); + std::pair read_element_properties (bool ignore_special); void replace_forward_references_in_variant (tl::Variant &v); + void extract_context_strings (db::PropertiesSet &properties, std::vector &context_strings); + bool has_forward_refs (const db::PropertiesSet &properties); + db::properties_id_type make_forward_properties_id (const db::PropertiesSet &properties); + const db::PropertiesSet &forward_properties (db::properties_id_type id) const; + bool is_forward_properties_id (db::properties_id_type id) const; + void register_forward_property_for_shape (const db::Shape &shape); + void register_forward_property_for_instance (const db::Instance &instance); + void resolve_forward_references (db::PropertiesSet &properties); unsigned char get_byte () { diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc index 3b6393e38..12920ddb4 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc @@ -997,10 +997,10 @@ OASISWriter::write_ucoord (db::Coord c) void OASISWriter::emit_propname_def (db::properties_id_type prop_id) { - const db::PropertiesRepository::properties_set &props = mp_layout->properties_repository ().properties (prop_id); - for (db::PropertiesRepository::properties_set::const_iterator p = props.begin (); p != props.end (); ++p) { + auto props = db::properties (prop_id).to_map (); + for (auto p = props.begin (); p != props.end (); ++p) { - const tl::Variant &name = mp_layout->properties_repository ().prop_name (p->first); + const tl::Variant &name = p->first; const char *name_str = s_gds_property_name; if (! make_gds_property (name)) { name_str = name.to_string (); @@ -1019,13 +1019,13 @@ OASISWriter::emit_propstring_def (db::properties_id_type prop_id) { std::vector pv_list; - const db::PropertiesRepository::properties_set &props = mp_layout->properties_repository ().properties (prop_id); - for (db::PropertiesRepository::properties_set::const_iterator p = props.begin (); p != props.end (); ++p) { + auto props = db::properties (prop_id).to_map (); + for (auto p = props.begin (); p != props.end (); ++p) { pv_list.clear (); const std::vector *pvl = &pv_list; - const tl::Variant &name = mp_layout->properties_repository ().prop_name (p->first); + const tl::Variant &name = p->first; if (! make_gds_property (name)) { if (p->second.is_list ()) { @@ -2117,13 +2117,13 @@ OASISWriter::write_props (db::properties_id_type prop_id) { std::vector pv_list; - const db::PropertiesRepository::properties_set &props = mp_layout->properties_repository ().properties (prop_id); + auto props = db::properties (prop_id).to_map (); - for (db::PropertiesRepository::properties_set::const_iterator p = props.begin (); p != props.end (); ++p) { + for (auto p = props.begin (); p != props.end (); ++p) { m_progress.set (mp_stream->pos ()); - const tl::Variant &name = mp_layout->properties_repository ().prop_name (p->first); + const tl::Variant &name = p->first; const char *name_str = s_gds_property_name; bool sflag = true; diff --git a/src/plugins/streamers/oasis/unit_tests/dbOASISReaderTests.cc b/src/plugins/streamers/oasis/unit_tests/dbOASISReaderTests.cc index a6b9359b0..c05bcaccf 100644 --- a/src/plugins/streamers/oasis/unit_tests/dbOASISReaderTests.cc +++ b/src/plugins/streamers/oasis/unit_tests/dbOASISReaderTests.cc @@ -650,18 +650,16 @@ TEST(Bug_1799) reader.read (layout); } - db::properties_id_type pn = layout.properties_repository ().prop_name_id (tl::Variant (1)); - db::PropertiesRepository::properties_set ps; - ps.insert (std::make_pair (pn, tl::Variant ("hello, world!"))); + db::properties_id_type pn = db::property_names_id (tl::Variant (1)); + db::PropertiesSet ps; + ps.insert (pn, tl::Variant ("hello, world!")); - auto pid = layout.properties_repository ().properties_id (ps); + auto pid = db::properties_id (ps); - auto ps2 = layout.properties_repository ().properties (pid); + auto ps2 = db::properties (pid); EXPECT_EQ (ps2.size (), size_t (1)); - EXPECT_EQ (ps2.find (pn) != ps2.end (), true); - if (ps2.find (pn) != ps2.end ()) { - EXPECT_EQ (ps2.find (pn)->second.to_string (), "hello, world!"); - } + EXPECT_EQ (ps2.has_value (pn), true); + EXPECT_EQ (ps2.value (pn).to_string (), "hello, world!"); } TEST(DuplicateCellname) diff --git a/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc b/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc index c85a7f600..a108e4a96 100644 --- a/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc +++ b/src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc @@ -1207,19 +1207,19 @@ TEST(115) db::Layout g (&m); db::property_names_id_type n1, n2, n3; - n1 = g.properties_repository ().prop_name_id (tl::Variant (17)); - n2 = g.properties_repository ().prop_name_id (tl::Variant ("name")); - n3 = g.properties_repository ().prop_name_id (tl::Variant ((unsigned int) 42)); + n1 = db::property_names_id (tl::Variant (17)); + n2 = db::property_names_id (tl::Variant ("name")); + n3 = db::property_names_id (tl::Variant ((unsigned int) 42)); - db::PropertiesRepository::properties_set s1; - s1.insert (std::make_pair (n1, tl::Variant ("17value"))); - s1.insert (std::make_pair (n2, tl::Variant (117))); + db::PropertiesSet s1; + s1.insert (n1, tl::Variant ("17value")); + s1.insert (n2, tl::Variant (117)); - db::PropertiesRepository::properties_set s2; - s2.insert (std::make_pair (n3, tl::Variant (42))); + db::PropertiesSet s2; + s2.insert (n3, tl::Variant (42)); - db::properties_id_type p1 = g.properties_repository ().properties_id (s1); - db::properties_id_type p2 = g.properties_repository ().properties_id (s2); + db::properties_id_type p1 = db::properties_id (s1); + db::properties_id_type p2 = db::properties_id (s2); g.prop_id (p1); @@ -1288,19 +1288,19 @@ TEST(116) db::Layout g (&m); db::property_names_id_type n1, n2, n3; - n1 = g.properties_repository ().prop_name_id (tl::Variant (17)); - n2 = g.properties_repository ().prop_name_id (tl::Variant ("name")); - n3 = g.properties_repository ().prop_name_id (tl::Variant ((unsigned int) 42)); + n1 = db::property_names_id (tl::Variant (17)); + n2 = db::property_names_id (tl::Variant ("name")); + n3 = db::property_names_id (tl::Variant ((unsigned int) 42)); - db::PropertiesRepository::properties_set s1; - s1.insert (std::make_pair (n1, tl::Variant ("17value"))); - s1.insert (std::make_pair (n2, tl::Variant (117))); + db::PropertiesSet s1; + s1.insert (n1, tl::Variant ("17value")); + s1.insert (n2, tl::Variant (117)); - db::PropertiesRepository::properties_set s2; - s2.insert (std::make_pair (n3, tl::Variant (42))); + db::PropertiesSet s2; + s2.insert (n3, tl::Variant (42)); - db::properties_id_type p1 = g.properties_repository ().properties_id (s1); - db::properties_id_type p2 = g.properties_repository ().properties_id (s2); + db::properties_id_type p1 = db::properties_id (s1); + db::properties_id_type p2 = db::properties_id (s2); g.prop_id (p1); diff --git a/src/plugins/tools/diff/lay_plugin/layDiffToolDialog.cc b/src/plugins/tools/diff/lay_plugin/layDiffToolDialog.cc index c92e55c90..0d3593504 100644 --- a/src/plugins/tools/diff/lay_plugin/layDiffToolDialog.cc +++ b/src/plugins/tools/diff/lay_plugin/layDiffToolDialog.cc @@ -111,9 +111,9 @@ private: size_t m_obj_index; void produce_cell_inst (const db::CellInstArrayWithProperties &ci, const db::Layout *layout, const rdb::Category *cat); - template void produce_diffs_for_xor (const db::PropertiesRepository &pr, const std::vector > &a, const std::vector > &b, double dbu_a, db::Shapes &shapes); - template void produce_diffs (const db::PropertiesRepository &pr, const std::vector > &a, const std::vector > &b, double dbu_a, const rdb::Category *cat); - template void shape_diffs (const db::PropertiesRepository &pr, const std::vector > &a, const std::vector > &b); + template void produce_diffs_for_xor (const std::vector > &a, const std::vector > &b, double dbu_a, db::Shapes &shapes); + template void produce_diffs (const std::vector > &a, const std::vector > &b, double dbu_a, const rdb::Category *cat); + template void shape_diffs (const std::vector > &a, const std::vector > &b); void shape_diffs_found (); }; @@ -200,12 +200,12 @@ RdbDifferenceReceiver::RdbDifferenceReceiver (const db::Layout &layout_a, const } static void -add_property_text (rdb::Item *item, const db::PropertiesRepository &pr, db::properties_id_type prop_id) +add_property_text (rdb::Item *item, db::properties_id_type prop_id) { if (prop_id != 0) { - const db::PropertiesRepository::properties_set &p = pr.properties (prop_id); - for (db::PropertiesRepository::properties_set::const_iterator pp = p.begin (); pp != p.end (); ++pp) { - const tl::Variant &name = pr.prop_name (pp->first); + auto p = db::properties (prop_id).to_map (); + for (auto pp = p.begin (); pp != p.end (); ++pp) { + const tl::Variant &name = pp->first; std::string r = std::string ("property: ") + name.to_string () + " = " + pp->second.to_string (); item->add_value (r); } @@ -237,7 +237,7 @@ RdbDifferenceReceiver::produce_cell_inst (const db::CellInstArrayWithProperties item->add_value (box * layout->dbu ()); if (m_with_properties) { - add_property_text (item, layout->properties_repository (), ci.properties_id ()); + add_property_text (item, ci.properties_id ()); } } @@ -315,13 +315,13 @@ RdbDifferenceReceiver::begin_inst_differences () } void -RdbDifferenceReceiver::instances_in_a (const std::vector & /*insts_a*/, const std::vector & /*cell_names*/, const db::PropertiesRepository & /*props*/) +RdbDifferenceReceiver::instances_in_a (const std::vector & /*insts_a*/, const std::vector & /*cell_names*/) { // .. nothing .. } void -RdbDifferenceReceiver::instances_in_b (const std::vector & /*insts_b*/, const std::vector & /*cell_names*/, const db::PropertiesRepository & /*props*/) +RdbDifferenceReceiver::instances_in_b (const std::vector & /*insts_b*/, const std::vector & /*cell_names*/) { // .. nothing .. } @@ -469,7 +469,7 @@ inline std::string shape_type (const db::Box &) template void -RdbDifferenceReceiver::produce_diffs_for_xor (const db::PropertiesRepository & /*pr*/, const std::vector > &a, const std::vector > &b, double dbu_a, db::Shapes &shapes) +RdbDifferenceReceiver::produce_diffs_for_xor (const std::vector > &a, const std::vector > &b, double dbu_a, db::Shapes &shapes) { db::CplxTrans t (dbu_a); std::vector > anotb; @@ -481,7 +481,7 @@ RdbDifferenceReceiver::produce_diffs_for_xor (const db::PropertiesRepository & / template void -RdbDifferenceReceiver::produce_diffs (const db::PropertiesRepository &pr, const std::vector > &a, const std::vector > &b, double dbu_a, const rdb::Category *cat) +RdbDifferenceReceiver::produce_diffs (const std::vector > &a, const std::vector > &b, double dbu_a, const rdb::Category *cat) { db::CplxTrans t (dbu_a); std::vector > anotb; @@ -499,7 +499,7 @@ RdbDifferenceReceiver::produce_diffs (const db::PropertiesRepository &pr, const item->add_value (t * s->first); if (s->second && m_with_properties) { - add_property_text (item, pr, s->second); + add_property_text (item, s->second); } } @@ -507,15 +507,15 @@ RdbDifferenceReceiver::produce_diffs (const db::PropertiesRepository &pr, const template void -RdbDifferenceReceiver::shape_diffs (const db::PropertiesRepository &pr, const std::vector > &a, const std::vector > &b) +RdbDifferenceReceiver::shape_diffs (const std::vector > &a, const std::vector > &b) { if (m_detailed && m_is_valid_layer_index_a && mp_a_only_per_layer_cat [m_layer_index_a] != 0) { - produce_diffs (pr, a, b, mp_layout_a->dbu (), mp_a_only_per_layer_cat [m_layer_index_a]); + produce_diffs (a, b, mp_layout_a->dbu (), mp_a_only_per_layer_cat [m_layer_index_a]); } if (m_run_xor && m_is_valid_layer_index_a) { db::Shapes shapes; - produce_diffs_for_xor (pr, a, b, mp_layout_a->dbu (), shapes); + produce_diffs_for_xor (a, b, mp_layout_a->dbu (), shapes); for (db::Shapes::shape_iterator s = shapes.begin (db::Shapes::shape_iterator::All); ! s.at_end (); ++s) { m_ep.insert (*s, m_obj_index * 2); ++m_obj_index; @@ -523,12 +523,12 @@ RdbDifferenceReceiver::shape_diffs (const db::PropertiesRepository &pr, const st } if (m_detailed && m_is_valid_layer_index_b && mp_b_only_per_layer_cat [m_layer_index_b] != 0) { - produce_diffs (pr, b, a, mp_layout_b->dbu (), mp_b_only_per_layer_cat [m_layer_index_b]); + produce_diffs (b, a, mp_layout_b->dbu (), mp_b_only_per_layer_cat [m_layer_index_b]); } if (m_run_xor && m_is_valid_layer_index_b) { db::Shapes shapes; - produce_diffs_for_xor (pr, b, a, mp_layout_b->dbu (), shapes); + produce_diffs_for_xor (b, a, mp_layout_b->dbu (), shapes); for (db::Shapes::shape_iterator s = shapes.begin (db::Shapes::shape_iterator::All); ! s.at_end (); ++s) { m_ep.insert (*s, m_obj_index * 2 + 1); ++m_obj_index;