Bug fixes, RBA tests for meta info

This commit is contained in:
Matthias Koefferlein 2023-04-21 23:33:42 +02:00
parent d1f962a228
commit d9e0d107b1
6 changed files with 144 additions and 26 deletions

View File

@ -1799,7 +1799,7 @@ Layout::meta_info_iterator
Layout::begin_meta (db::cell_index_type ci) const
{
auto m = m_meta_info_by_cell.find (ci);
if (m != m_meta_info_by_cell.find (ci)) {
if (m != m_meta_info_by_cell.end ()) {
return m->second.begin ();
} else {
return s_empty_meta.begin ();
@ -1810,7 +1810,7 @@ Layout::meta_info_iterator
Layout::end_meta (db::cell_index_type ci) const
{
auto m = m_meta_info_by_cell.find (ci);
if (m != m_meta_info_by_cell.find (ci)) {
if (m != m_meta_info_by_cell.end ()) {
return m->second.end ();
} else {
return s_empty_meta.end ();
@ -1871,6 +1871,12 @@ Layout::meta_info (meta_info_name_id_type name_id) const
return n != m_meta_info.end () ? n->second : null_value;
}
bool
Layout::has_meta_info (meta_info_name_id_type name_id) const
{
return m_meta_info.find (name_id) != m_meta_info.end ();
}
void
Layout::clear_meta (db::cell_index_type ci)
{
@ -1907,7 +1913,18 @@ Layout::meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const
return null_value;
}
void
bool
Layout::has_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const
{
auto c = m_meta_info_by_cell.find (ci);
if (c != m_meta_info_by_cell.end ()) {
return c->second.find (name_id) != c->second.end ();
} else {
return false;
}
}
void
Layout::swap_layers (unsigned int a, unsigned int b)
{
tl_assert (m_layers.layer_state (a) != LayoutLayers::Free);

View File

@ -1932,6 +1932,19 @@ public:
*/
const MetaInfo &meta_info (meta_info_name_id_type name_id) const;
/**
* @brief Gets a value indicating whether a meta info with the given name is present
*/
bool has_meta_info (const std::string &name) const
{
return has_meta_info (meta_info_name_id (name));
}
/**
* @brief Gets a value indicating whether a meta info with the given name is present
*/
bool has_meta_info (meta_info_name_id_type name_id) const;
/**
* @brief Clears the meta information for a specific cell
*/
@ -1954,6 +1967,19 @@ public:
*/
void add_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id, const MetaInfo &i);
/**
* @brief Gets a value indicating whether a meta info with the given name is present for the given cell
*/
bool has_meta_info (db::cell_index_type ci, const std::string &name) const
{
return has_meta_info (ci, meta_info_name_id (name));
}
/**
* @brief Gets a value indicating whether a meta info with the given name is present for the given cell
*/
bool has_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const;
/**
* @brief Removes the meta information object with the given name from the given cell
* The method will do nothing if no object with that name exists.

View File

@ -1014,14 +1014,15 @@ static const tl::Variant &cell_meta_info_value (db::Cell *cell, const std::strin
}
}
static MetaInfo cell_meta_info (db::Cell *cell, const std::string &name)
static MetaInfo *cell_meta_info (db::Cell *cell, const std::string &name)
{
if (! cell->layout ()) {
static MetaInfo null_value;
return null_value;
} else {
return 0;
} else if (cell->layout ()->has_meta_info (cell->cell_index (), name)) {
const db::MetaInfo &value = cell->layout ()->meta_info (cell->cell_index (), name);
return MetaInfo (name, value);
return new MetaInfo (name, value);
} else {
return 0;
}
}
@ -1857,7 +1858,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n"
"This method has been introduced in version 0.28.8."
) +
gsi::method_ext ("meta_info", &cell_meta_info, gsi::arg ("name"),
gsi::factory_ext ("meta_info", &cell_meta_info, gsi::arg ("name"),
"@brief Gets the meta information for a given name\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"\n"

View File

@ -908,10 +908,14 @@ static void layout_add_meta_info (db::Layout *layout, const MetaInfo &mi)
layout->add_meta_info (mi.name, db::MetaInfo (mi.description, mi.value));
}
static MetaInfo layout_get_meta_info (db::Layout *layout, const std::string &name)
static MetaInfo *layout_get_meta_info (db::Layout *layout, const std::string &name)
{
const db::MetaInfo &value = layout->meta_info (name);
return MetaInfo (name, value);
if (layout->has_meta_info (name)) {
const db::MetaInfo &value = layout->meta_info (name);
return new MetaInfo (name, value);
} else {
return 0;
}
}
static const tl::Variant &layout_get_meta_info_value (db::Layout *layout, const std::string &name)
@ -1073,11 +1077,11 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been introduced in version 0.25. Starting with version 0.28.8, the value is of variant type instead of string only.\n"
) +
gsi::method_ext ("meta_info", &layout_get_meta_info, gsi::arg ("name"),
gsi::factory_ext ("meta_info", &layout_get_meta_info, gsi::arg ("name"),
"@brief Gets the meta information for a given name\n"
"See \\LayoutMetaInfo for details about layouts and meta information.\n"
"\n"
"If no meta information with the given name exists, a default object with empty fields will be returned.\n"
"If no meta information with the given name exists, nil is returned.\n"
"\n"
"This method has been introduced in version 0.28.8.\n"
) +

View File

@ -27,7 +27,7 @@
namespace gsi
{
static MetaInfo *layout_meta_info_ctor (const std::string &name, const std::string &value, const std::string &description, bool persisted)
static MetaInfo *layout_meta_info_ctor (const std::string &name, const tl::Variant &value, const std::string &description, bool persisted)
{
return new MetaInfo (name, description, value, persisted);
}
@ -101,7 +101,7 @@ Class<MetaInfo> decl_LayoutMetaInfo ("db", "LayoutMetaInfo",
gsi::method_ext ("description=", &layout_meta_set_description,
"@brief Sets the description of the layout meta info object\n"
) +
gsi::method_ext ("persisted", &layout_meta_get_persisted,
gsi::method_ext ("is_persisted?", &layout_meta_get_persisted,
"@brief Gets a value indicating whether the meta information will be persisted\n"
"This predicate was introduced in version 0.28.8.\n"
) +
@ -118,6 +118,22 @@ Class<MetaInfo> decl_LayoutMetaInfo ("db", "LayoutMetaInfo",
"Meta information is identified by a unique name and carries a string value plus an optional description string. "
"The description string is for information only and is not evaluated by code.\n"
"\n"
"Meta information can be attached to the layout object and to cells. It is similar to "
"user properties. The differences are:\n"
"\n"
"@ul\n"
"@li Meta information is stored differently in GDS and OASIS files using the context information added "
" by KLayout to annotated PCell or library cells too. Hence meta information does not pollute "
" the standard user properties space. @/li\n"
"@li The value of meta information can be complex serializable types such as lists, hashes and elementary "
" objects such as \\Box or \\DBox. Scalar types include floats and booleans. @/li\n"
"@li Meta information keys are strings and are supported also for GDS which only accepts integer number "
" keys for user properties. @/li\n"
"@/ul\n"
"\n"
"Note that only meta information marked with \\is_persisted? == true are stored in GDS or OASIS files. "
"This is not the default setting, so you need to explicitly set that flag.\n"
"\n"
"See also \\Layout#each_meta_info, \\Layout#meta_info_value, \\Layout#meta_info and \\Layout#remove_meta_info as "
"well as the corresponding \\Cell methods.\n"
"\n"

View File

@ -1044,36 +1044,39 @@ class DBLayoutTests2_TestClass < TestBase
end
# Meta information
def test_12
def test_12a
mi = RBA::LayoutMetaInfo::new("myinfo", "a")
assert_equal(mi.name, "myinfo")
assert_equal(mi.description, "")
assert_equal(mi.value, "a")
assert_equal(mi.is_persisted?, false)
mi.name = "x"
mi.description = "y"
mi.value = "z"
mi.persisted = true
assert_equal(mi.name, "x")
assert_equal(mi.description, "y")
assert_equal(mi.value, "z")
assert_equal(mi.is_persisted?, true)
ly = RBA::Layout::new
ly.add_meta_info(RBA::LayoutMetaInfo::new("myinfo", "a"))
ly.add_meta_info(RBA::LayoutMetaInfo::new("another", "42", "description"))
ly.add_meta_info(RBA::LayoutMetaInfo::new("another", 42, "description"))
assert_equal(ly.meta_info_value("myinfo"), "a")
assert_equal(ly.meta_info_value("doesnotexist"), "")
assert_equal(ly.meta_info_value("another"), "42")
assert_equal(ly.meta_info_value("doesnotexist"), nil)
assert_equal(ly.meta_info_value("another"), 42)
a = []
ly.each_meta_info { |mi| a << mi.name }
assert_equal(a.join(","), "myinfo,another")
a = []
ly.each_meta_info { |mi| a << mi.value }
ly.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "a,42")
a = []
ly.each_meta_info { |mi| a << mi.description }
@ -1081,13 +1084,64 @@ class DBLayoutTests2_TestClass < TestBase
ly.add_meta_info(RBA::LayoutMetaInfo::new("myinfo", "b"))
assert_equal(ly.meta_info_value("myinfo"), "b")
assert_equal(ly.meta_info_value("doesnotexist"), "")
assert_equal(ly.meta_info_value("another"), "42")
assert_equal(ly.meta_info_value("doesnotexist"), nil)
assert_equal(ly.meta_info_value("another"), 42)
ly.remove_meta_info("doesnotexist") # should not fail
ly.remove_meta_info("myinfo")
assert_equal(ly.meta_info_value("myinfo"), "")
assert_equal(ly.meta_info_value("doesnotexist"), "")
assert_equal(ly.meta_info_value("another"), "42")
assert_equal(ly.meta_info_value("myinfo"), nil)
assert_equal(ly.meta_info_value("doesnotexist"), nil)
assert_equal(ly.meta_info_value("another"), 42)
assert_equal(ly.meta_info("doesnotexist"), nil)
assert_equal(ly.meta_info("another").value, 42)
assert_equal(ly.meta_info("another").description, "description")
ly.clear_meta_info
assert_equal(ly.meta_info_value("another"), nil)
assert_equal(ly.meta_info("another"), nil)
# cellwise
c1 = ly.create_cell("X")
c2 = ly.create_cell("U")
c1.add_meta_info(RBA::LayoutMetaInfo::new("a", true))
c1.add_meta_info(RBA::LayoutMetaInfo::new("b", [ 1, 17, 42 ]))
assert_equal(c2.meta_info("a"), nil)
assert_equal(c2.meta_info_value("a"), nil)
a = []
c2.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "")
assert_equal(c1.meta_info("a").value, true)
assert_equal(c1.meta_info("b").value, [ 1, 17, 42 ])
assert_equal(c1.meta_info_value("b"), [ 1, 17, 42 ])
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "true,[1, 17, 42]")
c1.remove_meta_info("doesnotexist") # should not fail
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "true,[1, 17, 42]")
c1.remove_meta_info("b")
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "true")
c1.clear_meta_info
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "")
end