mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
06815fc1dc
commit
2eef9c38d6
|
|
@ -417,18 +417,18 @@ ValueBase::create_from_shape (const db::Shape &shape, const db::CplxTrans &trans
|
||||||
// ValueWrapper implementation
|
// ValueWrapper implementation
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
ValueWrapper::to_string (const Database *rdb) const
|
ValueWrapper::to_string () const
|
||||||
{
|
{
|
||||||
std::string r;
|
std::string r;
|
||||||
r.reserve (200);
|
r.reserve (200);
|
||||||
|
|
||||||
if (tag_id () > 0 && rdb) {
|
if (tag_id () > 0) {
|
||||||
r += "[";
|
r += "[";
|
||||||
const Tag &tag = rdb->tags ().tag (tag_id ());
|
auto np = rdb::Tags::name_for_id (tag_id ());
|
||||||
if (tag.is_user_tag ()) {
|
if (np.second) {
|
||||||
r += "#";
|
r += "#";
|
||||||
}
|
}
|
||||||
r += tl::to_word_or_quoted_string (tag.name ());
|
r += tl::to_word_or_quoted_string (np.first);
|
||||||
r += "] ";
|
r += "] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,14 +438,14 @@ ValueWrapper::to_string (const Database *rdb) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ValueWrapper::from_string (Database *rdb, const std::string &s)
|
ValueWrapper::from_string (const std::string &s)
|
||||||
{
|
{
|
||||||
tl::Extractor ex (s.c_str ());
|
tl::Extractor ex (s.c_str ());
|
||||||
from_string (rdb, ex);
|
from_string (ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ValueWrapper::from_string (Database *rdb, tl::Extractor &ex)
|
ValueWrapper::from_string (tl::Extractor &ex)
|
||||||
{
|
{
|
||||||
id_type tag_id = 0;
|
id_type tag_id = 0;
|
||||||
|
|
||||||
|
|
@ -456,7 +456,7 @@ ValueWrapper::from_string (Database *rdb, tl::Extractor &ex)
|
||||||
std::string tn;
|
std::string tn;
|
||||||
ex.read_word_or_quoted (tn);
|
ex.read_word_or_quoted (tn);
|
||||||
|
|
||||||
tag_id = rdb->tags ().tag (tn, user_tag).id ();
|
tag_id = rdb::Tags::id_for_name (tn, user_tag);
|
||||||
|
|
||||||
ex.test ("]");
|
ex.test ("]");
|
||||||
|
|
||||||
|
|
@ -477,16 +477,16 @@ Values::operator= (const Values &d)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Values::compare (const Values &other, const std::map<id_type, id_type> &tag_map, const std::map<id_type, id_type> &rev_tag_map) const
|
Values::compare (const Values &other, const std::set<id_type> &common_tags) const
|
||||||
{
|
{
|
||||||
Values::const_iterator a = begin (), b = other.begin ();
|
Values::const_iterator a = begin (), b = other.begin ();
|
||||||
while (a != end () && b != other.end ()) {
|
while (a != end () && b != other.end ()) {
|
||||||
|
|
||||||
id_type t12 = 0;
|
id_type t12 = 0;
|
||||||
while (a != end () && a->tag_id () != 0) {
|
while (a != end () && a->tag_id () != 0) {
|
||||||
auto j = tag_map.find (a->tag_id ());
|
auto j = common_tags.find (a->tag_id ());
|
||||||
if (j != tag_map.end ()) {
|
if (j != common_tags.end ()) {
|
||||||
t12 = j->second;
|
t12 = a->tag_id ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++a;
|
++a;
|
||||||
|
|
@ -494,9 +494,9 @@ Values::compare (const Values &other, const std::map<id_type, id_type> &tag_map,
|
||||||
|
|
||||||
id_type t2 = 0;
|
id_type t2 = 0;
|
||||||
while (b != other.end () && b->tag_id () != 0) {
|
while (b != other.end () && b->tag_id () != 0) {
|
||||||
auto j = rev_tag_map.find (b->tag_id ());
|
auto j = common_tags.find (b->tag_id ());
|
||||||
if (j != rev_tag_map.end ()) {
|
if (j != common_tags.end ()) {
|
||||||
t2 = j->first;
|
t2 = b->tag_id ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++b;
|
++b;
|
||||||
|
|
@ -529,7 +529,7 @@ Values::compare (const Values &other, const std::map<id_type, id_type> &tag_map,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Values::to_string (const Database *rdb) const
|
Values::to_string () const
|
||||||
{
|
{
|
||||||
std::string r;
|
std::string r;
|
||||||
r.reserve (200);
|
r.reserve (200);
|
||||||
|
|
@ -540,7 +540,7 @@ Values::to_string (const Database *rdb) const
|
||||||
r += ";";
|
r += ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
r += v->to_string (rdb);
|
r += v->to_string ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -548,14 +548,14 @@ Values::to_string (const Database *rdb) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Values::from_string (Database *rdb, const std::string &s)
|
Values::from_string (const std::string &s)
|
||||||
{
|
{
|
||||||
tl::Extractor ex (s.c_str ());
|
tl::Extractor ex (s.c_str ());
|
||||||
|
|
||||||
while (! ex.at_end ()) {
|
while (! ex.at_end ()) {
|
||||||
|
|
||||||
ValueWrapper v;
|
ValueWrapper v;
|
||||||
v.from_string (rdb, ex);
|
v.from_string (ex);
|
||||||
|
|
||||||
add (v);
|
add (v);
|
||||||
|
|
||||||
|
|
@ -905,6 +905,41 @@ Categories::import_category (Category *category)
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
// Tags implementation
|
// Tags implementation
|
||||||
|
|
||||||
|
static tl::Mutex s_tag_namespace_mutex;
|
||||||
|
static std::map<std::pair<std::string, bool>, id_type> s_tag_namespace;
|
||||||
|
static std::vector<std::pair<std::string, bool> > s_tags;
|
||||||
|
|
||||||
|
const std::pair<std::string, bool> &
|
||||||
|
Tags::name_for_id (id_type tag_id)
|
||||||
|
{
|
||||||
|
tl::MutexLocker locker (&s_tag_namespace_mutex);
|
||||||
|
tl_assert (tag_id > 0 && tag_id <= s_tags.size ());
|
||||||
|
return s_tags [tag_id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
id_type
|
||||||
|
Tags::id_for_name (const std::string &name, bool user_flag)
|
||||||
|
{
|
||||||
|
tl::MutexLocker locker (&s_tag_namespace_mutex);
|
||||||
|
|
||||||
|
auto k = std::make_pair (name, user_flag);
|
||||||
|
auto t = s_tag_namespace.find (k);
|
||||||
|
if (t != s_tag_namespace.end ()) {
|
||||||
|
return t->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
id_type id = s_tags.size () + 1;
|
||||||
|
s_tag_namespace [k] = id;
|
||||||
|
s_tags.push_back (k);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tag
|
||||||
|
Tags::tag_for_name (const std::string &name, bool user_flag)
|
||||||
|
{
|
||||||
|
return Tag (id_for_name (name, user_flag), name, user_flag);
|
||||||
|
}
|
||||||
|
|
||||||
Tags::Tags ()
|
Tags::Tags ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
|
|
@ -913,7 +948,7 @@ Tags::Tags ()
|
||||||
void
|
void
|
||||||
Tags::clear ()
|
Tags::clear ()
|
||||||
{
|
{
|
||||||
m_ids_for_names.clear ();
|
m_tags_per_id.clear ();
|
||||||
m_tags.clear ();
|
m_tags.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -926,26 +961,31 @@ Tags::tag (const std::string &name, bool user_tag) const
|
||||||
Tag &
|
Tag &
|
||||||
Tags::tag (const std::string &name, bool user_tag)
|
Tags::tag (const std::string &name, bool user_tag)
|
||||||
{
|
{
|
||||||
std::map <std::pair<std::string, bool>, id_type>::const_iterator i = m_ids_for_names.find (std::make_pair (name, user_tag));
|
id_type id = id_for_name (name, user_tag);
|
||||||
if (i == m_ids_for_names.end ()) {
|
auto i = m_tags_per_id.find (id);
|
||||||
i = m_ids_for_names.insert (std::make_pair (std::make_pair (name, user_tag), m_tags.size () + 1)).first;
|
if (i == m_tags_per_id.end ()) {
|
||||||
m_tags.push_back (Tag (i->second, name, user_tag));
|
m_tags.push_back (Tag (id, name, user_tag));
|
||||||
|
m_tags_per_id [id] = m_tags.size () - 1;
|
||||||
|
return m_tags.back ();
|
||||||
|
} else {
|
||||||
|
return m_tags [i->second];
|
||||||
}
|
}
|
||||||
return m_tags [i->second - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Tag &
|
const Tag &
|
||||||
Tags::tag (id_type id) const
|
Tags::tag (id_type id) const
|
||||||
{
|
{
|
||||||
tl_assert (id < m_tags.size () + 1 && id > 0);
|
auto i = m_tags_per_id.find (id);
|
||||||
return m_tags [id - 1];
|
tl_assert (i != m_tags_per_id.end ());
|
||||||
|
return m_tags [i->second];
|
||||||
}
|
}
|
||||||
|
|
||||||
Tag &
|
Tag &
|
||||||
Tags::tag (id_type id)
|
Tags::tag (id_type id)
|
||||||
{
|
{
|
||||||
tl_assert (id < m_tags.size () + 1 && id > 0);
|
auto i = m_tags_per_id.find (id);
|
||||||
return m_tags [id - 1];
|
tl_assert (i != m_tags_per_id.end ());
|
||||||
|
return m_tags [i->second];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -958,7 +998,7 @@ Tags::import_tag (const Tag &t)
|
||||||
bool
|
bool
|
||||||
Tags::has_tag (const std::string &name, bool user_tag) const
|
Tags::has_tag (const std::string &name, bool user_tag) const
|
||||||
{
|
{
|
||||||
return m_ids_for_names.find (std::make_pair (name, user_tag)) != m_ids_for_names.end ();
|
return m_tags_per_id.find (id_for_name (name, user_tag)) != m_tags_per_id.end ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
@ -1006,30 +1046,25 @@ Item &Item::operator= (const Item &d)
|
||||||
void
|
void
|
||||||
Item::add_tag (id_type tag_id)
|
Item::add_tag (id_type tag_id)
|
||||||
{
|
{
|
||||||
if (m_tag_ids.size () <= tag_id) {
|
m_tag_ids.insert (tag_id);
|
||||||
m_tag_ids.resize (tag_id + 1, false);
|
|
||||||
}
|
|
||||||
m_tag_ids [tag_id] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Item::remove_tag (id_type tag_id)
|
Item::remove_tag (id_type tag_id)
|
||||||
{
|
{
|
||||||
if (m_tag_ids.size () > tag_id) {
|
m_tag_ids.erase (tag_id);
|
||||||
m_tag_ids [tag_id] = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Item::remove_tags ()
|
Item::remove_tags ()
|
||||||
{
|
{
|
||||||
m_tag_ids = std::vector <bool> ();
|
m_tag_ids.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item::has_tag (id_type tag_id) const
|
Item::has_tag (id_type tag_id) const
|
||||||
{
|
{
|
||||||
return m_tag_ids.size () > tag_id && m_tag_ids [tag_id];
|
return m_tag_ids.find (tag_id) != m_tag_ids.end ();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
|
@ -1082,13 +1117,12 @@ Item::tag_str () const
|
||||||
|
|
||||||
if (! m_tag_ids.empty ()) {
|
if (! m_tag_ids.empty ()) {
|
||||||
|
|
||||||
id_type tag_id = 0;
|
for (std::set<id_type>::const_iterator t = m_tag_ids.begin (); t != m_tag_ids.end (); ++t) {
|
||||||
for (std::vector<bool>::const_iterator t = m_tag_ids.begin (); t != m_tag_ids.end (); ++t, ++tag_id) {
|
|
||||||
if (*t) {
|
if (*t) {
|
||||||
if (! r.empty ()) {
|
if (! r.empty ()) {
|
||||||
r += ",";
|
r += ",";
|
||||||
}
|
}
|
||||||
const Tag &tag = mp_database->tags ().tag (tag_id);
|
const Tag &tag = mp_database->tags ().tag (*t);
|
||||||
if (tag.is_user_tag ()) {
|
if (tag.is_user_tag ()) {
|
||||||
r += "#";
|
r += "#";
|
||||||
}
|
}
|
||||||
|
|
@ -1801,33 +1835,30 @@ namespace
|
||||||
class ValueMapEntryCompare
|
class ValueMapEntryCompare
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ValueMapEntryCompare (const std::map<id_type, id_type> &tag2tag, const std::map<id_type, id_type> &rev_tag2tag)
|
ValueMapEntryCompare (const std::set<id_type> &common_tags)
|
||||||
{
|
{
|
||||||
mp_tag2tag = &tag2tag;
|
mp_common_tags = &common_tags;
|
||||||
mp_rev_tag2tag = &rev_tag2tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() (const Item *a, const Item *b) const
|
bool operator() (const Item *a, const Item *b) const
|
||||||
{
|
{
|
||||||
return a->values ().compare (b->values (), *mp_tag2tag, *mp_rev_tag2tag);
|
return a->values ().compare (b->values (), *mp_common_tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::map<id_type, id_type> *mp_tag2tag;
|
const std::set<id_type> *mp_common_tags;
|
||||||
const std::map<id_type, id_type> *mp_rev_tag2tag;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ValueMapEntry
|
class ValueMapEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ValueMapEntry ()
|
ValueMapEntry ()
|
||||||
: mp_tag2tag (0), mp_rev_tag2tag (0)
|
: mp_common_tags (0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void build (const rdb::Database &rdb, id_type cell_id, id_type cat_id, const std::map<id_type, id_type> &tag2tag, const std::map<id_type, id_type> &rev_tag2tag)
|
void build (const rdb::Database &rdb, id_type cell_id, id_type cat_id, const std::set<id_type> &common_tags)
|
||||||
{
|
{
|
||||||
mp_tag2tag = &tag2tag;
|
mp_common_tags = &common_tags;
|
||||||
mp_rev_tag2tag = &rev_tag2tag;
|
|
||||||
|
|
||||||
auto i2i = rdb.items_by_cell_and_category (cell_id, cat_id);
|
auto i2i = rdb.items_by_cell_and_category (cell_id, cat_id);
|
||||||
|
|
||||||
|
|
@ -1841,13 +1872,13 @@ namespace
|
||||||
m_items.push_back ((*i).operator-> ());
|
m_items.push_back ((*i).operator-> ());
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueMapEntryCompare cmp (*mp_tag2tag, *mp_rev_tag2tag);
|
ValueMapEntryCompare cmp (*mp_common_tags);
|
||||||
std::sort (m_items.begin (), m_items.end (), cmp);
|
std::sort (m_items.begin (), m_items.end (), cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Item *find (const rdb::Item &item) const
|
const Item *find (const rdb::Item &item) const
|
||||||
{
|
{
|
||||||
ValueMapEntryCompare cmp (*mp_tag2tag, *mp_rev_tag2tag);
|
ValueMapEntryCompare cmp (*mp_common_tags);
|
||||||
|
|
||||||
auto i = std::lower_bound (m_items.begin (), m_items.end (), &item, cmp);
|
auto i = std::lower_bound (m_items.begin (), m_items.end (), &item, cmp);
|
||||||
if (i == m_items.end ()) {
|
if (i == m_items.end ()) {
|
||||||
|
|
@ -1863,8 +1894,7 @@ namespace
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<const Item *> m_items;
|
std::vector<const Item *> m_items;
|
||||||
const std::map<id_type, id_type> *mp_tag2tag;
|
const std::set<id_type> *mp_common_tags;
|
||||||
const std::map<id_type, id_type> *mp_rev_tag2tag;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1901,16 +1931,15 @@ Database::apply (const rdb::Database &other)
|
||||||
map_category (*c, *this, cat2cat);
|
map_category (*c, *this, cat2cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, id_type> tags_by_name;
|
std::set<id_type> t1;
|
||||||
for (auto c = tags ().begin_tags (); c != tags ().end_tags (); ++c) {
|
for (auto c = tags ().begin_tags (); c != tags ().end_tags (); ++c) {
|
||||||
tags_by_name.insert (std::make_pair (c->name (), c->id ()));
|
t1.insert (c->id ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<id_type> common_tags;
|
||||||
for (auto c = other.tags ().begin_tags (); c != other.tags ().end_tags (); ++c) {
|
for (auto c = other.tags ().begin_tags (); c != other.tags ().end_tags (); ++c) {
|
||||||
auto t = tags_by_name.find (c->name ());
|
if (t1.find (c->id ()) != t1.end ()) {
|
||||||
if (t != tags_by_name.end ()) {
|
common_tags.insert (c->id ());
|
||||||
tag2tag.insert (std::make_pair (t->second, c->id ()));
|
|
||||||
rev_tag2tag.insert (std::make_pair (c->id (), t->second));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1932,7 +1961,7 @@ Database::apply (const rdb::Database &other)
|
||||||
auto vmap = value_map.find (std::make_pair (icell->second, icat->second));
|
auto vmap = value_map.find (std::make_pair (icell->second, icat->second));
|
||||||
if (vmap == value_map.end ()) {
|
if (vmap == value_map.end ()) {
|
||||||
vmap = value_map.insert (std::make_pair (std::make_pair (icell->second, icat->second), ValueMapEntry ())).first;
|
vmap = value_map.insert (std::make_pair (std::make_pair (icell->second, icat->second), ValueMapEntry ())).first;
|
||||||
vmap->second.build (other, icell->second, icat->second, tag2tag, rev_tag2tag);
|
vmap->second.build (other, icell->second, icat->second, common_tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find a value in the reference DB
|
// find a value in the reference DB
|
||||||
|
|
|
||||||
|
|
@ -629,17 +629,17 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Convert the values collection to a string
|
* @brief Convert the values collection to a string
|
||||||
*/
|
*/
|
||||||
std::string to_string (const Database *rdb = 0) const;
|
std::string to_string () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fill the values collection from the string
|
* @brief Fill the values collection from the string
|
||||||
*/
|
*/
|
||||||
void from_string (Database *rdb, const std::string &s);
|
void from_string (const std::string &s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fill the values collection from an extractor
|
* @brief Fill the values collection from an extractor
|
||||||
*/
|
*/
|
||||||
void from_string (Database *rdb, tl::Extractor &ex);
|
void from_string (tl::Extractor &ex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueBase *mp_ptr;
|
ValueBase *mp_ptr;
|
||||||
|
|
@ -687,7 +687,7 @@ public:
|
||||||
*
|
*
|
||||||
* The order of the values matters.
|
* The order of the values matters.
|
||||||
*/
|
*/
|
||||||
bool compare (const Values &other, const std::map<id_type, id_type> &tag_map, const std::map<id_type, id_type> &rev_tag_map) const;
|
bool compare (const Values &other, const std::set<id_type> &common_tags) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The const iterator (begin)
|
* @brief The const iterator (begin)
|
||||||
|
|
@ -760,12 +760,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Convert the values collection to a string
|
* @brief Convert the values collection to a string
|
||||||
*/
|
*/
|
||||||
std::string to_string (const Database *rdb) const;
|
std::string to_string () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fill the values collection from the string
|
* @brief Fill the values collection from the string
|
||||||
*/
|
*/
|
||||||
void from_string (Database *rdb, const std::string &s);
|
void from_string (const std::string &s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list <ValueWrapper> m_values;
|
std::list <ValueWrapper> m_values;
|
||||||
|
|
@ -1057,7 +1057,7 @@ private:
|
||||||
size_t m_multiplicity;
|
size_t m_multiplicity;
|
||||||
std::string m_comment;
|
std::string m_comment;
|
||||||
bool m_visited;
|
bool m_visited;
|
||||||
std::vector <bool> m_tag_ids;
|
std::set <id_type> m_tag_ids;
|
||||||
Database *mp_database;
|
Database *mp_database;
|
||||||
std::string m_image_str;
|
std::string m_image_str;
|
||||||
|
|
||||||
|
|
@ -1982,11 +1982,32 @@ public:
|
||||||
*/
|
*/
|
||||||
void clear ();
|
void clear ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the name and user flag for a tag ID
|
||||||
|
*
|
||||||
|
* This method will assert if the tag ID is not valid in the global namespace.
|
||||||
|
*/
|
||||||
|
static const std::pair<std::string, bool> &name_for_id (id_type tag_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the id for a given name and user flag
|
||||||
|
*
|
||||||
|
* This will pull the ID from the global namespace.
|
||||||
|
*/
|
||||||
|
static id_type id_for_name (const std::string &name, bool user_flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets a tag object for a given name and user flag
|
||||||
|
*
|
||||||
|
* This will create the tag from the global namespace.
|
||||||
|
*/
|
||||||
|
static Tag tag_for_name (const std::string &name, bool user_flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Database;
|
friend class Database;
|
||||||
|
|
||||||
mutable std::map <std::pair<std::string, bool>, id_type> m_ids_for_names;
|
mutable std::map<id_type, size_t> m_tags_per_id;
|
||||||
mutable std::vector <Tag> m_tags;
|
mutable std::vector<Tag> m_tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -40,50 +40,46 @@ struct ValueConverter
|
||||||
{
|
{
|
||||||
typedef std::string pb_type;
|
typedef std::string pb_type;
|
||||||
|
|
||||||
ValueConverter (rdb::Database *rdb)
|
ValueConverter ()
|
||||||
: mp_rdb (rdb)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string (const ValueWrapper &value) const
|
std::string to_string (const ValueWrapper &value) const
|
||||||
{
|
{
|
||||||
return value.to_string (mp_rdb);
|
return value.to_string ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void from_string (const std::string &s, ValueWrapper &value) const
|
void from_string (const std::string &s, ValueWrapper &value) const
|
||||||
{
|
{
|
||||||
value.from_string (mp_rdb, s);
|
value.from_string (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pb_encode (const ValueWrapper &value) const
|
std::string pb_encode (const ValueWrapper &value) const
|
||||||
{
|
{
|
||||||
return value.to_string (mp_rdb);
|
return value.to_string ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb_decode (const std::string &s, ValueWrapper &value) const
|
void pb_decode (const std::string &s, ValueWrapper &value) const
|
||||||
{
|
{
|
||||||
value.from_string (mp_rdb, s);
|
value.from_string (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
rdb::Database *mp_rdb;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
|
||||||
tl::XMLElementList categories_format =
|
|
||||||
tl::make_element_with_parent_ref<rdb::Category, rdb::Categories::const_iterator, rdb::Categories> (&rdb::Categories::begin, &rdb::Categories::end, &rdb::Categories::import_category, "category",
|
|
||||||
tl::make_member<std::string, rdb::Category> (&rdb::Category::name, &rdb::Category::set_name, "name") +
|
|
||||||
tl::make_member<std::string, rdb::Category> (&rdb::Category::description, &rdb::Category::set_description, "description") +
|
|
||||||
tl::make_element_with_parent_ref<rdb::Categories, rdb::Category> (&rdb::Category::sub_categories, &rdb::Category::import_sub_categories, "categories",
|
|
||||||
&categories_format
|
|
||||||
)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
// generation of the RDB file XML structure
|
// generation of the RDB file XML structure
|
||||||
static tl::XMLStruct <rdb::Database>
|
static tl::XMLStruct <rdb::Database>
|
||||||
make_rdb_structure (rdb::Database *rdb)
|
make_rdb_structure ()
|
||||||
{
|
{
|
||||||
|
static
|
||||||
|
tl::XMLElementList categories_format =
|
||||||
|
tl::make_element_with_parent_ref<rdb::Category, rdb::Categories::const_iterator, rdb::Categories> (&rdb::Categories::begin, &rdb::Categories::end, &rdb::Categories::import_category, "category",
|
||||||
|
tl::make_member<std::string, rdb::Category> (&rdb::Category::name, &rdb::Category::set_name, "name") +
|
||||||
|
tl::make_member<std::string, rdb::Category> (&rdb::Category::description, &rdb::Category::set_description, "description") +
|
||||||
|
tl::make_element_with_parent_ref<rdb::Categories, rdb::Category> (&rdb::Category::sub_categories, &rdb::Category::import_sub_categories, "categories",
|
||||||
|
&categories_format
|
||||||
|
)
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
return tl::XMLStruct <rdb::Database>("report-database",
|
return tl::XMLStruct <rdb::Database>("report-database",
|
||||||
tl::make_member<std::string, rdb::Database> (&rdb::Database::description, &rdb::Database::set_description, "description") +
|
tl::make_member<std::string, rdb::Database> (&rdb::Database::description, &rdb::Database::set_description, "description") +
|
||||||
tl::make_member<std::string, rdb::Database> (&rdb::Database::original_file, &rdb::Database::set_original_file, "original-file") +
|
tl::make_member<std::string, rdb::Database> (&rdb::Database::original_file, &rdb::Database::set_original_file, "original-file") +
|
||||||
|
|
@ -122,13 +118,15 @@ make_rdb_structure (rdb::Database *rdb)
|
||||||
tl::make_member<std::string, rdb::Item> (&rdb::Item::comment, &rdb::Item::set_comment, "comment") +
|
tl::make_member<std::string, rdb::Item> (&rdb::Item::comment, &rdb::Item::set_comment, "comment") +
|
||||||
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image") +
|
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image") +
|
||||||
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values",
|
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values",
|
||||||
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value", ValueConverter (rdb))
|
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value", ValueConverter ())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tl::XMLStruct <rdb::Database> s_rdb_struct = make_rdb_structure ();
|
||||||
|
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
// Implementation of rdb::Database::save and write
|
// Implementation of rdb::Database::save and write
|
||||||
// TODO: move this somewhere else - with generalized functionality
|
// TODO: move this somewhere else - with generalized functionality
|
||||||
|
|
@ -144,7 +142,7 @@ void
|
||||||
rdb::Database::write (const std::string &fn)
|
rdb::Database::write (const std::string &fn)
|
||||||
{
|
{
|
||||||
tl::OutputStream os (fn, tl::OutputStream::OM_Auto);
|
tl::OutputStream os (fn, tl::OutputStream::OM_Auto);
|
||||||
make_rdb_structure (this).write (os, *this);
|
s_rdb_struct.write (os, *this);
|
||||||
|
|
||||||
if (tl::verbosity () >= 10) {
|
if (tl::verbosity () >= 10) {
|
||||||
tl::log << "Saved RDB to " << fn;
|
tl::log << "Saved RDB to " << fn;
|
||||||
|
|
@ -168,7 +166,7 @@ public:
|
||||||
{
|
{
|
||||||
tl::SelfTimer timer (tl::verbosity () >= 11, "Reading marker database file");
|
tl::SelfTimer timer (tl::verbosity () >= 11, "Reading marker database file");
|
||||||
tl::XMLStreamSource in (m_input_stream, tl::to_string (tr ("Reading RDB")));
|
tl::XMLStreamSource in (m_input_stream, tl::to_string (tr ("Reading RDB")));
|
||||||
make_rdb_structure (&db).parse (in, db);
|
s_rdb_struct.parse (in, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char *format () const
|
virtual const char *format () const
|
||||||
|
|
|
||||||
|
|
@ -595,7 +595,7 @@ class RDB_TestClass < TestBase
|
||||||
assert_equal(db.is_modified?, false)
|
assert_equal(db.is_modified?, false)
|
||||||
|
|
||||||
tag_id = db.tag_id("x")
|
tag_id = db.tag_id("x")
|
||||||
assert_equal(tag_id, 1)
|
assert_equal(db.tag_name(tag_id), "x")
|
||||||
db.set_tag_description(tag_id, "xdesc")
|
db.set_tag_description(tag_id, "xdesc")
|
||||||
assert_equal(db.tag_description(tag_id), "xdesc")
|
assert_equal(db.tag_description(tag_id), "xdesc")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue