diff --git a/src/db/db/dbLayoutDiff.cc b/src/db/db/dbLayoutDiff.cc index 1c80b6c65..2a12946c3 100644 --- a/src/db/db/dbLayoutDiff.cc +++ b/src/db/db/dbLayoutDiff.cc @@ -1395,22 +1395,8 @@ PrintingDifferenceReceiver::print_diffs (const std::vector >::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 << ""; } diff --git a/src/db/db/dbLayoutDiff.h b/src/db/db/dbLayoutDiff.h index 7c359972b..1913c4e50 100644 --- a/src/db/db/dbLayoutDiff.h +++ b/src/db/db/dbLayoutDiff.h @@ -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 diff --git a/src/db/unit_tests/dbAsIfFlatRegionTests.cc b/src/db/unit_tests/dbAsIfFlatRegionTests.cc index 0bc433434..41d2307c1 100644 --- a/src/db/unit_tests/dbAsIfFlatRegionTests.cc +++ b/src/db/unit_tests/dbAsIfFlatRegionTests.cc @@ -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)); diff --git a/src/tl/tl/tlVariant.cc b/src/tl/tl/tlVariant.cc index 07d4842a1..01205547a 100644 --- a/src/tl/tl/tlVariant.cc +++ b/src/tl/tl/tlVariant.cc @@ -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::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 +inline std::pair 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 +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 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 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 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 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 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 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::min () && (sizeof (long) == sizeof (unsigned int) || m_var.m_long <= (long) std::numeric_limits::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: diff --git a/src/tl/tl/tlVariant.h b/src/tl/tl/tlVariant.h index 9fd938dff..f4787cde8 100644 --- a/src/tl/tl/tlVariant.h +++ b/src/tl/tl/tlVariant.h @@ -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 diff --git a/src/tl/unit_tests/tlVariantTests.cc b/src/tl/unit_tests/tlVariantTests.cc index 9307ea7f5..62d2423d8 100644 --- a/src/tl/unit_tests/tlVariantTests.cc +++ b/src/tl/unit_tests/tlVariantTests.cc @@ -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::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); diff --git a/testdata/algo/net_proc_au1.gds b/testdata/algo/net_proc_au1.gds index 79ac941b5..be6e15498 100644 Binary files a/testdata/algo/net_proc_au1.gds and b/testdata/algo/net_proc_au1.gds differ diff --git a/testdata/algo/net_proc_au2.gds b/testdata/algo/net_proc_au2.gds index 694462a29..fd53350d7 100644 Binary files a/testdata/algo/net_proc_au2.gds and b/testdata/algo/net_proc_au2.gds differ diff --git a/testdata/algo/net_proc_au3.gds b/testdata/algo/net_proc_au3.gds index 17920b65b..b84c44b2c 100644 Binary files a/testdata/algo/net_proc_au3.gds and b/testdata/algo/net_proc_au3.gds differ