From df4221cfc90f6d4ac0f70678183dff6a1d21abda Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 16 Apr 2023 20:25:30 +0200 Subject: [PATCH] First features to support cell meta data --- src/db/db/db.pro | 1 + src/db/db/dbLayout.cc | 119 +++++++++++++++++++++++++++------ src/db/db/dbLayout.h | 116 ++++++++++++++++++++++++++++++-- src/db/db/dbMetaInfo.h | 9 +-- src/db/db/gsiDeclDbCell.cc | 75 ++++++++++++++++++++- src/db/db/gsiDeclDbLayout.cc | 91 +++++-------------------- src/db/db/gsiDeclDbMetaInfo.cc | 105 +++++++++++++++++++++++++++++ src/db/db/gsiDeclDbMetaInfo.h | 95 ++++++++++++++++++++++++++ 8 files changed, 503 insertions(+), 108 deletions(-) create mode 100644 src/db/db/gsiDeclDbMetaInfo.cc create mode 100644 src/db/db/gsiDeclDbMetaInfo.h diff --git a/src/db/db/db.pro b/src/db/db/db.pro index 066dbb5d2..6914e12fa 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -124,6 +124,7 @@ SOURCES = \ gsiDeclDbLibrary.cc \ gsiDeclDbManager.cc \ gsiDeclDbMatrix.cc \ + gsiDeclDbMetaInfo.cc \ gsiDeclDbPath.cc \ gsiDeclDbPoint.cc \ gsiDeclDbPolygon.cc \ diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc index edeeb0800..8885fd6de 100644 --- a/src/db/db/dbLayout.cc +++ b/src/db/db/dbLayout.cc @@ -1204,6 +1204,11 @@ Layout::take_cell (cell_index_type ci) m_cell_ptrs [ci] = 0; + auto mi = m_meta_info_by_cell.find (ci); + if (mi != m_meta_info_by_cell.end ()) { + m_meta_info_by_cell.erase (mi); + } + // Using free cell indices does have one significant drawback: // The cellview references cannot be uniquely classified as being invalid - because the // ID might be reused. This causes problems, when a cell is being deleted and subsequently a @@ -1748,6 +1753,58 @@ Layout::do_update () delete pr; } +static Layout::meta_info s_empty_meta; + +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)) { + return m->second.begin (); + } else { + return s_empty_meta.begin (); + } +} + +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)) { + return m->second.end (); + } else { + return s_empty_meta.end (); + } +} + +const std::string & +Layout::meta_info_name (Layout::meta_info_name_id_type name_id) const +{ + static std::string empty; + return name_id < m_meta_info_names.size () ? m_meta_info_names[name_id] : empty; +} + +Layout::meta_info_name_id_type +Layout::meta_info_name_id (const std::string &name) +{ + auto n = m_meta_info_name_map.find (name); + if (n != m_meta_info_name_map.end ()) { + return n->second; + } else { + size_t id = m_meta_info_names.size (); + m_meta_info_names.push_back (name); + m_meta_info_name_map.insert (std::make_pair (name, id)); + return id; + } +} + +Layout::meta_info_name_id_type +Layout::meta_info_name_id (const std::string &name) const +{ + auto n = m_meta_info_name_map.find (name); + return n != m_meta_info_name_map.end () ? n->second : std::numeric_limits::max (); +} + void Layout::clear_meta () { @@ -1755,39 +1812,59 @@ Layout::clear_meta () } void -Layout::add_meta_info (const MetaInfo &i) +Layout::add_meta_info (meta_info_name_id_type name_id, const MetaInfo &i) { - for (meta_info::iterator m = m_meta_info.begin (); m != m_meta_info.end (); ++m) { - if (m->name == i.name) { - *m = i; - return; - } - } - m_meta_info.push_back (i); + m_meta_info[name_id] = i; } void -Layout::remove_meta_info (const std::string &name) +Layout::remove_meta_info (meta_info_name_id_type name_id) { - for (meta_info::iterator m = m_meta_info.begin (); m != m_meta_info.end (); ++m) { - if (m->name == name) { - m_meta_info.erase (m); - return; - } + m_meta_info.erase (name_id); +} + +const tl::Variant & +Layout::meta_info_value (meta_info_name_id_type name_id) const +{ + auto n = m_meta_info.find (name_id); + static tl::Variant null_value; + return n != m_meta_info.end () ? n->second.value : null_value; +} + +void +Layout::clear_meta (db::cell_index_type ci) +{ + m_meta_info_by_cell.erase (ci); +} + +void +Layout::add_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id, const MetaInfo &i) +{ + m_meta_info_by_cell[ci][name_id] = i; +} + +void +Layout::remove_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) +{ + auto c = m_meta_info_by_cell.find (ci); + if (c != m_meta_info_by_cell.end ()) { + c->second.erase (name_id); } } -const std::string & -Layout::meta_info_value (const std::string &name) const +const tl::Variant & +Layout::meta_info_value (db::cell_index_type ci, meta_info_name_id_type name_id) const { - for (meta_info::const_iterator m = m_meta_info.begin (); m != m_meta_info.end (); ++m) { - if (m->name == name) { - return m->value; + auto c = m_meta_info_by_cell.find (ci); + if (c != m_meta_info_by_cell.end ()) { + auto i = c->second.find (name_id); + if (i != c->second.end ()) { + return i->second.value; } } - static const std::string s_empty; - return s_empty; + static tl::Variant null_value; + return null_value; } void diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index 232f52465..265561f6b 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -465,7 +465,8 @@ public: typedef pcell_name_map::const_iterator pcell_iterator; typedef std::map, cell_index_type> lib_proxy_map; typedef LayerIterator layer_iterator; - typedef std::vector meta_info; + typedef size_t meta_info_name_id_type; + typedef std::map meta_info; typedef meta_info::const_iterator meta_info_iterator; /** @@ -1812,6 +1813,31 @@ public: return m_meta_info.end (); } + /** + * @brief Delivers the meta information (begin iterator) per cell + */ + meta_info_iterator begin_meta (db::cell_index_type ci) const; + + /** + * @brief Delivers the meta information (end iterator) per cell + */ + meta_info_iterator end_meta (db::cell_index_type ci) const; + + /** + * @brief Gets the meta informatio name by ID + */ + const std::string &meta_info_name (meta_info_name_id_type name_id) const; + + /** + * @brief Gets the meta information name ID for a specific string + */ + meta_info_name_id_type meta_info_name_id (const std::string &name) const; + + /** + * @brief Gets the meta information name ID for a specific string (const version) + */ + meta_info_name_id_type meta_info_name_id (const std::string &name); + /** * @brief Clears the meta information */ @@ -1819,22 +1845,98 @@ public: /** * @brief Adds meta information - * The given meta information object is appended at the end of the meta information list. + * The given meta information object is added to the meta information list. * If a meta info object with the same name already exists it is overwritten. */ - void add_meta_info (const MetaInfo &i); + void add_meta_info (const std::string &name, const MetaInfo &i) + { + add_meta_info (meta_info_name_id (name), i); + } + + /** + * @brief Adds meta information (variant with name ID) + */ + void add_meta_info (meta_info_name_id_type name_id, const MetaInfo &i); /** * @brief Removes the meta information object with the given name * The method will do nothing if no object with that name exists. */ - void remove_meta_info (const std::string &name); + void remove_meta_info (const std::string &name) + { + remove_meta_info (meta_info_name_id (name)); + } + + /** + * @brief Removes the meta information object with the given name ID + */ + void remove_meta_info (meta_info_name_id_type name_id); /** * @brief Gets the meta info value for a meta info object with the given name * If no object with that name exists, an empty string is returned */ - const std::string &meta_info_value (const std::string &name) const; + const tl::Variant &meta_info_value (const std::string &name) const + { + return meta_info_value (meta_info_name_id (name)); + } + + /** + * @brief Gets the meta info value for a meta info object with the given name ID + */ + const tl::Variant &meta_info_value (meta_info_name_id_type name_id) const; + + /** + * @brief Clears the meta information for a specific cell + */ + void clear_meta (db::cell_index_type ci); + + /** + * @brief Adds meta information for a given cell + * The given meta information object is to the meta information list for the given cell. + * If a meta info object with the same name already exists it is overwritten. + */ + void add_meta_info (db::cell_index_type ci, const std::string &name, const MetaInfo &i) + { + add_meta_info (ci, meta_info_name_id (name), i); + } + + /** + * @brief Adds meta information for a given cell (version with name ID) + * The given meta information object is appended at the end of the meta information list. + * If a meta info object with the same name already exists it is overwritten. + */ + void add_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id, const MetaInfo &i); + + /** + * @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. + */ + void remove_meta_info (db::cell_index_type ci, const std::string &name) + { + remove_meta_info (ci, meta_info_name_id (name)); + } + + /** + * @brief Removes the meta information object with the given name ID from the given cell + * The method will do nothing if no object with that name exists. + */ + void remove_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id); + + /** + * @brief Gets the meta info value for a meta info object with the given name for the given cell + * If no object with that name exists, an empty string is returned + */ + const tl::Variant &meta_info_value (db::cell_index_type ci, const std::string &name) const + { + return meta_info_value (ci, meta_info_name_id (name)); + } + + /** + * @brief Gets the meta info value for a meta info object with the given name ID for the given cell + * If no object with that name exists, an empty string is returned + */ + const tl::Variant &meta_info_value (db::cell_index_type ci, meta_info_name_id_type name_id) const; /** * @brief This event is triggered when the technology changes @@ -1876,7 +1978,11 @@ private: lib_proxy_map m_lib_proxy_map; bool m_do_cleanup; bool m_editable; + std::map m_meta_info_name_map; + std::vector m_meta_info_names; meta_info m_meta_info; + std::map m_meta_info_by_cell; + std::string m_tech_name; tl::Mutex m_lock; diff --git a/src/db/db/dbMetaInfo.h b/src/db/db/dbMetaInfo.h index e5410751e..9a3778f6a 100644 --- a/src/db/db/dbMetaInfo.h +++ b/src/db/db/dbMetaInfo.h @@ -36,14 +36,13 @@ namespace db * * In the meta information block, the reader provides additional information * about the file and content etc. - * "name" is a unique name that can be used to identify the information. * "description" is a "speaking" description of the information. * "value" is the value of the specific part of meta information. */ struct DB_PUBLIC MetaInfo { - MetaInfo (const std::string &n, const std::string &d, const std::string &v) - : name (n), description (d), value (v) + MetaInfo (const std::string &d, const tl::Variant &v) + : description (d), value (v) { // .. nothing else .. } @@ -53,9 +52,8 @@ struct DB_PUBLIC MetaInfo // .. nothing else .. } - std::string name; std::string description; - std::string value; + tl::Variant value; }; /** @@ -63,7 +61,6 @@ struct DB_PUBLIC MetaInfo */ inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const MetaInfo &v, bool no_self, void *parent) { - db::mem_stat (stat, purpose, cat, v.name, no_self, parent); db::mem_stat (stat, purpose, cat, v.description, no_self, parent); db::mem_stat (stat, purpose, cat, v.value, no_self, parent); } diff --git a/src/db/db/gsiDeclDbCell.cc b/src/db/db/gsiDeclDbCell.cc index 00db50666..fd86ac3a8 100644 --- a/src/db/db/gsiDeclDbCell.cc +++ b/src/db/db/gsiDeclDbCell.cc @@ -20,9 +20,8 @@ */ - - #include "gsiDecl.h" +#include "gsiDeclDbMetaInfo.h" #include "gsiDeclDbHelpers.h" #include "dbLayout.h" @@ -984,6 +983,46 @@ static db::Layout *layout (db::Cell *cell) return cell->layout (); } +static void cell_clear_meta_info (db::Cell *cell) +{ + if (cell->layout ()) { + cell->layout ()->clear_meta (cell->cell_index ()); + } +} + +static void cell_remove_meta_info (db::Cell *cell, const std::string &name) +{ + if (cell->layout ()) { + cell->layout ()->remove_meta_info (cell->cell_index (), name); + } +} + +static void cell_add_meta_info (db::Cell *cell, const MetaInfo &mi) +{ + if (cell->layout ()) { + cell->layout ()->add_meta_info (cell->cell_index (), mi.name, db::MetaInfo (mi.description, mi.value)); + } +} + +static const tl::Variant &cell_meta_info_value (db::Cell *cell, const std::string &name) +{ + if (! cell->layout ()) { + static tl::Variant null_value; + return null_value; + } else { + return cell->layout ()->meta_info_value (cell->cell_index (), name); + } +} + +static gsi::MetaInfoIterator cell_each_meta_info (const db::Cell *cell) +{ + if (! cell->layout ()) { + return gsi::MetaInfoIterator (); + } else { + return gsi::MetaInfoIterator (cell->layout (), cell->layout ()->begin_meta (cell->cell_index ()), cell->layout ()->end_meta (cell->cell_index ())); + } +} + static bool cell_has_prop_id (const db::Cell *c) { return c->prop_id () != 0; @@ -1780,6 +1819,38 @@ Class decl_Cell ("db", "Cell", "\n" "This method has been introduced in version 0.23." ) + + gsi::method_ext ("add_meta_info", &cell_add_meta_info, gsi::arg ("info"), + "@brief Adds meta information to the cell\n" + "See \\LayoutMetaInfo for details about cells and meta information.\n" + "\n" + "This method has been introduced in version 0.28.7." + ) + + gsi::method_ext ("clear_meta_info", &cell_clear_meta_info, + "@brief Clears the meta information of the cell\n" + "See \\LayoutMetaInfo for details about cells and meta information.\n" + "\n" + "This method has been introduced in version 0.28.7." + ) + + gsi::method_ext ("remove_meta_info", &cell_remove_meta_info, gsi::arg ("name"), + "@brief Removes meta information from the cell\n" + "See \\LayoutMetaInfo for details about cells and meta information.\n" + "\n" + "This method has been introduced in version 0.28.7." + ) + + gsi::method_ext ("meta_info_value", &cell_meta_info_value, gsi::arg ("name"), + "@brief Gets the meta information value for a given name\n" + "See \\LayoutMetaInfo for details about cells and meta information.\n" + "\n" + "If no meta information with the given name exists, an nil value will be returned.\n" + "\n" + "This method has been introduced in version 0.28.7." + ) + + gsi::iterator_ext ("each_meta_info", &cell_each_meta_info, + "@brief Iterates over the meta information of the cell\n" + "See \\LayoutMetaInfo for details about cells and meta information.\n" + "\n" + "This method has been introduced in version 0.28.7." + ) + gsi::method_ext ("write", &write_simple, gsi::arg ("file_name"), "@brief Writes the cell to a layout file\n" "The format of the file will be determined from the file name. Only the cell and " diff --git a/src/db/db/gsiDeclDbLayout.cc b/src/db/db/gsiDeclDbLayout.cc index bff85e070..de20c8e6f 100644 --- a/src/db/db/gsiDeclDbLayout.cc +++ b/src/db/db/gsiDeclDbLayout.cc @@ -22,6 +22,7 @@ #include "gsiDecl.h" +#include "gsiDeclDbMetaInfo.h" #include "dbLayout.h" #include "dbClip.h" #include "dbRecursiveShapeIterator.h" @@ -902,39 +903,14 @@ static db::Cell *create_cell4 (db::Layout *layout, const std::string &name, cons return &layout->cell (layout->get_lib_proxy (lib, lib_cell)); } -static db::MetaInfo *layout_meta_info_ctor (const std::string &name, const std::string &value, const std::string &description) +static void layout_add_meta_info (db::Layout *layout, const MetaInfo &mi) { - return new db::MetaInfo (name, description, value); + layout->add_meta_info (mi.name, db::MetaInfo (mi.description, mi.value)); } -static void layout_meta_set_name (db::MetaInfo *mi, const std::string &n) +static MetaInfoIterator layout_each_meta_info (const db::Layout *layout) { - mi->name = n; -} - -static const std::string &layout_meta_get_name (const db::MetaInfo *mi) -{ - return mi->name; -} - -static void layout_meta_set_value (db::MetaInfo *mi, const std::string &n) -{ - mi->value = n; -} - -static const std::string &layout_meta_get_value (const db::MetaInfo *mi) -{ - return mi->value; -} - -static void layout_meta_set_description (db::MetaInfo *mi, const std::string &n) -{ - mi->description = n; -} - -static const std::string &layout_meta_get_description (const db::MetaInfo *mi) -{ - return mi->description; + return MetaInfoIterator (layout, layout->begin_meta (), layout->end_meta ()); } static void scale_and_snap1 (db::Layout *layout, db::Cell &cell, db::Coord g, db::Coord m, db::Coord d) @@ -997,45 +973,6 @@ static void move_tree_shapes3 (db::Layout *layout, db::Layout &source_layout, co db::move_shapes (*layout, source_layout, trans, cm.source_cells (), cm.table (), lm.table ()); } -Class decl_LayoutMetaInfo ("db", "LayoutMetaInfo", - gsi::constructor ("new", &layout_meta_info_ctor, gsi::arg ("name"), gsi::arg ("value"), gsi::arg ("description", std::string ()), - "@brief Creates a layout meta info object\n" - "@param name The name\n" - "@param value The value\n" - "@param description An optional description text\n" - ) + - gsi::method_ext ("name", &layout_meta_get_name, - "@brief Gets the name of the layout meta info object\n" - ) + - gsi::method_ext ("name=", &layout_meta_set_name, - "@brief Sets the name of the layout meta info object\n" - ) + - gsi::method_ext ("value", &layout_meta_get_value, - "@brief Gets the value of the layout meta info object\n" - ) + - gsi::method_ext ("value=", &layout_meta_set_value, - "@brief Sets the value of the layout meta info object\n" - ) + - gsi::method_ext ("description", &layout_meta_get_description, - "@brief Gets the description of the layout meta info object\n" - ) + - gsi::method_ext ("description=", &layout_meta_set_description, - "@brief Sets the description of the layout meta info object\n" - ), - "@brief A piece of layout meta information\n" - "Layout meta information is basically additional data that can be attached to a layout. " - "Layout readers may generate meta information and some writers will add layout information to " - "the layout object. Some writers will also read meta information to determine certain attributes.\n" - "\n" - "Multiple layout meta information objects can be attached to one layout using \\Layout#add_meta_info. " - "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" - "See also \\Layout#each_meta_info and \\Layout#meta_info_value and \\Layout#remove_meta_info" - "\n" - "This class has been introduced in version 0.25." -); - static void dtransform (db::Layout *layout, const db::DTrans &trans) { db::CplxTrans dbu_trans (layout->dbu ()); @@ -1097,27 +1034,33 @@ Class decl_Layout ("db", "Layout", "\n" "This method has been introduced in version 0.27.9." ) + - gsi::method ("add_meta_info", &db::Layout::add_meta_info, gsi::arg ("info"), + gsi::method_ext ("add_meta_info", &layout_add_meta_info, gsi::arg ("info"), "@brief Adds meta information to the layout\n" "See \\LayoutMetaInfo for details about layouts and meta information." "\n" "This method has been introduced in version 0.25." ) + - gsi::method ("remove_meta_info", &db::Layout::remove_meta_info, gsi::arg ("name"), + gsi::method ("clear_meta_info", static_cast (&db::Layout::clear_meta), + "@brief Clears the meta information of the layout\n" + "See \\LayoutMetaInfo for details about layouts and meta information." + "\n" + "This method has been introduced in version 0.28.7." + ) + + gsi::method ("remove_meta_info", static_cast (&db::Layout::remove_meta_info), gsi::arg ("name"), "@brief Removes meta information from the layout\n" "See \\LayoutMetaInfo for details about layouts and meta information." "\n" "This method has been introduced in version 0.25." ) + - gsi::method ("meta_info_value", &db::Layout::meta_info_value, gsi::arg ("name"), + gsi::method ("meta_info_value", static_cast (&db::Layout::meta_info_value), gsi::arg ("name"), "@brief Gets the meta information value 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, an empty string will be returned.\n" + "If no meta information with the given name exists, an nil value will be returned.\n" "\n" - "This method has been introduced in version 0.25." + "This method has been introduced in version 0.25. Starting with version 0.28.7, the value is of variant type instead of string only.\n" ) + - gsi::iterator ("each_meta_info", &db::Layout::begin_meta, &db::Layout::end_meta, + gsi::iterator_ext ("each_meta_info", &layout_each_meta_info, "@brief Iterates over the meta information of the layout\n" "See \\LayoutMetaInfo for details about layouts and meta information.\n" "\n" diff --git a/src/db/db/gsiDeclDbMetaInfo.cc b/src/db/db/gsiDeclDbMetaInfo.cc new file mode 100644 index 000000000..656a6d611 --- /dev/null +++ b/src/db/db/gsiDeclDbMetaInfo.cc @@ -0,0 +1,105 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "gsiDecl.h" +#include "gsiDeclDbMetaInfo.h" + +namespace gsi +{ + +static MetaInfo *layout_meta_info_ctor (const std::string &name, const std::string &value, const std::string &description) +{ + return new MetaInfo (name, description, value); +} + +static void layout_meta_set_name (MetaInfo *mi, const std::string &n) +{ + mi->name = n; +} + +static const std::string &layout_meta_get_name (const MetaInfo *mi) +{ + return mi->name; +} + +static void layout_meta_set_value (MetaInfo *mi, const tl::Variant &n) +{ + mi->value = n; +} + +static const tl::Variant &layout_meta_get_value (const MetaInfo *mi) +{ + return mi->value; +} + +static void layout_meta_set_description (MetaInfo *mi, const std::string &n) +{ + mi->description = n; +} + +static const std::string &layout_meta_get_description (const MetaInfo *mi) +{ + return mi->description; +} + + +Class decl_LayoutMetaInfo ("db", "LayoutMetaInfo", + gsi::constructor ("new", &layout_meta_info_ctor, gsi::arg ("name"), gsi::arg ("value"), gsi::arg ("description", std::string ()), + "@brief Creates a layout meta info object\n" + "@param name The name\n" + "@param value The value\n" + "@param description An optional description text\n" + ) + + gsi::method_ext ("name", &layout_meta_get_name, + "@brief Gets the name of the layout meta info object\n" + ) + + gsi::method_ext ("name=", &layout_meta_set_name, + "@brief Sets the name of the layout meta info object\n" + ) + + gsi::method_ext ("value", &layout_meta_get_value, + "@brief Gets the value of the layout meta info object\n" + ) + + gsi::method_ext ("value=", &layout_meta_set_value, + "@brief Sets the value of the layout meta info object\n" + ) + + gsi::method_ext ("description", &layout_meta_get_description, + "@brief Gets the description of the layout meta info object\n" + ) + + gsi::method_ext ("description=", &layout_meta_set_description, + "@brief Sets the description of the layout meta info object\n" + ), + "@brief A piece of layout meta information\n" + "Layout meta information is basically additional data that can be attached to a layout. " + "Layout readers may generate meta information and some writers will add layout information to " + "the layout object. Some writers will also read meta information to determine certain attributes.\n" + "\n" + "Multiple layout meta information objects can be attached to one layout using \\Layout#add_meta_info. " + "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" + "See also \\Layout#each_meta_info and \\Layout#meta_info_value and \\Layout#remove_meta_info" + "\n" + "This class has been introduced in version 0.25." +); + +} diff --git a/src/db/db/gsiDeclDbMetaInfo.h b/src/db/db/gsiDeclDbMetaInfo.h new file mode 100644 index 000000000..aea636b05 --- /dev/null +++ b/src/db/db/gsiDeclDbMetaInfo.h @@ -0,0 +1,95 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef _HDR_gsiDeclDbMetaInfo +#define _HDR_gsiDeclDbMetaInfo + +#include "dbLayout.h" +#include "tlVariant.h" +#include "tlObject.h" + +#include +#include + +namespace gsi +{ + +struct MetaInfo +{ + MetaInfo (const std::string &n, const std::string &d, const tl::Variant &v) + : name (n), description (d), value (v) + { } + + MetaInfo () + : name (), description (), value () + { } + + std::string name; + std::string description; + tl::Variant value; +}; + +struct MetaInfoIterator +{ + typedef std::forward_iterator_tag iterator_category; + typedef MetaInfo value_type; + typedef void difference_type; + typedef MetaInfo reference; + typedef void pointer; + + MetaInfoIterator () + : mp_layout (), m_b (), m_e () + { } + + MetaInfoIterator (const db::Layout *layout, db::Layout::meta_info_iterator b, db::Layout::meta_info_iterator e) + : mp_layout (const_cast (layout)), m_b (b), m_e (e) + { } + + bool at_end () const + { + return !mp_layout || m_b == m_e; + } + + void operator++ () + { + if (mp_layout) { + ++m_b; + } + } + + MetaInfo operator* () const + { + if (mp_layout) { + return MetaInfo (mp_layout->meta_info_name (m_b->first), m_b->second.description, m_b->second.value); + } else { + return MetaInfo (); + } + } + +private: + tl::weak_ptr mp_layout; + db::Layout::meta_info_iterator m_b, m_e; +}; + +} + +#endif