Consistently differenting between double and int values as property keys (otherwise there may be a confusing mix present in the property repository)

This commit is contained in:
Matthias Koefferlein 2025-08-03 19:46:31 +02:00
parent 4773bb3227
commit 8a5e83bf5d
4 changed files with 48 additions and 15 deletions

View File

@ -462,24 +462,16 @@ public:
}
private:
struct CompareNamePtrByValueForValues
struct CompareVariantPtrByValue
{
bool operator() (const tl::Variant *a, const tl::Variant *b) const
{
// NOTE: for values, the type should matter, so 2.0 is different from 2 (integer).
// NOTE: for values and names, the type should matter, so 2.0 is different from 2 (integer).
// Hence we use "less" here.
return a->less (*b);
}
};
struct CompareNamePtrByValueForNames
{
bool operator() (const tl::Variant *a, const tl::Variant *b) const
{
return *a < *b;
}
};
struct ComparePropertiesPtrByValue
{
bool operator() (const PropertiesSet *a, const PropertiesSet *b) const
@ -488,9 +480,9 @@ private:
}
};
std::set <const tl::Variant *, CompareNamePtrByValueForNames> m_propnames;
std::set <const tl::Variant *, CompareVariantPtrByValue> m_propnames;
std::list <tl::Variant> m_property_names_heap;
std::set <const tl::Variant *, CompareNamePtrByValueForValues> m_propvalues;
std::set <const tl::Variant *, CompareVariantPtrByValue> m_propvalues;
std::list <tl::Variant> m_property_values_heap;
std::set <const PropertiesSet *, ComparePropertiesPtrByValue> m_properties;
std::list <PropertiesSet> m_properties_heap;

View File

@ -472,3 +472,34 @@ TEST(PropertiesSetHash)
EXPECT_EQ (ps2.hash (), h1);
EXPECT_EQ (db::hash_for_properties_id (rp.properties_id (ps2)), h1);
}
TEST(SameValueDifferentTypes)
{
{
db::PropertiesRepository rp;
EXPECT_EQ (db::property_value (rp.prop_value_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_value (rp.prop_value_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_value (rp.prop_value_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_value (rp.prop_value_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((double) 5)).to_parsable_string (), "##5");
}
{
db::PropertiesRepository rp;
EXPECT_EQ (db::property_value (rp.prop_value_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_value (rp.prop_value_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_value (rp.prop_value_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_value (rp.prop_value_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((int) 5)).to_parsable_string (), "#5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((double) 5)).to_parsable_string (), "##5");
EXPECT_EQ (db::property_name (rp.prop_name_id ((int) 5)).to_parsable_string (), "#5");
}
}

View File

@ -1151,6 +1151,8 @@ normalized_types (Variant::type type1, Variant::type type2)
type2 = Variant::t_double;
}
// Ruby sometimes produces byte arrays instead of strings, so use those
// as common type for strings and byte arrays
if (is_string_type (type1) && type2 == Variant::t_bytearray) {
type1 = Variant::t_bytearray;
} else if (is_string_type (type2) && type1 == Variant::t_bytearray) {
@ -1174,6 +1176,14 @@ normalized_type_rigid (Variant::type type1, Variant::type type2)
type1 = normalized_type (type1);
type2 = normalized_type (type2);
// Ruby sometimes produces byte arrays instead of strings, so use those
// as common type for strings and byte arrays
if (is_string_type (type1) && type2 == Variant::t_bytearray) {
type1 = Variant::t_bytearray;
} else if (is_string_type (type2) && type1 == Variant::t_bytearray) {
type2 = Variant::t_bytearray;
}
return std::make_pair (type1 == type2, type1);
}

View File

@ -1144,11 +1144,11 @@ class DBLayoutTest(unittest.TestCase):
shape = s
self.assertEqual(shape.property(2), "hello, world")
self.assertEqual(shape.property("2"), None)
self.assertEqual(shape.property(2.0), "hello, world")
self.assertEqual(shape.property(2.0), None)
self.assertEqual(shape.property(22), None)
self.assertEqual(shape.property(42), "the answer")
self.assertEqual(shape.property("42"), None)
self.assertEqual(shape.property(42.0), "the answer")
self.assertEqual(shape.property(42.0), None)
ly2 = pya.Layout()
ly2.read(file_oas)
@ -1158,7 +1158,7 @@ class DBLayoutTest(unittest.TestCase):
shape = s
self.assertEqual(shape.property(2), "hello, world")
self.assertEqual(shape.property("2"), None)
self.assertEqual(shape.property(2.0), "hello, world")
self.assertEqual(shape.property(2.0), None)
self.assertEqual(shape.property(22), None)
self.assertEqual(shape.property("42"), "the answer")
self.assertEqual(shape.property(42), None)