mirror of https://github.com/KLayout/klayout.git
817 lines
24 KiB
C++
817 lines
24 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2017 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "tlVariant.h"
|
|
#include "tlVariantUserClasses.h"
|
|
#include "tlObject.h"
|
|
#include "tlTypeTraits.h"
|
|
#include "tlUnitTest.h"
|
|
#include <cstdio>
|
|
#include <memory>
|
|
|
|
struct A
|
|
{
|
|
std::string a;
|
|
const std::string &to_string () const { return a; }
|
|
};
|
|
|
|
struct AA
|
|
: public tl::Object
|
|
{
|
|
std::string a;
|
|
static int ac;
|
|
AA() { ac += 1; }
|
|
~AA() { ac -= 1; }
|
|
const std::string &to_string () const { return a; }
|
|
};
|
|
|
|
int AA::ac = 0;
|
|
|
|
namespace tl
|
|
{
|
|
template<>
|
|
class type_traits<A>
|
|
: public type_traits<void>
|
|
{
|
|
public:
|
|
typedef tl::true_tag supports_to_string;
|
|
typedef tl::true_tag has_copy_constructor;
|
|
};
|
|
}
|
|
|
|
struct B
|
|
{
|
|
int bb;
|
|
std::string b;
|
|
bool operator== (const B &d) const { return bb == d.bb; }
|
|
bool operator< (const B &d) const { return bb < d.bb; }
|
|
const std::string &to_string () const { return b; }
|
|
};
|
|
|
|
namespace tl
|
|
{
|
|
template<>
|
|
class type_traits<B>
|
|
: public type_traits<void>
|
|
{
|
|
public:
|
|
typedef tl::true_tag supports_to_string;
|
|
typedef tl::true_tag has_equal_operator;
|
|
typedef tl::true_tag has_less_operator;
|
|
typedef tl::true_tag has_copy_constructor;
|
|
};
|
|
}
|
|
|
|
static tl::VariantUserClassImpl<A> a_class_instance;
|
|
static tl::VariantUserClassImpl<AA> aa_class_instance;
|
|
static tl::VariantUserClassImpl<B> b_class_instance;
|
|
|
|
// This namespace separates the test structs from other objects
|
|
namespace
|
|
{
|
|
|
|
TEST(1)
|
|
{
|
|
tl::Variant vv;
|
|
|
|
{
|
|
tl::Variant v;
|
|
EXPECT_EQ (tl::to_string (v.to_qvariant ().toString ()), "");
|
|
EXPECT_EQ (v.is_nil (), true);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is<unsigned char> (), false);
|
|
EXPECT_EQ (v.is<signed char> (), false);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is_char (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "nil");
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (1ul);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u1");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is_ulong (), true);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#u1");
|
|
EXPECT_EQ (v.to_long (), 1l);
|
|
EXPECT_EQ (v.is<unsigned long> (), true);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (2u);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u2");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), true);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is_ulong (), true);
|
|
EXPECT_EQ (v.is_long (), 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 (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
v.morph<unsigned long> ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (1);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#1");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_long (), true);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<int> (), true);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#1");
|
|
EXPECT_EQ (v.to_long (), 1l);
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
v.morph<long> ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (2l);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#2");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_long (), true);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.is_char (), false);
|
|
EXPECT_EQ (v.is<long> (), true);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<float> (), false);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is<unsigned char> (), false);
|
|
EXPECT_EQ (v.is<signed char> (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#2");
|
|
EXPECT_EQ (v.to_long (), 2l);
|
|
EXPECT_EQ (v.to_double (), 2.0);
|
|
EXPECT_EQ (v.to_float (), 2.0);
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v ((float)5.0);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "##5");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_char (), false);
|
|
EXPECT_EQ (v.is_double (), true);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<double> (), false);
|
|
EXPECT_EQ (v.is<float> (), true);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is<unsigned char> (), false);
|
|
EXPECT_EQ (v.is<signed char> (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "##5");
|
|
EXPECT_EQ (v.to_double (), 5.0);
|
|
EXPECT_EQ (v.to_float (), 5.0);
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
v.morph<double>();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (5.0);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "##5");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_double (), true);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<float> (), false);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is_char (), false);
|
|
EXPECT_EQ (v.is<unsigned char> (), false);
|
|
EXPECT_EQ (v.is<signed char> (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "##5");
|
|
EXPECT_EQ (v.to_double (), 5.0);
|
|
EXPECT_EQ (*(double *)v.native_ptr (), 5.0);
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
v.morph<float> ();
|
|
EXPECT_EQ (*(float *)v.native_ptr (), 5.0);
|
|
v.morph<int> ();
|
|
EXPECT_EQ (*(int *)v.native_ptr (), 5);
|
|
v.morph<long> ();
|
|
EXPECT_EQ (*(long *)v.native_ptr (), 5);
|
|
v.morph<long long> ();
|
|
EXPECT_EQ (*(long long *)v.native_ptr (), 5);
|
|
v.morph<unsigned long> ();
|
|
EXPECT_EQ (*(unsigned long *)v.native_ptr (), (unsigned long) 5);
|
|
v.morph<unsigned int> ();
|
|
EXPECT_EQ (*(unsigned int *)v.native_ptr (), (unsigned int) 5);
|
|
v.morph<unsigned short> ();
|
|
EXPECT_EQ (*(unsigned short *)v.native_ptr (), 5);
|
|
v.morph<unsigned char> ();
|
|
EXPECT_EQ (*(unsigned char *)v.native_ptr (), 5);
|
|
}
|
|
|
|
{
|
|
tl::Variant v((short)2);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#2");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is<short> (), true);
|
|
EXPECT_EQ (v.is<unsigned short> (), false);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is<unsigned char> (), false);
|
|
EXPECT_EQ (v.is<signed char> (), false);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is_char (), false);
|
|
EXPECT_EQ (v.is_long (), true);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#2");
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
EXPECT_EQ (vx.is_long (), true);
|
|
EXPECT_EQ (vx.is_ulong (), false);
|
|
EXPECT_EQ (vx.is<long> (), true);
|
|
EXPECT_EQ (vx.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.is<short> (), true);
|
|
EXPECT_EQ (*(long *)vx.native_ptr(), 2);
|
|
EXPECT_EQ (*(short *)v.native_ptr(), 2);
|
|
v.morph<long>();
|
|
EXPECT_EQ (vx == v, true);
|
|
EXPECT_EQ (vx.is_long (), true);
|
|
EXPECT_EQ (v.is_long (), true);
|
|
EXPECT_EQ (*(long *)vx.native_ptr(), 2);
|
|
EXPECT_EQ (*(long *)v.native_ptr(), 2);
|
|
}
|
|
|
|
{
|
|
tl::Variant v((unsigned short)2);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u2");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is_char (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), true);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.is<short> (), false);
|
|
EXPECT_EQ (v.is<unsigned short> (), true);
|
|
EXPECT_EQ (v.is<int> (), false);
|
|
EXPECT_EQ (v.is<unsigned int> (), false);
|
|
EXPECT_EQ (v.is<unsigned char> (), false);
|
|
EXPECT_EQ (v.is<signed char> (), false);
|
|
EXPECT_EQ (v.is<long> (), false);
|
|
EXPECT_EQ (v.is<unsigned long> (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#u2");
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
EXPECT_EQ (vx.is_ulong (), true);
|
|
EXPECT_EQ (v.is<unsigned short> (), true);
|
|
EXPECT_EQ (*(unsigned long *)vx.native_ptr(), (unsigned long) 2);
|
|
EXPECT_EQ (*(unsigned short *)v.native_ptr(), 2);
|
|
v.morph<unsigned long>();
|
|
EXPECT_EQ (vx == v, true);
|
|
EXPECT_EQ (vx.is_ulong (), true);
|
|
EXPECT_EQ (v.is_ulong (), true);
|
|
EXPECT_EQ (*(long *)vx.native_ptr(), 2);
|
|
EXPECT_EQ (*(long *)v.native_ptr(), 2);
|
|
}
|
|
|
|
{
|
|
tl::Variant v ("hal'l\"o");
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "'hal\\'l\"o'");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), true);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "'hal\\'l\"o'");
|
|
EXPECT_EQ (std::string (v.to_string ()), "hal'l\"o");
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx.is_stdstring (), true);
|
|
EXPECT_EQ (vx == v, true);
|
|
vx.morph<const char *>();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (tl::to_qstring ("hal'l\"o"));
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "'hal\\'l\"o'");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_qstring (), true);
|
|
EXPECT_EQ (v.is_stdstring (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (std::string (v.to_string ()), "hal'l\"o");
|
|
EXPECT_EQ (tl::to_string (*(QString *)v.native_ptr ()), "hal'l\"o");
|
|
v.morph<std::string> ();
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_qstring (), false);
|
|
EXPECT_EQ (v.is_stdstring (), true);
|
|
EXPECT_EQ (std::string (v.to_string ()), "hal'l\"o");
|
|
EXPECT_EQ (*(std::string *)v.native_ptr (), "hal'l\"o");
|
|
v.morph<const char *> ();
|
|
EXPECT_EQ (v.is_cstring (), true);
|
|
EXPECT_EQ (v.is_qstring (), false);
|
|
EXPECT_EQ (v.is_stdstring (), false);
|
|
EXPECT_EQ (std::string (v.to_string ()), "hal'l\"o");
|
|
EXPECT_EQ (std::string ((const char *)v.native_ptr ()), "hal'l\"o");
|
|
}
|
|
|
|
{
|
|
long a[3] = { 1, 5, 25 };
|
|
tl::Variant v (a, a + 3);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "(#1,#5,#25)");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), true);
|
|
EXPECT_EQ (v.is_cstring (), 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_id (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "(#1,#5,#25)");
|
|
EXPECT_EQ (v.get_list ().size (), size_t (3));
|
|
EXPECT_EQ (v.begin ()->is_long (), true);
|
|
EXPECT_EQ (v.begin ()->to_long (), 1);
|
|
EXPECT_EQ (v.begin ()[1].is_long (), true);
|
|
EXPECT_EQ (v.begin ()[1].to_long (), 5);
|
|
EXPECT_EQ (v.begin ()[2].is_long (), true);
|
|
EXPECT_EQ (v.begin ()[2].to_long (), 25);
|
|
EXPECT_EQ (v.begin () + 3 == v.end (), true);
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v ((long long) 17);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#l17");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_longlong (), true);
|
|
EXPECT_EQ (v.is_ulonglong (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#l17");
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v ((unsigned long long) 17);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#lu17");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_ulonglong (), true);
|
|
EXPECT_EQ (v.is_longlong (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "#lu17");
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
{
|
|
tl::Variant v (17, true);
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u17");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), true);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_ulonglong (), false);
|
|
EXPECT_EQ (v.is_longlong (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "[id17]");
|
|
}
|
|
|
|
{
|
|
tl::Variant v = tl::Variant::empty_array ();
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "{}");
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_array (), true);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_id (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_ulonglong (), false);
|
|
EXPECT_EQ (v.is_longlong (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.to_parsable_string (), "{}");
|
|
v.insert (tl::Variant (1), tl::Variant ("A"));
|
|
EXPECT_EQ (v.to_parsable_string (), "{#1=>\'A\'}");
|
|
v.insert (tl::Variant ("B"), tl::Variant (17));
|
|
EXPECT_EQ (v.to_parsable_string (), "{#1=>\'A\',\'B\'=>#17}");
|
|
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "{\'1\'=>\'A\',\'B\'=>#17}");
|
|
tl::Variant *x;
|
|
x = v.find (tl::Variant ("B"));
|
|
EXPECT_EQ (x != 0, true);
|
|
EXPECT_EQ (x->to_parsable_string (), "#17");
|
|
x = v.find (tl::Variant (1l));
|
|
EXPECT_EQ (x != 0, true);
|
|
EXPECT_EQ (x->to_parsable_string (), "\'A\'");
|
|
x = v.find (tl::Variant ("C"));
|
|
EXPECT_EQ (x == 0, true);
|
|
x = v.find (tl::Variant (1));
|
|
EXPECT_EQ (x != 0, true);
|
|
EXPECT_EQ (x->to_parsable_string (), "\'A\'");
|
|
x = v.find (tl::Variant ("C"));
|
|
EXPECT_EQ (x == 0, true);
|
|
x = v.find (tl::Variant ());
|
|
EXPECT_EQ (x == 0, true);
|
|
x = v.find (tl::Variant (17l));
|
|
EXPECT_EQ (x == 0, true);
|
|
tl::Variant vx;
|
|
std::string s (v.to_parsable_string ());
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (vx);
|
|
ex.expect_end ();
|
|
EXPECT_EQ (vx.to_parsable_string (), "{#1=>\'A\',\'B\'=>#17}");
|
|
EXPECT_EQ (vx == v, true);
|
|
}
|
|
|
|
}
|
|
|
|
TEST(2)
|
|
{
|
|
bool err = false;
|
|
|
|
A a;
|
|
a.a = "A member";
|
|
B b;
|
|
b.b = "B member";
|
|
b.bb = 112;
|
|
B b2;
|
|
b2.b = "B2 member";
|
|
b2.bb = 110;
|
|
|
|
tl::Variant v2;
|
|
// note: because the UT's are defined outside the main DLL, A is also defined outside
|
|
// the main DLL. To access the right instance, we need to use dll_local_instance
|
|
tl::Variant v (new A (a), &a_class_instance, true);
|
|
EXPECT_EQ (v.is_nil (), false);
|
|
EXPECT_EQ (v.is_list (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_long (), false);
|
|
EXPECT_EQ (v.is_ulong (), false);
|
|
EXPECT_EQ (v.is_cstring (), false);
|
|
EXPECT_EQ (v.is_double (), false);
|
|
EXPECT_EQ (v.is_user (), true);
|
|
EXPECT_EQ (v.is_user<A> (), true);
|
|
EXPECT_EQ (v.is_user<B> (), false);
|
|
EXPECT_EQ (v.to_user<A> ().a, a.a);
|
|
tl::Variant vv;
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
// not working yet: EXPECT_EQ (vv == v, true);
|
|
// not working yet: EXPECT_EQ (vv != v, false);
|
|
EXPECT_EQ (vv.is_user (), true);
|
|
EXPECT_EQ (vv.to_user<A> ().a, a.a);
|
|
err = false;
|
|
try {
|
|
EXPECT_EQ (vv.to_user<B> ().b, b.b);
|
|
} catch (...) {
|
|
err = true;
|
|
}
|
|
EXPECT_EQ (err, true);
|
|
|
|
v = tl::Variant (new B(b), &b_class_instance, true);
|
|
v2 = tl::Variant (new B(b2), &b_class_instance, true);
|
|
EXPECT_EQ (vv == v, false);
|
|
EXPECT_EQ (vv != v, true);
|
|
vv = v;
|
|
EXPECT_EQ (vv == v, true);
|
|
EXPECT_EQ (vv != v, false);
|
|
EXPECT_EQ (v2 == v, false);
|
|
EXPECT_EQ (v2 != v, true);
|
|
EXPECT_EQ (v2 < v, true);
|
|
EXPECT_EQ (v < v2, false);
|
|
EXPECT_EQ (vv.is_user (), true);
|
|
EXPECT_EQ (vv.is_user<B> (), true);
|
|
EXPECT_EQ (vv.is_user<A> (), false);
|
|
err = false;
|
|
try {
|
|
EXPECT_EQ (vv.to_user<A> ().a, a.a);
|
|
} catch (...) {
|
|
err = true;
|
|
}
|
|
EXPECT_EQ (err, true);
|
|
EXPECT_EQ (vv.to_user<B> ().b, b.b);
|
|
EXPECT_EQ (vv.to_user<B> ().bb, b.bb);
|
|
|
|
// deep copy for owned objects
|
|
v = tl::Variant (new B(), &b_class_instance, true);
|
|
v.to_user<B> ().bb = 42;
|
|
v2 = v;
|
|
|
|
EXPECT_EQ (v.to_user<B> ().bb, 42);
|
|
EXPECT_EQ (v2.to_user<B> ().bb, 42);
|
|
|
|
v.to_user<B> ().bb += 1;
|
|
EXPECT_EQ (v.to_user<B> ().bb, 43);
|
|
EXPECT_EQ (v2.to_user<B> ().bb, 42);
|
|
|
|
b = B ();
|
|
b.bb = 17;
|
|
|
|
B *b1 = 0;
|
|
|
|
v = tl::Variant ();
|
|
v.set_user (b1 = new B(b), &b_class_instance, true);
|
|
v2 = v;
|
|
|
|
EXPECT_EQ (v.to_user<B> ().bb, b1->bb);
|
|
EXPECT_EQ (v2.to_user<B> ().bb, b1->bb);
|
|
|
|
b1->bb += 1;
|
|
EXPECT_EQ (v.to_user<B> ().bb, b1->bb);
|
|
EXPECT_EQ (v2.to_user<B> ().bb, b1->bb - 1);
|
|
|
|
b = B ();
|
|
b.bb = 17;
|
|
|
|
v = tl::Variant (&b, &b_class_instance, false);
|
|
v2 = v;
|
|
EXPECT_EQ (v.to_user<B> ().bb, b.bb);
|
|
EXPECT_EQ (v2.to_user<B> ().bb, b.bb);
|
|
|
|
b.bb += 1;
|
|
EXPECT_EQ (v.to_user<B> ().bb, b.bb);
|
|
EXPECT_EQ (v2.to_user<B> ().bb, b.bb);
|
|
|
|
// tl::Object based objects
|
|
AA::ac = 0;
|
|
|
|
AA *aa;
|
|
|
|
// shallow copy for tl::Object based objects
|
|
v = tl::Variant (aa = new AA (), &aa_class_instance, true);
|
|
EXPECT_EQ (AA::ac, 1);
|
|
v2 = v;
|
|
EXPECT_EQ (AA::ac, 1);
|
|
|
|
aa->a = "u";
|
|
EXPECT_EQ (v.to_user<AA> ().a, "u");
|
|
EXPECT_EQ (v2.to_user<AA> ().a, "u");
|
|
|
|
v = tl::Variant ();
|
|
EXPECT_EQ (AA::ac, 1);
|
|
v2 = tl::Variant ();
|
|
EXPECT_EQ (AA::ac, 0);
|
|
|
|
// shallow copy for tl::Object based objects
|
|
std::auto_ptr<AA> aptr (new AA ());
|
|
|
|
v = tl::Variant (aptr.get (), &aa_class_instance, false);
|
|
EXPECT_EQ (AA::ac, 1);
|
|
v2 = v;
|
|
EXPECT_EQ (AA::ac, 1);
|
|
|
|
aptr->a = "x";
|
|
EXPECT_EQ (v.to_user<AA> ().a, "x");
|
|
EXPECT_EQ (v2.to_user<AA> ().a, "x");
|
|
|
|
v = tl::Variant ();
|
|
EXPECT_EQ (AA::ac, 1);
|
|
v2 = tl::Variant ();
|
|
EXPECT_EQ (AA::ac, 1);
|
|
|
|
v = tl::Variant (aptr.get (), &aa_class_instance, false);
|
|
EXPECT_EQ (AA::ac, 1);
|
|
v2 = v;
|
|
EXPECT_EQ (AA::ac, 1);
|
|
EXPECT_EQ (v.to_user<AA> ().a, "x");
|
|
EXPECT_EQ (v2.to_user<AA> ().a, "x");
|
|
|
|
aptr.reset (0);
|
|
EXPECT_EQ (v.to_user (), 0);
|
|
EXPECT_EQ (v2.to_user (), 0);
|
|
}
|
|
|
|
TEST(3)
|
|
{
|
|
std::string s = "'1',#1";
|
|
tl::Variant v1;
|
|
tl::Variant v2;
|
|
tl::Extractor ex (s.c_str ());
|
|
ex.read (v1);
|
|
ex.test (",");
|
|
ex.read (v2);
|
|
EXPECT_EQ (v1 == tl::Variant ("1"), true);
|
|
EXPECT_EQ (v2 == tl::Variant (1), true);
|
|
EXPECT_EQ (v2 == v1, false);
|
|
EXPECT_EQ (v1 == v1, true);
|
|
EXPECT_EQ (v2 == v2, true);
|
|
EXPECT_EQ (v2 < v1, true);
|
|
EXPECT_EQ (v1 < v2, false);
|
|
EXPECT_EQ (v1 < v1, false);
|
|
EXPECT_EQ (v2 < v2, false);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|