From 08dbe3aba571f3f604ba35382aba484343ce7346 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 2 Feb 2025 19:41:54 +0100 Subject: [PATCH] Fixing problem with sorting order of tl::Variant as key in std::map --- src/tl/tl/tlVariant.cc | 32 ++++++++++++---- src/tl/unit_tests/tlVariantTests.cc | 58 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/src/tl/tl/tlVariant.cc b/src/tl/tl/tlVariant.cc index 82192cca0..38b5bf14b 100644 --- a/src/tl/tl/tlVariant.cc +++ b/src/tl/tl/tlVariant.cc @@ -1309,22 +1309,40 @@ Variant::less_core (const tl::Variant &d, type t) const bool Variant::operator== (const tl::Variant &d) const { - std::pair tt = normalized_type (m_type, d.m_type); - if (! tt.first) { + type type1 = normalized_type (m_type); + type type2 = normalized_type (d.m_type); + + if (is_integer_type (type1)) { + type1 = Variant::t_double; + } + if (is_integer_type (type2)) { + type2 = Variant::t_double; + } + + if (type1 != type2) { return false; } else { - return equal_core (d, tt.second); + return equal_core (d, type1); } } 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); + type type1 = normalized_type (m_type); + type type2 = normalized_type (d.m_type); + + if (is_integer_type (type1)) { + type1 = Variant::t_double; + } + if (is_integer_type (type2)) { + type2 = Variant::t_double; + } + + if (type1 != type2) { + return type1 < type2; } else { - return less_core (d, tt.second); + return less_core (d, type1); } } diff --git a/src/tl/unit_tests/tlVariantTests.cc b/src/tl/unit_tests/tlVariantTests.cc index 2f01572fc..fbe9695d5 100644 --- a/src/tl/unit_tests/tlVariantTests.cc +++ b/src/tl/unit_tests/tlVariantTests.cc @@ -1377,4 +1377,62 @@ TEST(12) EXPECT_EQ (std::string (v.to_parsable_string ()), "('Aber_',##2.5,(#5,'x'),())"); } +// tl::Variant sorting with different numericals +TEST(13) +{ + tl::Variant v1 ((long) 2); + tl::Variant v2 ((int) 2); + tl::Variant v3 ((unsigned int) 2); + tl::Variant v4 (2.0); + tl::Variant v5 ("2"); + tl::Variant v6 (2, true); // ID + + EXPECT_EQ (v1 == v2, true); + EXPECT_EQ (v2 == v1, true); + EXPECT_EQ (v1 < v2, false); + EXPECT_EQ (v2 < v1, false); + + EXPECT_EQ (v1 == v3, true); // signed compares to unsigned + EXPECT_EQ (v3 == v1, true); + EXPECT_EQ (v3 < v1, false); + EXPECT_EQ (v1 < v3, false); + + EXPECT_EQ (v1 == v4, true); + EXPECT_EQ (v2 == v1, true); + EXPECT_EQ (v1 < v2, false); + EXPECT_EQ (v2 < v1, false); + + EXPECT_EQ (v1 == v5, false); // string != value + EXPECT_EQ (v5 == v1, false); + EXPECT_EQ (v1 < v5, true); + EXPECT_EQ (v5 < v1, false); + + // IDs are treated differently + EXPECT_EQ (v1 == v6, false); + EXPECT_EQ (v6 == v1, false); + EXPECT_EQ (v1 < v6, false); + EXPECT_EQ (v6 < v1, true); + + // Use of tl::Variant as map keys + std::map vm; + + vm.insert (std::make_pair (tl::Variant (2), 1)); + EXPECT_EQ (vm[tl::Variant (2)], 1); + + vm.insert (std::make_pair (tl::Variant (2.0), 2)); + EXPECT_EQ (vm[tl::Variant (2)], 1); + EXPECT_EQ (vm[tl::Variant (2.0)], 1); + + vm.insert (std::make_pair (tl::Variant (2, true), 3)); + EXPECT_EQ (vm[tl::Variant (2)], 1); + EXPECT_EQ (vm[tl::Variant (2.0)], 1); + EXPECT_EQ (vm[tl::Variant (2, true)], 3); + + vm.insert (std::make_pair (tl::Variant ("2"), 4)); + EXPECT_EQ (vm[tl::Variant (2)], 1); + EXPECT_EQ (vm[tl::Variant (2.0)], 1); + EXPECT_EQ (vm[tl::Variant (2, true)], 3); + EXPECT_EQ (vm[tl::Variant ("2")], 4); +} + }