This commit is contained in:
Matthias Koefferlein 2018-04-07 16:02:39 -07:00
commit d3227b5bda
9 changed files with 496 additions and 200 deletions

View File

@ -860,8 +860,10 @@ template <class C, class R>
inline box<C, R> &
box<C, R>::move (const vector<C> &p)
{
m_p1 += p;
m_p2 += p;
if (! empty ()) {
m_p1 += p;
m_p2 += p;
}
return *this;
}
@ -869,8 +871,10 @@ template <class C, class R>
inline box<C, R> &
box<C, R>::enlarge (const vector<C> &p)
{
m_p1 -= p;
m_p2 += p;
if (! empty ()) {
m_p1 -= p;
m_p2 += p;
}
return *this;
}

View File

@ -831,15 +831,8 @@ GDS2WriterBase::write_properties (const db::Layout &layout, db::properties_id_ty
const tl::Variant &name = layout.properties_repository ().prop_name (p->first);
long attr = -1;
if (name.is_long ()) {
if (name.can_convert_to_long ()) {
attr = name.to_long ();
} else if (name.is_a_string ()) {
// string names representing a number are converted to numeric property names
tl::Extractor ex (name.to_string ());
long a = 0;
if (ex.try_read (a) && ex.at_end ()) {
attr = a;
}
}
if (attr >= 0 && attr < 65535) {

View File

@ -55,7 +55,9 @@ make_gds_property (const tl::Variant &name)
{
// We write S_GDS_PROPERTY properties, because that is the only way to write properties
// with numerical keys
return (name.is_long () && (name.to_long () < 0x8000 || name.to_long () >= 0)) ||
return (name.is_longlong () && name.to_longlong () < 0x8000 && name.to_longlong () >= 0) ||
(name.is_ulonglong () && name.to_ulonglong () < 0x8000) ||
(name.is_long () && name.to_long () < 0x8000 && name.to_long () >= 0) ||
(name.is_ulong () && name.to_ulong () < 0x8000);
}

View File

@ -41,12 +41,19 @@ TEST(2)
EXPECT_EQ (b.moved (db::Vector (10, 20)), db::Box (110, 20, 10, 220));
EXPECT_EQ (b.enlarged (db::Vector (10, 20)), db::Box (-10, -20, 110, 220));
EXPECT_EQ (empty.moved (db::Vector (10, 20)).empty (), true);
EXPECT_EQ (empty.enlarged (db::Vector (10, 20)).empty (), true);
EXPECT_EQ (b + db::Box (-10, 20, 100, 200), db::Box (-10, 0, 100, 200));
EXPECT_EQ (b + db::Box (-10, -20, 100, -10), db::Box (-10, -20, 100, 200));
EXPECT_EQ (b + db::Box (110, 220, 120, 250), db::Box (0, 0, 120, 250));
EXPECT_EQ (b & db::Box (110, 220, 120, 250), empty);
EXPECT_EQ (b & db::Box (50, 100, 120, 250), db::Box (50, 100, 100, 200));
EXPECT_EQ (b & db::Box (50, 100, 60, 120), db::Box (50, 100, 60, 120));
empty.move (db::Vector (10, 20));
EXPECT_EQ (empty == db::Box (), true);
empty.enlarge (db::Vector (10, 20));
EXPECT_EQ (empty == db::Box (), true);
}
TEST(3)

View File

@ -831,186 +831,160 @@ tl::Extractor::read_quoted (std::string &value)
return *this;
}
bool
namespace
{
template <class T> struct overflow_msg_func;
template <> struct overflow_msg_func<long long>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on long long integer"));
}
};
template <> struct overflow_msg_func<unsigned long long>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on unsigned long long integer"));
}
};
template <> struct overflow_msg_func<long>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on long integer"));
}
};
template <> struct overflow_msg_func<unsigned long>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on unsigned long integer"));
}
};
template <> struct overflow_msg_func<int>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on integer"));
}
};
template <> struct overflow_msg_func<unsigned int>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on unsigned integer"));
}
};
}
template <class T> bool
tl::Extractor::try_read_signed_int (T &value)
{
if (! *skip ()) {
return false;
}
bool minus = false;
if (*m_cp == '-') {
minus = true;
++m_cp;
} else if (*m_cp == '+') {
++m_cp;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if (value > std::numeric_limits<T>::max () / 10) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value *= 10;
if (value > std::numeric_limits<T>::max () - (*m_cp - '0')) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value += (*m_cp - '0');
++m_cp;
}
if (minus) {
value = -value;
}
return true;
}
template <class T> bool
tl::Extractor::try_read_unsigned_int (T &value)
{
if (! *skip ()) {
return false;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if (value > std::numeric_limits<T>::max () / 10) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value *= 10;
if (value > std::numeric_limits<T>::max () - (*m_cp - '0')) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value += (*m_cp - '0');
++m_cp;
}
return true;
}
bool
tl::Extractor::try_read (unsigned int &value)
{
if (! *skip ()) {
return false;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on unsigned integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
return true;
return try_read_unsigned_int (value);
}
bool
tl::Extractor::try_read (int &value)
{
if (! *skip ()) {
return false;
}
bool minus = false;
if (*m_cp == '-') {
minus = true;
++m_cp;
} else if (*m_cp == '+') {
++m_cp;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
if (minus) {
value = -value;
}
return true;
}
bool
bool
tl::Extractor::try_read (unsigned long &value)
{
if (! *skip ()) {
return false;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on unsigned long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
return true;
return try_read_unsigned_int (value);
}
bool
bool
tl::Extractor::try_read (unsigned long long &value)
{
if (! *skip ()) {
return false;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on unsigned long long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
return true;
return try_read_unsigned_int (value);
}
bool
bool
tl::Extractor::try_read (int &value)
{
return try_read_signed_int (value);
}
bool
tl::Extractor::try_read (long &value)
{
if (! *skip ()) {
return false;
}
bool minus = false;
if (*m_cp == '-') {
minus = true;
++m_cp;
} else if (*m_cp == '+') {
++m_cp;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
if (minus) {
value = -value;
}
return true;
return try_read_signed_int (value);
}
bool
bool
tl::Extractor::try_read (long long &value)
{
if (! *skip ()) {
return false;
}
bool minus = false;
if (*m_cp == '-') {
minus = true;
++m_cp;
} else if (*m_cp == '+') {
++m_cp;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on long long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
if (minus) {
value = -value;
}
return true;
return try_read_signed_int (value);
}
bool
tl::Extractor::try_read (double &value)
{

View File

@ -732,6 +732,9 @@ public:
}
private:
template <class T> bool try_read_signed_int (T &value);
template <class T> bool try_read_unsigned_int (T &value);
const char *m_cp;
std::string m_str;
};

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

@ -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 (), false);
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 (), false);
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 (), false);
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 (), false);
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);
}
}

View File

@ -19,6 +19,7 @@
import pya
import unittest
import sys
import os
class DBLayoutTest(unittest.TestCase):
@ -1104,6 +1105,53 @@ class DBLayoutTest(unittest.TestCase):
ly._destroy()
# Bug #109
def test_bug109(self):
testtmp = os.getenv("TESTTMP_WITH_NAME", os.getenv("TESTTMP", "."))
file_gds = os.path.join(testtmp, "bug109.gds")
file_oas = os.path.join(testtmp, "bug109.oas")
ly = pya.Layout()
top = ly.create_cell("TOP")
l1 = ly.layer(1, 0)
shape = top.shapes(l1).insert(pya.Box(0, 10, 20, 30))
shape.set_property(2, "hello, world")
shape.set_property("42", "the answer")
ly.write(file_gds)
ly.write(file_oas)
ly2 = pya.Layout()
ly2.read(file_gds)
l2 = ly2.layer(1, 0)
shape = None
for s in ly2.top_cell().shapes(l2).each():
shape = s
self.assertEqual(shape.property(2), "hello, world")
self.assertEqual(shape.property("2"), None)
self.assertEqual(shape.property(2.0), "hello, world")
self.assertEqual(shape.property(22), None)
self.assertEqual(shape.property(42), "the answer")
self.assertEqual(shape.property("42"), None)
self.assertEqual(shape.property(42.0), "the answer")
ly2 = pya.Layout()
ly2.read(file_oas)
l2 = ly2.layer(1, 0)
shape = None
for s in ly2.top_cell().shapes(l2).each():
shape = s
self.assertEqual(shape.property(2), "hello, world")
self.assertEqual(shape.property("2"), None)
self.assertEqual(shape.property(2.0), "hello, world")
self.assertEqual(shape.property(22), None)
self.assertEqual(shape.property("42"), "the answer")
self.assertEqual(shape.property(42), None)
self.assertEqual(shape.property(42.0), None)
# run unit tests
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(DBLayoutTest)