Bugfix #109 (part 1): account for long != long long on Windows in tl::Variant

This commit is contained in:
Matthias Koefferlein 2018-04-06 14:53:40 +02:00
parent a7446dd0dc
commit ea3ebba470
3 changed files with 293 additions and 28 deletions

View File

@ -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<unsigned long long>::max ()) && m_var.m_int128 >= __int128 (std::numeric_limits<unsigned long long>::min ());
#endif
case t_longlong:
return m_var.m_longlong >= 0 && m_var.m_longlong < (long long) std::numeric_limits<unsigned long>::max ();
return m_var.m_longlong >= 0 && (unsigned long long) m_var.m_longlong <= (unsigned long long) std::numeric_limits<unsigned long>::max ();
case t_ulonglong:
return m_var.m_ulonglong < (unsigned long long) std::numeric_limits<unsigned long>::max ();
return m_var.m_ulonglong <= (unsigned long long) std::numeric_limits<unsigned long>::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<int>::min () && l <= (long) std::numeric_limits<int>::max ();
try {
long l;
return ex.try_read (l) && ex.at_end () && l >= (long) std::numeric_limits<int>::min () && l <= (long) std::numeric_limits<int>::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<int>::min () && l <= (long) std::numeric_limits<int>::max ();
try {
long l;
return ex.try_read (l) && ex.at_end () && l >= (long) std::numeric_limits<int>::min () && l <= (long) std::numeric_limits<int>::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;

View File

@ -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)

View File

@ -113,7 +113,9 @@ TEST(1)
EXPECT_EQ (v.is<long> (), 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<unsigned long> (), true);
EXPECT_EQ (v.is<long> (), false);
EXPECT_EQ (vv == v, false);
@ -167,11 +172,14 @@ TEST(1)
EXPECT_EQ (v.is<unsigned long> (), false);
EXPECT_EQ (v.is<long> (), 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<long> (), false);
EXPECT_EQ (v.is<unsigned long> (), false);
EXPECT_EQ (v.is<int> (), 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<signed char> (), 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<long> (), 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<long> (), false);
EXPECT_EQ (v.is<unsigned long> (), 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<tl::Variant, int> 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);
}
}