WIP - refined tl::Variant::equal and less implementation, fixed tests

This commit is contained in:
Matthias Koefferlein 2024-12-25 17:36:29 +01:00
parent dc73b8145f
commit 1278ffeb77
9 changed files with 74 additions and 42 deletions

View File

@ -1395,22 +1395,8 @@ PrintingDifferenceReceiver::print_diffs (const std::vector <std::pair <SH, db::p
std::set_difference (a.begin (), a.end (), b.begin (), b.end (), std::back_inserter (anotb));
for (typename std::vector <std::pair <SH, db::properties_id_type> >::const_iterator s = anotb.begin (); s != anotb.end (); ++s) {
enough (tl::info) << " " << s->first.to_string () << tl::noendl;
if (s->second != 0) {
if (m_print_properties) {
const db::PropertiesSet &props = db::properties (s->second);
for (db::PropertiesSet::iterator p = props.begin (); p != props.end (); ++p) {
const tl::Variant &name = property_name (p->first);
const tl::Variant &value = property_value (p->second);
if (name.is_long ()) {
tl::info << " {" << int (name.to_long ()) << " {" << value.to_string () << "}}" << tl::noendl;
} else {
tl::info << " {{" << name.to_string () << "} {" << value.to_string () << "}}" << tl::noendl;
}
}
tl::info << "";
} else {
tl::info << " [" << s->second << "]";
}
if (s->second != 0 && m_print_properties) {
tl::info << " " << db::properties (s->second).to_dict_var ().to_string ();
} else {
tl::info << "";
}

View File

@ -157,7 +157,7 @@ public:
*
* @return True, if the layouts are identical
*/
bool DB_PUBLIC compare_layouts (const db::Layout &a, const db::Layout &b, unsigned int flags, db::Coord tolerance, size_t max_count = 0, bool print_properties = false);
bool DB_PUBLIC compare_layouts (const db::Layout &a, const db::Layout &b, unsigned int flags, db::Coord tolerance, size_t max_count = 0, bool print_properties = true);
/**
* @brief Compare two layout objects
@ -176,7 +176,7 @@ bool DB_PUBLIC compare_layouts (const db::Layout &a, const db::Layout &b, unsign
*
* @return True, if the layouts are identical
*/
bool DB_PUBLIC compare_layouts (const db::Layout &a, db::cell_index_type top_a, const db::Layout &b, db::cell_index_type top_b, unsigned int flags, db::Coord tolerance, size_t max_count = 0, bool print_properties = false);
bool DB_PUBLIC compare_layouts (const db::Layout &a, db::cell_index_type top_a, const db::Layout &b, db::cell_index_type top_b, unsigned int flags, db::Coord tolerance, size_t max_count = 0, bool print_properties = true);
/**
* @brief Compare two layout objects with a custom receiver for the differences

View File

@ -1744,7 +1744,7 @@ TEST(40_BoolWithProperties)
db::Region clip_region_wp (new db::FlatRegion ());
db::PropertiesSet ps;
ps.insert (tl::Variant (1), 42);
ps.insert (tl::Variant (1), "42"); // "42" needs to be a string as GDS properties are strings as well
db::properties_id_type pid42 = db::properties_id (ps);
clip_region_wp.insert (db::BoxWithProperties (clip, pid42));

View File

@ -1009,6 +1009,9 @@ is_integer_type (Variant::type type)
}
}
/**
* @brief normalized_type
*/
inline Variant::type
normalized_type (Variant::type type)
{
@ -1017,6 +1020,12 @@ normalized_type (Variant::type type)
case Variant::t_double:
return Variant::t_double;
case Variant::t_char:
// NOTE: char can be signed or unsigned
if (std::numeric_limits<char>::min () < 0) {
return Variant::t_longlong;
} else {
return Variant::t_ulonglong;
}
case Variant::t_schar:
case Variant::t_short:
case Variant::t_int:
@ -1048,7 +1057,7 @@ normalized_type (Variant::type type)
}
}
inline std::pair<bool, Variant::type>
inline std::pair<bool, Variant::type>
normalized_type (Variant::type type1, Variant::type type2)
{
type1 = normalized_type (type1);
@ -1069,6 +1078,23 @@ normalized_type (Variant::type type1, Variant::type type2)
}
}
/**
* @brief A more rigid definition of "normalized_type" with two arguments
*
* The former version allows casting floats to integers while this version
* treats floats differently.
*
* This version is employed in Variant::less and Variant::equal.
*/
inline std::pair<bool, Variant::type>
normalized_type_rigid (Variant::type type1, Variant::type type2)
{
type1 = normalized_type (type1);
type2 = normalized_type (type2);
return std::make_pair (type1 == type2, type1);
}
static const double epsilon = 1e-13;
// NOTE: in order to be able to use Variant for std::map or std::set
@ -1106,14 +1132,8 @@ static inline bool fless (double a, double b)
}
bool
Variant::operator== (const tl::Variant &d) const
Variant::equal_core (const tl::Variant &d, type t) const
{
std::pair<bool, type> tt = normalized_type (m_type, d.m_type);
if (! tt.first) {
return false;
}
type t = tt.second;
if (t == t_nil) {
return true;
} else if (t == t_bool) {
@ -1161,15 +1181,8 @@ Variant::operator== (const tl::Variant &d) const
}
bool
Variant::operator< (const tl::Variant &d) const
Variant::less_core (const tl::Variant &d, type t) const
{
std::pair<bool, type> tt = normalized_type (m_type, d.m_type);
if (! tt.first) {
return normalized_type (m_type) < normalized_type (d.m_type);
}
type t = tt.second;
if (t == t_nil) {
return false;
} else if (t == t_bool) {
@ -1224,22 +1237,48 @@ Variant::operator< (const tl::Variant &d) const
}
}
bool
Variant::operator== (const tl::Variant &d) const
{
std::pair<bool, type> tt = normalized_type (m_type, d.m_type);
if (! tt.first) {
return false;
} else {
return equal_core (d, tt.second);
}
}
bool
Variant::operator< (const tl::Variant &d) const
{
std::pair<bool, type> tt = normalized_type (m_type, d.m_type);
if (! tt.first) {
return normalized_type (m_type) < normalized_type (d.m_type);
} else {
return less_core (d, tt.second);
}
}
bool
Variant::equal (const Variant &d) const
{
if (m_type != d.m_type) {
std::pair<bool, type> tt = normalized_type_rigid (m_type, d.m_type);
if (! tt.first) {
return false;
} else {
return equal_core (d, tt.second);
}
return operator== (d);
}
bool
Variant::less (const Variant &d) const
{
if (m_type != d.m_type) {
return m_type < d.m_type;
std::pair<bool, type> tt = normalized_type_rigid (m_type, d.m_type);
if (! tt.first) {
return normalized_type (m_type) < normalized_type (d.m_type);
} else {
return less_core (d, tt.second);
}
return operator< (d);
}
bool
@ -1640,7 +1679,6 @@ Variant::can_convert_to_uint () const
case t_long:
return m_var.m_long >= (long) std::numeric_limits<unsigned int>::min () && (sizeof (long) == sizeof (unsigned int) || m_var.m_long <= (long) std::numeric_limits<unsigned int>::max ());
case t_bool:
case t_char:
case t_uchar:
case t_schar:
case t_short:
@ -1648,6 +1686,8 @@ Variant::can_convert_to_uint () const
case t_uint:
case t_nil:
return true;
case t_char:
return m_var.m_char >= 0;
case t_string:
#if defined(HAVE_QT)
case t_qstring:

View File

@ -1720,6 +1720,8 @@ private:
mutable char *m_string;
void set_user_object (void *obj, bool shared);
bool equal_core (const Variant &d, type t) const;
bool less_core (const Variant &d, type t) const;
};
// specializations of the to ... methods

View File

@ -871,7 +871,7 @@ TEST(4)
EXPECT_EQ (v.can_convert_to_ulonglong (), true);
v = tl::Variant (-1);
EXPECT_EQ (v.can_convert_to_char (), true);
EXPECT_EQ (v.can_convert_to_char (), std::numeric_limits<char>::min () < 0 ? true : false);
EXPECT_EQ (v.can_convert_to_uchar (), false);
EXPECT_EQ (v.can_convert_to_double (), true);
EXPECT_EQ (v.can_convert_to_float (), true);
@ -1332,6 +1332,8 @@ TEST(11)
// compare without type
EXPECT_EQ (tl::Variant (1l) == tl::Variant (1.0), true);
EXPECT_EQ (tl::Variant (1l) == tl::Variant (1), true);
EXPECT_EQ (tl::Variant (1l) == tl::Variant (1u), false);
EXPECT_EQ (tl::Variant (1l) == tl::Variant (1.5), false);
EXPECT_EQ (tl::Variant (1l) < tl::Variant (1.0), false);
EXPECT_EQ (tl::Variant (1.0) < tl::Variant (1l), false);
@ -1340,6 +1342,8 @@ TEST(11)
// compare with type
EXPECT_EQ (tl::Variant (1l).equal (tl::Variant (1.0)), false);
EXPECT_EQ (tl::Variant (1l).equal (tl::Variant (1)), true);
EXPECT_EQ (tl::Variant (1l).equal (tl::Variant (1u)), false);
EXPECT_EQ (tl::Variant (1l).equal (tl::Variant (1.5)), false);
EXPECT_EQ (tl::Variant (1l).less (tl::Variant (1.0)), true);
EXPECT_EQ (tl::Variant (1.0).less (tl::Variant (1l)), false);

Binary file not shown.

Binary file not shown.

Binary file not shown.