mirror of https://github.com/KLayout/klayout.git
WIP - refined tl::Variant::equal and less implementation, fixed tests
This commit is contained in:
parent
dc73b8145f
commit
1278ffeb77
|
|
@ -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 << "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
Loading…
Reference in New Issue