diff --git a/src/tl/tl/tlVariant.cc b/src/tl/tl/tlVariant.cc index d223ab537..322e17820 100644 --- a/src/tl/tl/tlVariant.cc +++ b/src/tl/tl/tlVariant.cc @@ -894,18 +894,18 @@ normalized_type (Variant::type type) case Variant::t_short: case Variant::t_int: case Variant::t_long: - return Variant::t_long; + case Variant::t_longlong: + return Variant::t_longlong; case Variant::t_uchar: case Variant::t_ushort: case Variant::t_uint: case Variant::t_ulong: - return Variant::t_ulong; + case Variant::t_ulonglong: + return Variant::t_ulonglong; case Variant::t_stdstring: case Variant::t_string: return Variant::t_string; default: - case Variant::t_longlong: - case Variant::t_ulonglong: #if defined(HAVE_64BIT_COORD) case Variant::t_int128: #endif @@ -1195,8 +1195,12 @@ Variant::can_convert_to_ulonglong () const case t_stdstring: { tl::Extractor ex (to_string ()); - unsigned long long ll; - return ex.try_read (ll) && ex.at_end (); + try { + unsigned long long ll; + return ex.try_read (ll) && ex.at_end (); + } catch (...) { + return false; + } } default: return false; @@ -1236,8 +1240,12 @@ Variant::can_convert_to_longlong () const case t_stdstring: { tl::Extractor ex (to_string ()); - long long ll; - return ex.try_read (ll) && ex.at_end (); + try { + long long ll; + return ex.try_read (ll) && ex.at_end (); + } catch (...) { + return false; + } } default: return false; @@ -1257,9 +1265,9 @@ Variant::can_convert_to_ulong () const return m_var.m_int128 <= __int128 (std::numeric_limits::max ()) && m_var.m_int128 >= __int128 (std::numeric_limits::min ()); #endif case t_longlong: - return m_var.m_longlong >= 0 && m_var.m_longlong < (long long) std::numeric_limits::max (); + return m_var.m_longlong >= 0 && (unsigned long long) m_var.m_longlong <= (unsigned long long) std::numeric_limits::max (); case t_ulonglong: - return m_var.m_ulonglong < (unsigned long long) std::numeric_limits::max (); + return m_var.m_ulonglong <= (unsigned long long) std::numeric_limits::max (); case t_ulong: case t_bool: case t_uchar: @@ -1283,8 +1291,12 @@ Variant::can_convert_to_ulong () const case t_stdstring: { tl::Extractor ex (to_string ()); - unsigned long l; - return ex.try_read (l) && ex.at_end (); + try { + unsigned long l; + return ex.try_read (l) && ex.at_end (); + } catch (...) { + return false; + } } default: return false; @@ -1326,8 +1338,12 @@ Variant::can_convert_to_long () const case t_stdstring: { tl::Extractor ex (to_string ()); - long l; - return ex.try_read (l) && ex.at_end (); + try { + long l; + return ex.try_read (l) && ex.at_end (); + } catch (...) { + return false; + } } default: return false; @@ -1371,8 +1387,12 @@ Variant::can_convert_to_int () const case t_stdstring: { tl::Extractor ex (to_string ()); - long l; - return ex.try_read (l) && ex.at_end () && l >= (long) std::numeric_limits::min () && l <= (long) std::numeric_limits::max (); + try { + long l; + return ex.try_read (l) && ex.at_end () && l >= (long) std::numeric_limits::min () && l <= (long) std::numeric_limits::max (); + } catch (...) { + return false; + } } default: return false; @@ -1416,8 +1436,12 @@ Variant::can_convert_to_uint () const case t_stdstring: { tl::Extractor ex (to_string ()); - long l; - return ex.try_read (l) && ex.at_end () && l >= (long) std::numeric_limits::min () && l <= (long) std::numeric_limits::max (); + try { + long l; + return ex.try_read (l) && ex.at_end () && l >= (long) std::numeric_limits::min () && l <= (long) std::numeric_limits::max (); + } catch (...) { + return false; + } } default: return false; @@ -1684,7 +1708,7 @@ Variant::to_ulonglong () const return m_var.m_long; #if defined(HAVE_64BIT_COORD) } else if (m_type == t_int128) { - return m_var.m_int128; + return (unsigned long long) m_var.m_int128; #endif } else if (m_type == t_ulonglong) { return m_var.m_ulonglong; @@ -1738,7 +1762,7 @@ Variant::to_longlong () const return m_var.m_longlong; #if defined(HAVE_64BIT_COORD) } else if (m_type == t_int128) { - return m_var.m_int128; + return (long long) m_var.m_int128; #endif } else if (m_type == t_bool) { return m_var.m_bool; @@ -1783,12 +1807,12 @@ Variant::to_ulong () const } else if (m_type == t_long) { return m_var.m_long; } else if (m_type == t_ulonglong) { - return m_var.m_ulonglong; + return (unsigned long) (m_var.m_ulonglong); } else if (m_type == t_longlong) { - return m_var.m_longlong; + return (unsigned long) (m_var.m_longlong); #if defined(HAVE_64BIT_COORD) } else if (m_type == t_int128) { - return m_var.m_int128; + return (unsigned long) (m_var.m_int128); #endif } else if (m_type == t_bool) { return m_var.m_bool; @@ -1833,12 +1857,12 @@ Variant::to_long () const } else if (m_type == t_long) { return m_var.m_long; } else if (m_type == t_ulonglong) { - return m_var.m_ulonglong; + return long (m_var.m_ulonglong); } else if (m_type == t_longlong) { - return m_var.m_longlong; + return long (m_var.m_longlong); #if defined(HAVE_64BIT_COORD) } else if (m_type == t_int128) { - return m_var.m_int128; + return long (m_var.m_int128); #endif } else if (m_type == t_bool) { return m_var.m_bool; diff --git a/src/tl/tl/tlVariant.h b/src/tl/tl/tlVariant.h index df9fda803..967c753de 100644 --- a/src/tl/tl/tlVariant.h +++ b/src/tl/tl/tlVariant.h @@ -1268,7 +1268,7 @@ public: */ bool is_longlong () const { - return m_type == t_longlong; + return m_type == t_longlong || is_long (); } /** @@ -1276,7 +1276,7 @@ public: */ bool is_ulonglong () const { - return m_type == t_ulonglong; + return m_type == t_ulonglong || is_ulong (); } #if defined(HAVE_64BIT_COORD) diff --git a/src/tl/unit_tests/tlVariant.cc b/src/tl/unit_tests/tlVariant.cc index 6fa511411..d3a25748c 100644 --- a/src/tl/unit_tests/tlVariant.cc +++ b/src/tl/unit_tests/tlVariant.cc @@ -113,7 +113,9 @@ TEST(1) EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is_char (), false); EXPECT_EQ (v.is_long (), false); + EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.to_parsable_string (), "nil"); vv = v; @@ -135,10 +137,13 @@ TEST(1) EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is_id (), false); EXPECT_EQ (v.is_ulong (), true); + EXPECT_EQ (v.is_ulonglong (), true); EXPECT_EQ (v.is_long (), false); + EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.to_parsable_string (), "#u1"); EXPECT_EQ (v.to_long (), 1l); + EXPECT_EQ (v.to_longlong (), 1l); EXPECT_EQ (v.is (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (vv == v, false); @@ -167,11 +172,14 @@ TEST(1) EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is_ulong (), true); + EXPECT_EQ (v.is_ulonglong (), true); EXPECT_EQ (v.is_long (), false); + EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_id (), false); EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.to_parsable_string (), "#u2"); EXPECT_EQ (v.to_long (), 2l); + EXPECT_EQ (v.to_longlong (), 2l); EXPECT_EQ (vv == v, false); EXPECT_EQ (vv != v, true); vv = v; @@ -194,7 +202,9 @@ TEST(1) EXPECT_EQ (v.is_list (), false); EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is_long (), true); + EXPECT_EQ (v.is_longlong (), true); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), true); @@ -202,6 +212,7 @@ TEST(1) EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.to_parsable_string (), "#1"); EXPECT_EQ (v.to_long (), 1l); + EXPECT_EQ (v.to_longlong (), 1l); EXPECT_EQ (vv == v, false); EXPECT_EQ (vv != v, true); vv = v; @@ -239,6 +250,7 @@ TEST(1) EXPECT_EQ (v.is (), false); EXPECT_EQ (v.to_parsable_string (), "#2"); EXPECT_EQ (v.to_long (), 2l); + EXPECT_EQ (v.to_longlong (), 2l); EXPECT_EQ (v.to_double (), 2.0); EXPECT_EQ (v.to_float (), 2.0); EXPECT_EQ (vv == v, false); @@ -261,7 +273,9 @@ TEST(1) EXPECT_EQ (v.is_list (), false); EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is_long (), false); + EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_char (), false); EXPECT_EQ (v.is_double (), true); EXPECT_EQ (v.is (), false); @@ -278,6 +292,10 @@ TEST(1) EXPECT_EQ (v.to_parsable_string (), "##5"); EXPECT_EQ (v.to_double (), 5.0); EXPECT_EQ (v.to_float (), 5.0); + EXPECT_EQ (v.to_long (), 5); + EXPECT_EQ (v.to_ulong (), 5u); + EXPECT_EQ (v.to_longlong (), 5); + EXPECT_EQ (v.to_ulonglong (), 5u); EXPECT_EQ (vv == v, false); EXPECT_EQ (vv != v, true); vv = v; @@ -300,7 +318,9 @@ TEST(1) EXPECT_EQ (v.is_list (), false); EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is_long (), false); + EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_double (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); @@ -317,6 +337,10 @@ TEST(1) EXPECT_EQ (v.is_id (), false); EXPECT_EQ (v.to_parsable_string (), "##5"); EXPECT_EQ (v.to_double (), 5.0); + EXPECT_EQ (v.to_long (), 5); + EXPECT_EQ (v.to_longlong (), 5); + EXPECT_EQ (v.to_ulong (), 5u); + EXPECT_EQ (v.to_ulonglong (), 5u); EXPECT_EQ (*(double *)v.native_ptr (), 5.0); EXPECT_EQ (vv == v, true); EXPECT_EQ (vv != v, false); @@ -365,6 +389,8 @@ TEST(1) EXPECT_EQ (v.is_char (), false); EXPECT_EQ (v.is_long (), true); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_longlong (), true); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.to_parsable_string (), "#2"); vv = v; @@ -440,6 +466,8 @@ TEST(1) EXPECT_EQ (v.is_cstring (), true); EXPECT_EQ (v.is_long (), false); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_longlong (), false); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.is_id (), false); EXPECT_EQ (v.to_parsable_string (), "'hal\\'l\"o'"); @@ -470,6 +498,8 @@ TEST(1) EXPECT_EQ (v.is_stdstring (), false); EXPECT_EQ (v.is_long (), false); EXPECT_EQ (v.is_ulong (), false); + EXPECT_EQ (v.is_longlong (), false); + EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.is_id (), false); EXPECT_EQ (std::string (v.to_string ()), "hal'l\"o"); @@ -810,6 +840,217 @@ TEST(3) EXPECT_EQ (v2 < v2, false); } +// can_convert_to +TEST(4) +{ + tl::Variant v; + v = tl::Variant (1); + EXPECT_EQ (v.can_convert_to_char (), true); + EXPECT_EQ (v.can_convert_to_uchar (), true); + EXPECT_EQ (v.can_convert_to_double (), true); + EXPECT_EQ (v.can_convert_to_float (), true); + EXPECT_EQ (v.can_convert_to_short (), true); + EXPECT_EQ (v.can_convert_to_ushort (), true); + EXPECT_EQ (v.can_convert_to_int (), true); + EXPECT_EQ (v.can_convert_to_uint (), true); + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), true); + EXPECT_EQ (v.can_convert_to_longlong (), true); + 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_uchar (), false); + EXPECT_EQ (v.can_convert_to_double (), true); + EXPECT_EQ (v.can_convert_to_float (), true); + EXPECT_EQ (v.can_convert_to_short (), true); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), true); + EXPECT_EQ (v.can_convert_to_uint (), false); + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), false); + EXPECT_EQ (v.can_convert_to_longlong (), true); + EXPECT_EQ (v.can_convert_to_ulonglong (), false); + + v = tl::Variant (1000); + EXPECT_EQ (v.can_convert_to_char (), 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); + EXPECT_EQ (v.can_convert_to_short (), true); + EXPECT_EQ (v.can_convert_to_ushort (), true); + EXPECT_EQ (v.can_convert_to_int (), true); + EXPECT_EQ (v.can_convert_to_uint (), true); + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), true); + EXPECT_EQ (v.can_convert_to_longlong (), true); + EXPECT_EQ (v.can_convert_to_ulonglong (), true); + + v = tl::Variant ("1000"); + EXPECT_EQ (v.can_convert_to_char (), 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); + EXPECT_EQ (v.can_convert_to_short (), true); + EXPECT_EQ (v.can_convert_to_ushort (), true); + EXPECT_EQ (v.can_convert_to_int (), true); + EXPECT_EQ (v.can_convert_to_uint (), true); + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), true); + EXPECT_EQ (v.can_convert_to_longlong (), true); + EXPECT_EQ (v.can_convert_to_ulonglong (), true); + + v = tl::Variant (100000); + EXPECT_EQ (v.can_convert_to_char (), 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); + EXPECT_EQ (v.can_convert_to_short (), false); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), true); + EXPECT_EQ (v.can_convert_to_uint (), true); + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), true); + EXPECT_EQ (v.can_convert_to_longlong (), true); + EXPECT_EQ (v.can_convert_to_ulonglong (), true); + + v = tl::Variant (10000000000ll); + EXPECT_EQ (v.can_convert_to_char (), 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); + EXPECT_EQ (v.can_convert_to_short (), false); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), false); + EXPECT_EQ (v.can_convert_to_uint (), false); + if (sizeof (long) == 4) { + EXPECT_EQ (v.can_convert_to_long (), false); + EXPECT_EQ (v.can_convert_to_ulong (), false); + } else { + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), true); + } + EXPECT_EQ (v.can_convert_to_longlong (), true); + EXPECT_EQ (v.can_convert_to_ulonglong (), true); + + v = tl::Variant (0.5); + EXPECT_EQ (v.can_convert_to_char (), true); + EXPECT_EQ (v.can_convert_to_uchar (), true); + EXPECT_EQ (v.can_convert_to_double (), true); + EXPECT_EQ (v.can_convert_to_float (), true); + EXPECT_EQ (v.can_convert_to_short (), true); + EXPECT_EQ (v.can_convert_to_ushort (), true); + EXPECT_EQ (v.can_convert_to_int (), true); + EXPECT_EQ (v.can_convert_to_uint (), true); + EXPECT_EQ (v.can_convert_to_long (), true); + EXPECT_EQ (v.can_convert_to_ulong (), true); + EXPECT_EQ (v.can_convert_to_longlong (), true); + EXPECT_EQ (v.can_convert_to_ulonglong (), true); + + v = tl::Variant ("100000000000000000000"); + EXPECT_EQ (v.can_convert_to_char (), 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); + EXPECT_EQ (v.can_convert_to_short (), false); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), false); + EXPECT_EQ (v.can_convert_to_uint (), false); + EXPECT_EQ (v.can_convert_to_long (), false); + EXPECT_EQ (v.can_convert_to_ulong (), false); + EXPECT_EQ (v.can_convert_to_longlong (), false); + EXPECT_EQ (v.can_convert_to_ulonglong (), false); + + v = tl::Variant ("1000x"); + EXPECT_EQ (v.can_convert_to_char (), false); + EXPECT_EQ (v.can_convert_to_uchar (), false); + EXPECT_EQ (v.can_convert_to_double (), false); + EXPECT_EQ (v.can_convert_to_float (), false); + EXPECT_EQ (v.can_convert_to_short (), false); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), false); + EXPECT_EQ (v.can_convert_to_uint (), false); + EXPECT_EQ (v.can_convert_to_long (), false); + EXPECT_EQ (v.can_convert_to_ulong (), false); + EXPECT_EQ (v.can_convert_to_longlong (), false); + EXPECT_EQ (v.can_convert_to_ulonglong (), false); + + v = tl::Variant (""); + EXPECT_EQ (v.can_convert_to_char (), false); + EXPECT_EQ (v.can_convert_to_uchar (), false); + EXPECT_EQ (v.can_convert_to_double (), false); + EXPECT_EQ (v.can_convert_to_float (), false); + EXPECT_EQ (v.can_convert_to_short (), false); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), false); + EXPECT_EQ (v.can_convert_to_uint (), false); + EXPECT_EQ (v.can_convert_to_long (), false); + EXPECT_EQ (v.can_convert_to_ulong (), false); + EXPECT_EQ (v.can_convert_to_longlong (), false); + EXPECT_EQ (v.can_convert_to_ulonglong (), false); + + v = tl::Variant ("x"); + EXPECT_EQ (v.can_convert_to_char (), false); + EXPECT_EQ (v.can_convert_to_uchar (), false); + EXPECT_EQ (v.can_convert_to_double (), false); + EXPECT_EQ (v.can_convert_to_float (), false); + EXPECT_EQ (v.can_convert_to_short (), false); + EXPECT_EQ (v.can_convert_to_ushort (), false); + EXPECT_EQ (v.can_convert_to_int (), false); + EXPECT_EQ (v.can_convert_to_uint (), false); + EXPECT_EQ (v.can_convert_to_long (), false); + EXPECT_EQ (v.can_convert_to_ulong (), false); + EXPECT_EQ (v.can_convert_to_longlong (), false); + EXPECT_EQ (v.can_convert_to_ulonglong (), false); +} + +// Variants as key maps +TEST(5) +{ + std::map m; + + // there are four categories which are separated: + // int + // unsigned int + // float (downwards compatible with int and unsigned int) + // string + m.insert (std::make_pair (tl::Variant (1), 17)); + m.insert (std::make_pair (tl::Variant ((unsigned int) 2), 42)); + m.insert (std::make_pair (tl::Variant ("3"), 41)); + m.insert (std::make_pair (tl::Variant (2.5), -17)); + + // int category + EXPECT_EQ (m [1], 17); + EXPECT_EQ (m [(char) 1], 17); + EXPECT_EQ (m [(short) 1], 17); + EXPECT_EQ (m [(int) 1], 17); + EXPECT_EQ (m [(long long) 1], 17); + EXPECT_EQ (m [1.0], 17); + // non-members of that category + EXPECT_EQ (m [1.25], 0); + EXPECT_EQ (m [(unsigned int) 1], 0); + EXPECT_EQ (m ["1"], 0); + + // unsigned int category + EXPECT_EQ (m [(unsigned char) 2], 42); + EXPECT_EQ (m [(unsigned short) 2], 42); + EXPECT_EQ (m [(unsigned int) 2], 42); + EXPECT_EQ (m [(unsigned long long) 2], 42); + EXPECT_EQ (m [2.0], 42); + // non-members of that category + EXPECT_EQ (m [2.25], 0); + EXPECT_EQ (m [2], 0); + EXPECT_EQ (m ["2"], 0); + + // float category + EXPECT_EQ (m [2.5], -17); + EXPECT_EQ (m [2.5001], 0); + + // string category + EXPECT_EQ (m ["3"], 41); + EXPECT_EQ (m [" 3"], 0); +} + }