This commit is contained in:
Matthias Koefferlein 2024-12-24 11:19:21 +01:00
parent dd7aa9b84f
commit 128a00896e
6 changed files with 406 additions and 324 deletions

View File

@ -65,20 +65,18 @@ build_net_name_equivalence (const db::Layout *layout, const db::Connectivity &co
{
std::map<std::string, std::set<size_t> > prop_by_name;
#if 0 // @@@
for (db::PropertiesRepository::iterator i = layout->properties_repository ().begin (); i != layout->properties_repository ().end (); ++i) {
for (db::PropertiesRepository::properties_set::const_iterator p = i->second.begin (); p != i->second.end (); ++p) {
if (p->first == net_name_id) {
std::string nn = p->second.to_string ();
for (std::list<tl::GlobPattern>::const_iterator jp = jn_pattern.begin (); jp != jn_pattern.end (); ++jp) {
if (jp->match (nn)) {
prop_by_name [nn].insert (db::prop_id_to_attr (i->first));
}
{
db::PropertiesRepository::properties_id_set with_name = db::PropertiesRepository::instance ().properties_ids_by_name (net_name_id);
for (auto i = with_name.begin (); i != with_name.end (); ++i) {
const db::PropertiesSet &props = db::properties (*i);
std::string nn = props.value (net_name_id).to_string ();
for (std::list<tl::GlobPattern>::const_iterator jp = jn_pattern.begin (); jp != jn_pattern.end (); ++jp) {
if (jp->match (nn)) {
prop_by_name [nn].insert (db::prop_id_to_attr (*i));
}
}
}
}
#endif
// include pseudo-attributes for global nets to implement "join_with" for global nets
for (size_t gid = 0; gid < conn.global_nets (); ++gid) {
@ -115,18 +113,16 @@ build_net_name_equivalence_for_explicit_connections (const db::Layout *layout, c
{
std::map<std::string, std::set<size_t> > prop_by_name;
#if 0 // @@@
for (db::PropertiesRepository::iterator i = layout->properties_repository ().begin (); i != layout->properties_repository ().end (); ++i) {
for (db::PropertiesRepository::properties_set::const_iterator p = i->second.begin (); p != i->second.end (); ++p) {
if (p->first == net_name_id) {
std::string nn = p->second.to_string ();
if (nets_to_join.find (nn) != nets_to_join.end ()) {
prop_by_name [nn].insert (db::prop_id_to_attr (i->first));
}
{
db::PropertiesRepository::properties_id_set with_name = db::PropertiesRepository::instance ().properties_ids_by_name (net_name_id);
for (auto i = with_name.begin (); i != with_name.end (); ++i) {
const db::PropertiesSet &props = db::properties (*i);
std::string nn = props.value (net_name_id).to_string ();
if (nets_to_join.find (nn) != nets_to_join.end ()) {
prop_by_name [nn].insert (db::prop_id_to_attr (*i));
}
}
}
#endif
// include pseudo-attributes for global nets to implement "join_with" for global nets
for (size_t gid = 0; gid < conn.global_nets (); ++gid) {

View File

@ -187,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::insert_by_id (db::property_names_id_type nid, db::property_values_id_type vid)
{
m_map.insert (std::make_pair (nid, vid));
}
void
PropertiesSet::merge (const db::PropertiesSet &other)
{
@ -230,10 +236,19 @@ PropertiesSet::to_list_var () const
// ----------------------------------------------------------------------------------
// PropertiesRepository implementation
PropertiesRepository &PropertiesRepository::instance ()
static PropertiesRepository s_instance;
static PropertiesRepository *sp_temp_instance = 0;
PropertiesRepository &
PropertiesRepository::instance ()
{
static PropertiesRepository s_instance;
return s_instance;
return sp_temp_instance ? *sp_temp_instance : s_instance;
}
void
PropertiesRepository::replace_instance_temporarily (db::PropertiesRepository *temp)
{
sp_temp_instance = temp;
}
PropertiesRepository::PropertiesRepository ()
@ -383,17 +398,28 @@ PropertiesRepository::is_valid_property_values_id (property_values_id_type id) c
}
PropertiesRepository::properties_id_set
PropertiesRepository::properties_ids_by_name_value (db::property_names_id_type name, db::property_values_id_type value) const
PropertiesRepository::properties_ids_by_name (db::property_names_id_type name_id) const
{
tl::MutexLocker locker (&m_lock);
auto ni = m_properties_by_name_table.find (name_id);
if (ni == m_properties_by_name_table.end ()) {
return properties_id_set ();
} else {
return ni->second;
}
}
PropertiesRepository::properties_id_set
PropertiesRepository::properties_ids_by_name_value (db::property_names_id_type name_id, db::property_values_id_type value_id) const
{
tl::MutexLocker locker (&m_lock);
db::property_names_id_type name_id = property_names_id (name);
auto ni = m_properties_by_name_table.find (name_id);
if (ni == m_properties_by_name_table.end ()) {
return properties_id_set ();
}
db::property_values_id_type value_id = property_values_id (value);
auto vi = m_properties_by_value_table.find (value_id);
if (vi == m_properties_by_value_table.end ()) {
return properties_id_set ();
@ -405,7 +431,7 @@ PropertiesRepository::properties_ids_by_name_value (db::property_names_id_type n
}
// ----------------------------------------------------------------------------------
// PropertiesRepository implementation
// PropertiesTranslator implementation
PropertiesTranslator::PropertiesTranslator ()
: m_pass (true), m_null (true)
@ -478,64 +504,81 @@ PropertiesTranslator::make_pass_all ()
}
PropertiesTranslator
PropertiesTranslator::make_filter (const std::set<tl::Variant> &keys)
PropertiesTranslator::make_filter (const std::set<tl::Variant> &keys, db::PropertiesRepository &repo)
{
std::map<db::properties_id_type, db::properties_id_type> map;
db::PropertiesRepository::properties_id_set ids;
std::set<db::property_names_id_type> names_selected;
#if 0 // @@@ later
for (auto k = keys.begin (); k != keys.end (); ++k) {
names_selected.insert (repo.prop_name_id (*k));
db::property_names_id_type nid = repo.prop_name_id (*k);
names_selected.insert (nid);
db::PropertiesRepository::properties_id_set ids_with_name = repo.properties_ids_by_name (nid);
ids.insert (ids_with_name.begin (), ids_with_name.end ());
}
db::PropertiesRepository org_repo = repo; // @@@ should not be available
std::map<db::properties_id_type, db::properties_id_type> map;
for (auto p = org_repo.begin (); p != org_repo.end (); ++p) {
db::PropertiesRepository::properties_set new_set;
for (auto i = p->second.begin (); i != p->second.end (); ++i) {
if (names_selected.find (i->first) != names_selected.end ()) {
new_set.insert (*i);
for (auto i = ids.begin (); i != ids.end (); ++i) {
const db::PropertiesSet &props = db::properties (*i);
db::PropertiesSet new_props;
for (auto p = props.begin (); p != props.end (); ++p) {
if (names_selected.find (p->first) != names_selected.end ()) {
new_props.insert_by_id (p->first, p->second);
}
}
if (! new_set.empty ()) {
map.insert (std::make_pair (p->first, repo.properties_id (new_set)));
if (! new_props.empty ()) {
map.insert (std::make_pair (*i, new_props == props ? *i : repo.properties_id (new_props)));
}
}
#endif // @@@
return PropertiesTranslator (map);
}
PropertiesTranslator
PropertiesTranslator::make_key_mapper (const std::map<tl::Variant, tl::Variant> &keys)
PropertiesTranslator::make_key_mapper (const std::map<tl::Variant, tl::Variant> &keys, db::PropertiesRepository &repo)
{
std::map<db::properties_id_type, db::properties_id_type> map;
db::PropertiesRepository::properties_id_set ids;
std::map<db::property_names_id_type, db::property_names_id_type> name_map;
#if 0 // @@@ later
for (auto k = keys.begin (); k != keys.end (); ++k) {
name_map.insert (std::make_pair (repo.prop_name_id (k->first), repo.prop_name_id (k->second)));
db::property_names_id_type nid = repo.prop_name_id (k->first);
name_map.insert (std::make_pair (nid, repo.prop_name_id (k->second)));
db::PropertiesRepository::properties_id_set ids_with_name = repo.properties_ids_by_name (nid);
ids.insert (ids_with_name.begin (), ids_with_name.end ());
}
db::PropertiesRepository org_repo = repo; // @@@ should not be available
std::map<db::properties_id_type, db::properties_id_type> map;
for (auto p = org_repo.begin (); p != org_repo.end (); ++p) {
db::PropertiesRepository::properties_set new_set;
for (auto i = p->second.begin (); i != p->second.end (); ++i) {
auto nm = name_map.find (i->first);
for (auto i = ids.begin (); i != ids.end (); ++i) {
const db::PropertiesSet &props = db::properties (*i);
db::PropertiesSet new_props;
for (auto p = props.begin (); p != props.end (); ++p) {
auto nm = name_map.find (p->first);
if (nm != name_map.end ()) {
new_set.insert (std::make_pair (nm->second, i->second));
new_props.insert_by_id (nm->second, p->second);
}
}
if (! new_set.empty ()) {
map.insert (std::make_pair (p->first, repo.properties_id (new_set)));
if (! new_props.empty ()) {
map.insert (std::make_pair (*i, new_props == props ? *i : repo.properties_id (new_props)));
}
}
#endif
return PropertiesTranslator (map);
}
} // namespace db

View File

@ -203,6 +203,11 @@ public:
*/
void insert (db::property_names_id_type name_id, const tl::Variant &value);
/**
* @brief Inserts a value by ID for the given name ID
*/
void insert_by_id (db::property_names_id_type name_id, db::property_values_id_type value_id);
/**
* @brief Merge another properties set into self
*/
@ -292,11 +297,26 @@ class DB_PUBLIC PropertiesRepository
public:
typedef std::set <properties_id_type> properties_id_set;
/**
* @brief Default constructor
*
* This constructor is mainly provided for test purposes.
*/
PropertiesRepository ();
/**
* @brief Gets the singleton instance of the properties repository
*/
static PropertiesRepository &instance ();
/**
* @brief Temporarily replace the singleton instance
*
* This method is intended for testing purposes only. Passing 0 for the
* repository argument resets back to the global singleton.
*/
static void replace_instance_temporarily (db::PropertiesRepository *temp);
/**
* @brief Gets the name ID for a property name
*
@ -372,12 +392,19 @@ public:
/**
* @brief Lookup a table of properties id's by a name value pair
*
* For a given name/value pair, this method returns a vector of ids
* of property sets that contain the given name/value pair. This method
* is intended for use with the properties_id resolution algorithm.
* For a given name/value pair, this method returns a set of property IDs
* of property sets that contain the given name/value pair.
*/
properties_id_set properties_ids_by_name_value (db::property_names_id_type name, db::property_values_id_type value) const;
/**
* @brief Lookup a table of properties id's by a name
*
* For a given name, this method returns a set of property IDs
* of property sets that contain the given name.
*/
properties_id_set properties_ids_by_name (db::property_names_id_type name) const;
/**
* @brief Collect memory statistics
*/
@ -432,11 +459,6 @@ private:
std::map <property_values_id_type, properties_id_set> m_properties_by_value_table;
mutable tl::Mutex m_lock;
/**
* @brief Default constructor
*/
PropertiesRepository ();
};
/**
@ -534,16 +556,20 @@ public:
* @brief Factory: create a filter translator
*
* The translator delivered by this function will leave only the given keys in the properties.
*
* If no repository is given, the translator acts on the singleton instance.
*/
static PropertiesTranslator make_filter (const std::set<tl::Variant> &keys);
static PropertiesTranslator make_filter (const std::set<tl::Variant> &keys, db::PropertiesRepository &repo = db::PropertiesRepository::instance ());
/**
* @brief Factory: create a key mapper translator
*
* The translator delivered by this function will translate the given keys to new ones
* and remove non-listed keys.
*
* If no repository is given, the translator acts on the singleton instance.
*/
static PropertiesTranslator make_key_mapper (const std::map<tl::Variant, tl::Variant> &keys);
static PropertiesTranslator make_key_mapper (const std::map<tl::Variant, tl::Variant> &keys, db::PropertiesRepository &repo = db::PropertiesRepository::instance ());
private:
std::map<db::properties_id_type, db::properties_id_type> m_map;

View File

@ -26,242 +26,189 @@
#include "tlString.h"
#include "tlUnitTest.h"
#if 0 // @@@
TEST(1)
namespace {
/**
* @brief Installs a temporary repository instance for testing
*
* By using a temp instance, we do not disturb other tests.
*/
class TempPropertiesRepository
{
tl::Variant v;
public:
TempPropertiesRepository ()
{
db::PropertiesRepository::replace_instance_temporarily (&m_temp);
}
EXPECT_EQ (std::string (v.to_parsable_string ()) == "nil", true);
~TempPropertiesRepository ()
{
db::PropertiesRepository::replace_instance_temporarily (0);
}
v = 1l;
EXPECT_EQ (std::string (v.to_parsable_string ()) == "#1", true);
EXPECT_EQ (v.to_long () == 1, true);
private:
db::PropertiesRepository m_temp;
};
v = "102";
EXPECT_EQ (std::string (v.to_parsable_string ()) == "'102'", true);
v = 2l;
EXPECT_EQ (std::string (v.to_parsable_string ()) == "#2", true);
EXPECT_EQ (v.is_long (), true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), false);
EXPECT_EQ (v.to_long () == 2, true);
EXPECT_EQ (v.to_double () == 2, true);
v = tl::Variant ();
EXPECT_EQ (std::string (v.to_parsable_string ()) == "nil", true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), false);
EXPECT_EQ (v.is_long (), false);
EXPECT_EQ (v.is_nil (), true);
EXPECT_EQ (v.is_list (), false);
v = tl::Variant ((long) 1);
EXPECT_EQ (std::string (v.to_parsable_string ()) == "#1", true);
EXPECT_EQ (v.to_long () == 1, true);
EXPECT_EQ (v.to_double () == 1, true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), false);
v = tl::Variant ("A");
EXPECT_EQ (std::string (v.to_parsable_string ()) == "'A'", true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), true);
EXPECT_EQ (v.is_long (), false);
EXPECT_EQ (v < tl::Variant (), false);
EXPECT_EQ (tl::Variant (1l) < v, true);
EXPECT_EQ (tl::Variant ("B") < v, false);
EXPECT_EQ (tl::Variant ("A") < v, false);
EXPECT_EQ (tl::Variant (" ") < v, true);
}
TEST(2)
TEST(BasicNames)
{
db::PropertiesRepository rep;
tl::Variant n1 ("Hallo");
tl::Variant n2 ("AAA");
size_t id1 = rep.prop_name_id (n1);
size_t id2 = rep.prop_name_id (n2);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (1));
db::property_names_id_type id1 = rep.prop_name_id (n1);
db::property_names_id_type id2 = rep.prop_name_id (n2);
db::property_names_id_type id1_copy = id1, id2_copy = id2;
id2 = rep.prop_name_id (n2);
id1 = rep.prop_name_id (n1);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (1));
EXPECT_EQ (id1, id1_copy);
EXPECT_EQ (id2, id2_copy);
EXPECT_EQ (rep.prop_name (0) == n1, true);
EXPECT_EQ (rep.prop_name (1) == n2, true);
db::PropertiesRepository rep2;
rep2 = rep;
id2 = rep2.prop_name_id (n2);
id1 = rep2.prop_name_id (n1);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (1));
EXPECT_EQ (rep2.prop_name (0) == n1, true);
EXPECT_EQ (rep2.prop_name (1) == n2, true);
db::PropertiesRepository empty_rep;
rep2 = empty_rep;
id1 = rep2.prop_name_id (n2);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (db::property_name (id1) == n1, true);
EXPECT_EQ (db::property_name (id2) == n2, true);
}
TEST(3)
TEST(BasicValues)
{
db::PropertiesRepository rep;
tl::Variant n1 (1.5);
tl::Variant n2 ("AAA");
tl::Variant v1 ("X");
tl::Variant v2 (17);
size_t id1 = rep.prop_name_id (n1);
size_t id2 = rep.prop_name_id (n2);
db::property_values_id_type id1 = rep.prop_value_id (v1);
db::property_values_id_type id2 = rep.prop_value_id (v2);
db::property_values_id_type id1_copy = id1, id2_copy = id2;
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (1));
id2 = rep.prop_value_id (v2);
id1 = rep.prop_value_id (v1);
id2 = rep.prop_name_id (n2);
id1 = rep.prop_name_id (n1);
EXPECT_EQ (id1, id1_copy);
EXPECT_EQ (id2, id2_copy);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (1));
EXPECT_EQ (rep.prop_name (0) == n1, true);
EXPECT_EQ (rep.prop_name (1) == n2, true);
db::PropertiesRepository rep2;
rep2 = rep;
id2 = rep2.prop_name_id (n2);
id1 = rep2.prop_name_id (n1);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (1));
EXPECT_EQ (rep2.prop_name (0) == n1, true);
EXPECT_EQ (rep2.prop_name (1) == n2, true);
db::PropertiesRepository empty_rep;
rep2 = empty_rep;
id1 = rep2.prop_name_id (n2);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (db::property_value (id1) == v1, true);
EXPECT_EQ (db::property_value (id2) == v2, true);
}
TEST(4)
TEST(BasicPropertySetsInRepository)
{
db::PropertiesRepository::properties_set set1;
db::PropertiesRepository::properties_set set2;
db::PropertiesSet set1;
db::PropertiesSet set2;
set1.insert (std::make_pair (0, tl::Variant (15l)));
set1.insert (std::make_pair (10, tl::Variant (0.125)));
set1.insert_by_id (0, 1);
set1.insert (10, 2);
set2.insert (std::make_pair (0, tl::Variant (15l)));
set2.insert (std::make_pair (9, tl::Variant ("Ein String")));
set2.insert (0, 1);
set2.insert (9, 3);
set2.insert (2, 5);
db::PropertiesRepository rep;
size_t id1 = rep.properties_id (set1);
size_t id2 = rep.properties_id (set2);
EXPECT_EQ (id1, size_t (1));
EXPECT_EQ (id2, size_t (2));
db::properties_id_type id1 = rep.properties_id (set1);
db::properties_id_type id2 = rep.properties_id (set2);
db::properties_id_type id1_copy = id1, id2_copy = id2;
id2 = rep.properties_id (set2);
id1 = rep.properties_id (set1);
EXPECT_EQ (id1, size_t (1));
EXPECT_EQ (id2, size_t (2));
EXPECT_EQ (id1, id1_copy);
EXPECT_EQ (id2, id2_copy);
EXPECT_EQ (rep.properties (1) == set1, true);
EXPECT_EQ (rep.properties (2) == set2, true);
db::PropertiesRepository rep2;
rep2 = rep;
id2 = rep2.properties_id (set2);
id1 = rep2.properties_id (set1);
EXPECT_EQ (id1, size_t (1));
EXPECT_EQ (id2, size_t (2));
EXPECT_EQ (rep2.properties (1) == set1, true);
EXPECT_EQ (rep2.properties (2) == set2, true);
db::PropertiesRepository empty_rep;
rep2 = empty_rep;
id1 = rep2.properties_id (set2);
EXPECT_EQ (id1, size_t (1));
EXPECT_EQ (rep.properties (id1) == set1, true);
EXPECT_EQ (rep.properties (id2) == set2, true);
}
TEST(5)
TEST(PropertySets)
{
tl::Variant v;
tl::Extractor ex (" #10 a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant ((long) 10), true);
ex = tl::Extractor (" ## 12.5 a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant (12.5), true);
ex = tl::Extractor (" Aber a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant ("Aber"), true);
ex = tl::Extractor (" Aber a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant ("Aber"), true);
ex = tl::Extractor (" (Aber_, ##2.500, (#05,x) ,() ) a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (std::string (v.to_parsable_string ()), "('Aber_',##2.5,(#5,'x'),())");
TempPropertiesRepository tmp_repo;
db::PropertiesSet ps1;
db::PropertiesSet ps2;
EXPECT_EQ (ps1.empty (), true);
EXPECT_EQ (ps1.size (), size_t (0));
EXPECT_EQ (ps1.value (tl::Variant (17)).is_nil (), true);
EXPECT_EQ (ps1 == ps2, true);
EXPECT_EQ (ps1 != ps2, false);
EXPECT_EQ (ps1 < ps2, false);
EXPECT_EQ (ps2 < ps1, false);
ps1.insert (tl::Variant (17), tl::Variant ("value"));
EXPECT_EQ (ps1.empty (), false);
EXPECT_EQ (ps1.size (), size_t (1));
EXPECT_EQ (ps1.has_value (tl::Variant (17)), true);
EXPECT_EQ (ps1.has_value (tl::Variant ()), false);
EXPECT_EQ (ps1.has_value (tl::Variant ("x")), false);
EXPECT_EQ (ps1.value (tl::Variant (17)).to_string (), "value");
EXPECT_EQ (ps1.value (tl::Variant ("x")).is_nil (), true);
EXPECT_EQ (ps1.value (db::property_names_id (17)).to_string (), "value");
EXPECT_EQ (ps1.value (db::property_names_id ("x")).is_nil (), true);
EXPECT_EQ (ps1 [tl::Variant (17)].to_string (), "value");
EXPECT_EQ (ps1 [tl::Variant ("x")].is_nil (), true);
EXPECT_EQ (ps1 == ps2, false);
EXPECT_EQ (ps1 != ps2, true);
EXPECT_EQ (ps1 < ps2, true);
EXPECT_EQ (ps2 < ps1, false);
ps2.swap (ps1);
EXPECT_EQ (ps1.value (tl::Variant (17)).is_nil (), true);
EXPECT_EQ (ps2.value (tl::Variant (17)).to_string (), "value");
ps2 = ps1;
EXPECT_EQ (ps1.value (tl::Variant (17)).to_string (), "value");
EXPECT_EQ (ps1.value (tl::Variant ("x")).is_nil (), true);
EXPECT_EQ (ps1 == ps2, true);
EXPECT_EQ (ps1 != ps2, false);
EXPECT_EQ (ps1 < ps2, false);
EXPECT_EQ (ps2 < ps1, false);
ps2.erase (tl::Variant (17));
EXPECT_EQ (ps2.value (tl::Variant (17)).is_nil (), true);
EXPECT_EQ (ps2.has_value (tl::Variant (17)), false);
EXPECT_EQ (ps2.size (), size_t (0));
EXPECT_EQ (ps2.empty (), true);
ps1.clear ();
EXPECT_EQ (ps1.size (), size_t (0));
EXPECT_EQ (ps1.empty (), true);
}
TEST(6)
TEST(PropertySetsMerge)
{
db::PropertiesRepository rep;
TempPropertiesRepository tmp_repo;
tl::Variant n1(1);
tl::Variant n2(1l);
db::PropertiesSet ps1, ps2;
ps1.insert (tl::Variant (17), tl::Variant ("value"));
ps2.insert (tl::Variant ("x"), tl::Variant (42));
EXPECT_EQ (n1 == n2, true);
EXPECT_EQ (n1 < n2, false);
EXPECT_EQ (n2 < n1, false);
ps1.merge (ps2);
size_t id1 = rep.prop_name_id (n1);
size_t id2 = rep.prop_name_id (n2);
EXPECT_EQ (id1, size_t (0));
EXPECT_EQ (id2, size_t (0));
db::PropertiesRepository::properties_set set1;
db::PropertiesRepository::properties_set set2;
set1.insert (std::make_pair (0, tl::Variant ("JTAG_DIO1")));
set2.insert (std::make_pair (0, tl::Variant (2)));
size_t pid1 = rep.properties_id (set1);
size_t pid2 = rep.properties_id (set2);
EXPECT_EQ (pid1, size_t (1));
EXPECT_EQ (pid2, size_t (2));
EXPECT_EQ (ps1.to_dict_var ().to_string (), "...");
}
TEST(PropertySetsConversions)
{
TempPropertiesRepository tmp_repo;
TEST(10_PropertiesTranslator)
db::PropertiesSet ps1;
ps1.insert (tl::Variant (17), tl::Variant ("value"));
ps1.insert (tl::Variant ("x"), tl::Variant (42));
EXPECT_EQ (ps1.to_dict_var ().to_string (), "...");
EXPECT_EQ (ps1.to_list_var ().to_string (), "...");
auto ps1_map = ps1.to_map ();
EXPECT_EQ (ps1_map.size (), size_t (2));
EXPECT_EQ (ps1_map.find (tl::Variant (17))->second.to_string (), "value");
EXPECT_EQ (ps1_map.find (tl::Variant ("x"))->second.to_string (), "42");
EXPECT_EQ (ps1_map.find (tl::Variant (42)) == ps1_map.end (), true);
}
TEST(PropertiesTranslator)
{
EXPECT_EQ (db::PropertiesTranslator ().is_null (), true);
EXPECT_EQ (db::PropertiesTranslator ().is_pass (), true);
@ -278,118 +225,111 @@ TEST(10_PropertiesTranslator)
db::property_names_id_type key2 = rp.prop_name_id (2);
db::property_names_id_type key3 = rp.prop_name_id (3);
db::PropertiesRepository::properties_set ps;
ps.insert (std::make_pair (key1, 100));
ps.insert (std::make_pair (key2, 101));
db::PropertiesSet ps;
ps.insert (key1, 100);
ps.insert (key2, 101);
db::properties_id_type prop1a = rp.properties_id (ps);
EXPECT_EQ (prop2string (rp, prop1a), "1=100\n2=101");
EXPECT_EQ (db::prop2string (prop1a), "1=100\n2=101");
ps.clear ();
ps.insert (std::make_pair (key1, 0));
ps.insert (std::make_pair (key2, 101));
ps.insert (key1, 0);
ps.insert (key2, 101);
db::properties_id_type prop1b = rp.properties_id (ps);
EXPECT_EQ (prop2string (rp, prop1b), "1=0\n2=101");
EXPECT_EQ (db::prop2string (prop1b), "1=0\n2=101");
ps.clear ();
ps.insert (std::make_pair (key1, 100));
ps.insert (std::make_pair (key3, 102));
ps.insert (key1, 100);
ps.insert (key3, 102);
db::properties_id_type prop2 = rp.properties_id (ps);
EXPECT_EQ (prop2string (rp, prop2), "1=100\n3=102");
EXPECT_EQ (db::prop2string (prop2), "1=100\n3=102");
ps.clear ();
ps.insert (std::make_pair (key1, 100));
ps.insert (key1, 100);
db::properties_id_type prop3 = rp.properties_id (ps);
EXPECT_EQ (prop2string (rp, prop3), "1=100");
db::PropertiesRepository rp_org = rp;
EXPECT_EQ (db::prop2string (prop3), "1=100");
db::PropertiesTranslator t;
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100\n2=101");
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0\n2=101");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102");
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
EXPECT_EQ (db::prop2string (t (prop1a)), "1=100\n2=101");
EXPECT_EQ (db::prop2string (t (prop1b)), "1=0\n2=101");
EXPECT_EQ (db::prop2string (t (prop2)), "1=100\n3=102");
EXPECT_EQ (db::prop2string (t (prop3)), "1=100");
t = db::PropertiesTranslator::make_pass_all ();
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100\n2=101");
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0\n2=101");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102");
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
EXPECT_EQ (db::prop2string (t (prop1a)), "1=100\n2=101");
EXPECT_EQ (db::prop2string (t (prop1b)), "1=0\n2=101");
EXPECT_EQ (db::prop2string (t (prop2)), "1=100\n3=102");
EXPECT_EQ (db::prop2string (t (prop3)), "1=100");
t = db::PropertiesTranslator::make_remove_all ();
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
EXPECT_EQ (prop2string (rp, t (prop2)), "");
EXPECT_EQ (prop2string (rp, t (prop3)), "");
EXPECT_EQ (db::prop2string (t (prop1a)), "");
EXPECT_EQ (db::prop2string (t (prop1b)), "");
EXPECT_EQ (db::prop2string (t (prop2)), "");
EXPECT_EQ (db::prop2string (t (prop3)), "");
std::set<tl::Variant> kf;
kf.insert (1);
t = db::PropertiesTranslator::make_filter (rp, kf);
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100");
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100");
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
t = db::PropertiesTranslator::make_filter (kf, rp);
EXPECT_EQ (db::prop2string (t (prop1a)), "1=100");
EXPECT_EQ (db::prop2string (t (prop1b)), "1=0");
EXPECT_EQ (db::prop2string (t (prop2)), "1=100");
EXPECT_EQ (db::prop2string (t (prop3)), "1=100");
kf.insert (3);
t = db::PropertiesTranslator::make_filter (rp, kf);
EXPECT_EQ (prop2string (rp, t (prop1a)), "1=100");
EXPECT_EQ (prop2string (rp, t (prop1b)), "1=0");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=100\n3=102");
EXPECT_EQ (prop2string (rp, t (prop3)), "1=100");
t = db::PropertiesTranslator::make_filter (kf, rp);
EXPECT_EQ (db::prop2string (t (prop1a)), "1=100");
EXPECT_EQ (db::prop2string (t (prop1b)), "1=0");
EXPECT_EQ (db::prop2string (t (prop2)), "1=100\n3=102");
EXPECT_EQ (db::prop2string (t (prop3)), "1=100");
std::map<tl::Variant, tl::Variant> km;
km[1] = 4;
km[3] = 1;
t = db::PropertiesTranslator::make_key_mapper (rp, km);
EXPECT_EQ (prop2string (rp, t (prop1a)), "4=100");
EXPECT_EQ (prop2string (rp, t (prop1b)), "4=0");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=102\n4=100");
EXPECT_EQ (prop2string (rp, t (prop3)), "4=100");
t = db::PropertiesTranslator::make_key_mapper (km, rp);
EXPECT_EQ (db::prop2string (t (prop1a)), "4=100");
EXPECT_EQ (db::prop2string (t (prop1b)), "4=0");
EXPECT_EQ (db::prop2string (t (prop2)), "1=102\n4=100");
EXPECT_EQ (db::prop2string (t (prop3)), "4=100");
kf.clear ();
kf.insert (4);
t = db::PropertiesTranslator::make_filter (rp, kf) * db::PropertiesTranslator::make_key_mapper (rp, km);
t = db::PropertiesTranslator::make_filter (kf, rp) * db::PropertiesTranslator::make_key_mapper (km, rp);
EXPECT_EQ (t.is_empty (), false);
EXPECT_EQ (prop2string (rp, t (prop1a)), "4=100");
EXPECT_EQ (prop2string (rp, t (prop1b)), "4=0");
EXPECT_EQ (prop2string (rp, t (prop2)), "4=100");
EXPECT_EQ (prop2string (rp, t (prop3)), "4=100");
EXPECT_EQ (db::prop2string (t (prop1a)), "4=100");
EXPECT_EQ (db::prop2string (t (prop1b)), "4=0");
EXPECT_EQ (db::prop2string (t (prop2)), "4=100");
EXPECT_EQ (db::prop2string (t (prop3)), "4=100");
kf.clear ();
kf.insert (3);
t = db::PropertiesTranslator::make_filter (rp, kf) * db::PropertiesTranslator::make_key_mapper (rp, km);
t = db::PropertiesTranslator::make_filter (kf, rp) * db::PropertiesTranslator::make_key_mapper (km, rp);
EXPECT_EQ (t.is_empty (), true);
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
EXPECT_EQ (prop2string (rp, t (prop2)), "");
EXPECT_EQ (prop2string (rp, t (prop3)), "");
EXPECT_EQ (db::prop2string (t (prop1a)), "");
EXPECT_EQ (db::prop2string (t (prop1b)), "");
EXPECT_EQ (db::prop2string (t (prop2)), "");
EXPECT_EQ (db::prop2string (t (prop3)), "");
t = db::PropertiesTranslator::make_key_mapper (rp, km) * db::PropertiesTranslator::make_filter (rp, kf);
t = db::PropertiesTranslator::make_key_mapper (km, rp) * db::PropertiesTranslator::make_filter (kf, rp);
EXPECT_EQ (t.is_empty (), false);
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=102");
EXPECT_EQ (prop2string (rp, t (prop3)), "");
EXPECT_EQ (db::prop2string (t (prop1a)), "");
EXPECT_EQ (db::prop2string (t (prop1b)), "");
EXPECT_EQ (db::prop2string (t (prop2)), "1=102");
EXPECT_EQ (db::prop2string (t (prop3)), "");
rp = rp_org;
t = db::PropertiesTranslator::make_key_mapper (rp, km);
t = db::PropertiesTranslator::make_filter (rp, kf) * t;
t = db::PropertiesTranslator::make_key_mapper (km, rp);
t = db::PropertiesTranslator::make_filter (kf, rp) * t;
EXPECT_EQ (t.is_empty (), true);
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
EXPECT_EQ (prop2string (rp, t (prop2)), "");
EXPECT_EQ (prop2string (rp, t (prop3)), "");
EXPECT_EQ (db::prop2string (t (prop1a)), "");
EXPECT_EQ (db::prop2string (t (prop1b)), "");
EXPECT_EQ (db::prop2string (t (prop2)), "");
EXPECT_EQ (db::prop2string (t (prop3)), "");
rp = rp_org;
t = db::PropertiesTranslator::make_filter (rp, kf);
t = db::PropertiesTranslator::make_key_mapper (rp, km) * t;
t = db::PropertiesTranslator::make_filter (kf, rp);
t = db::PropertiesTranslator::make_key_mapper (km, rp) * t;
EXPECT_EQ (t.is_empty (), false);
EXPECT_EQ (prop2string (rp, t (prop1a)), "");
EXPECT_EQ (prop2string (rp, t (prop1b)), "");
EXPECT_EQ (prop2string (rp, t (prop2)), "1=102");
EXPECT_EQ (prop2string (rp, t (prop3)), "");
EXPECT_EQ (db::prop2string (t (prop1a)), "");
EXPECT_EQ (db::prop2string (t (prop1b)), "");
EXPECT_EQ (db::prop2string (t (prop2)), "1=102");
EXPECT_EQ (db::prop2string (t (prop3)), "");
}
#endif

View File

@ -3406,9 +3406,10 @@ PartialService::handle_guiding_shape_changes ()
parent_inst = s->first.back ().inst_ptr;
}
// @@@ name by id, don't repeat key
db::property_names_id_type name_id = db::property_names_id ("name");
const db::PropertiesSet &input_props = db::properties (s->first.shape ().prop_id ());
tl::Variant name_value = input_props.value (tl::Variant ("name"));
tl::Variant name_value = input_props.value (name_id);
if (name_value.is_nil ()) {
return false;
}
@ -3431,7 +3432,7 @@ PartialService::handle_guiding_shape_changes ()
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::PropertiesSet &props = db::properties (sh->prop_id ());
if (props.value (tl::Variant ("name")) == shape_name) {
if (props.value (name_id) == shape_name) {
lay::ObjectInstPath inst_path = s->first;
inst_path.back ().inst_ptr = new_inst;
inst_path.back ().array_inst = new_inst.begin ();

View File

@ -1276,4 +1276,80 @@ TEST(10)
EXPECT_EQ (vnan < vnan, false);
}
// some tests originally from PropertiesRepositoryTests
TEST(11)
{
tl::Variant v;
EXPECT_EQ (std::string (v.to_parsable_string ()) == "nil", true);
v = 1l;
EXPECT_EQ (std::string (v.to_parsable_string ()) == "#1", true);
EXPECT_EQ (v.to_long () == 1, true);
v = "102";
EXPECT_EQ (std::string (v.to_parsable_string ()) == "'102'", true);
v = 2l;
EXPECT_EQ (std::string (v.to_parsable_string ()) == "#2", true);
EXPECT_EQ (v.is_long (), true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), false);
EXPECT_EQ (v.to_long () == 2, true);
EXPECT_EQ (v.to_double () == 2, true);
v = tl::Variant ();
EXPECT_EQ (std::string (v.to_parsable_string ()) == "nil", true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), false);
EXPECT_EQ (v.is_long (), false);
EXPECT_EQ (v.is_nil (), true);
EXPECT_EQ (v.is_list (), false);
v = tl::Variant ((long) 1);
EXPECT_EQ (std::string (v.to_parsable_string ()) == "#1", true);
EXPECT_EQ (v.to_long () == 1, true);
EXPECT_EQ (v.to_double () == 1, true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), false);
v = tl::Variant ("A");
EXPECT_EQ (std::string (v.to_parsable_string ()) == "'A'", true);
EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.is_a_string (), true);
EXPECT_EQ (v.is_long (), false);
EXPECT_EQ (v < tl::Variant (), false);
EXPECT_EQ (tl::Variant (1l) < v, true);
EXPECT_EQ (tl::Variant ("B") < v, false);
EXPECT_EQ (tl::Variant ("A") < v, false);
EXPECT_EQ (tl::Variant (" ") < v, true);
}
// some tests originally from PropertiesRepositoryTests
TEST(12)
{
tl::Variant v;
tl::Extractor ex (" #10 a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant ((long) 10), true);
ex = tl::Extractor (" ## 12.5 a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant (12.5), true);
ex = tl::Extractor (" Aber a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant ("Aber"), true);
ex = tl::Extractor (" Aber a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (v == tl::Variant ("Aber"), true);
ex = tl::Extractor (" (Aber_, ##2.500, (#05,x) ,() ) a");
ex.read (v);
ex.expect ("a");
EXPECT_EQ (std::string (v.to_parsable_string ()), "('Aber_',##2.5,(#5,'x'),())");
}
}