First features to support cell meta data

This commit is contained in:
Matthias Koefferlein 2023-04-16 20:25:30 +02:00
parent 5083e6e45e
commit df4221cfc9
8 changed files with 503 additions and 108 deletions

View File

@ -124,6 +124,7 @@ SOURCES = \
gsiDeclDbLibrary.cc \
gsiDeclDbManager.cc \
gsiDeclDbMatrix.cc \
gsiDeclDbMetaInfo.cc \
gsiDeclDbPath.cc \
gsiDeclDbPoint.cc \
gsiDeclDbPolygon.cc \

View File

@ -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<meta_info_name_id_type>::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

View File

@ -465,7 +465,8 @@ public:
typedef pcell_name_map::const_iterator pcell_iterator;
typedef std::map<std::pair<lib_id_type, cell_index_type>, cell_index_type> lib_proxy_map;
typedef LayerIterator layer_iterator;
typedef std::vector<MetaInfo> meta_info;
typedef size_t meta_info_name_id_type;
typedef std::map<meta_info_name_id_type, MetaInfo> 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<std::string, meta_info_name_id_type> m_meta_info_name_map;
std::vector<std::string> m_meta_info_names;
meta_info m_meta_info;
std::map<db::cell_index_type, meta_info> m_meta_info_by_cell;
std::string m_tech_name;
tl::Mutex m_lock;

View File

@ -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);
}

View File

@ -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<db::Cell> 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 "

View File

@ -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<db::MetaInfo> 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<db::Layout> 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<void (db::Layout::*) ()> (&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<void (db::Layout::*) (const std::string &name)> (&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<const tl::Variant &(db::Layout::*) (const std::string &name) const> (&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"

View File

@ -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<MetaInfo> 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."
);
}

View File

@ -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 <string>
#include <iterator>
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<db::Layout *> (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<db::Layout> mp_layout;
db::Layout::meta_info_iterator m_b, m_e;
};
}
#endif