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;