/* KLayout Layout Viewer Copyright (C) 2006-2018 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 #include 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 : public type_traits { 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 : public type_traits { 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_class_instance; static tl::VariantUserClassImpl aa_class_instance; static tl::VariantUserClassImpl b_class_instance; // This namespace separates the test structs from other objects namespace { TEST(1) { tl::Variant vv; { tl::Variant v; #if defined(HAVE_QT) EXPECT_EQ (tl::to_string (v.to_qvariant ().toString ()), ""); #endif 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 (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); 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; 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u1"); #endif 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_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 (), true); EXPECT_EQ (v.is (), 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u2"); #endif EXPECT_EQ (v.is_nil (), false); EXPECT_EQ (v.is_list (), false); EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), 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; 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 (); EXPECT_EQ (vx == v, true); } { tl::Variant v (1); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#1"); #endif 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_longlong (), false); 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); EXPECT_EQ (v.is (), false); 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; 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 (); EXPECT_EQ (vx == v, true); } { tl::Variant v (2l); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#2"); #endif 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 (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); 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); 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "##5"); #endif 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_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); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), 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 (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; 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(); EXPECT_EQ (vx == v, true); } { tl::Variant v (5.0); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "##5"); #endif 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_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); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is_char (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), 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_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); 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 (); EXPECT_EQ (*(float *)v.native_ptr (), 5.0); v.morph (); EXPECT_EQ (*(int *)v.native_ptr (), 5); v.morph (); EXPECT_EQ (*(long *)v.native_ptr (), 5); v.morph (); EXPECT_EQ (*(long long *)v.native_ptr (), 5); v.morph (); EXPECT_EQ (*(unsigned long *)v.native_ptr (), (unsigned long) 5); v.morph (); EXPECT_EQ (*(unsigned int *)v.native_ptr (), (unsigned int) 5); v.morph (); EXPECT_EQ (*(unsigned short *)v.native_ptr (), 5); v.morph (); EXPECT_EQ (*(unsigned char *)v.native_ptr (), 5); } { tl::Variant v((short)2); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#2"); #endif 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 (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); 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; 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 (), true); EXPECT_EQ (vx.is (), false); EXPECT_EQ (v.is (), true); EXPECT_EQ (*(long *)vx.native_ptr(), 2); EXPECT_EQ (*(short *)v.native_ptr(), 2); v.morph(); 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u2"); #endif 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 (), false); EXPECT_EQ (v.is (), true); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), false); EXPECT_EQ (v.is (), 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 (), true); EXPECT_EQ (*(unsigned long *)vx.native_ptr(), (unsigned long) 2); EXPECT_EQ (*(unsigned short *)v.native_ptr(), 2); v.morph(); 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"); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "'hal\\'l\"o'"); #endif 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_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'"); 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(); EXPECT_EQ (vx == v, true); } { #if defined(HAVE_QT) 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_qstring (), true); EXPECT_EQ (v.is_nil (), false); EXPECT_EQ (v.is_list (), false); EXPECT_EQ (v.is_cstring (), false); 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"); EXPECT_EQ (tl::to_string (*(QString *)v.native_ptr ()), "hal'l\"o"); v.morph (); 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 (); 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"); #endif } { long a[3] = { 1, 5, 25 }; tl::Variant v (a, a + 3); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "(#1,#5,#25)"); #endif 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#l17"); #endif 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#lu17"); #endif 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); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "#u17"); #endif 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 (); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "{}"); #endif 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}"); #if defined(HAVE_QT) EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "{\'1\'=>\'A\',\'B\'=>#17}"); #endif 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 (), true); EXPECT_EQ (v.is_user (), false); EXPECT_EQ (v.to_user ().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); err = false; try { EXPECT_EQ (vv.to_user ().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 (), true); EXPECT_EQ (vv.is_user (), false); err = false; try { EXPECT_EQ (vv.to_user ().a, a.a); } catch (...) { err = true; } EXPECT_EQ (err, true); EXPECT_EQ (vv.to_user ().b, b.b); EXPECT_EQ (vv.to_user ().bb, b.bb); // deep copy for owned objects v = tl::Variant (new B(), &b_class_instance, true); v.to_user ().bb = 42; v2 = v; EXPECT_EQ (v.to_user ().bb, 42); EXPECT_EQ (v2.to_user ().bb, 42); v.to_user ().bb += 1; EXPECT_EQ (v.to_user ().bb, 43); EXPECT_EQ (v2.to_user ().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 ().bb, b1->bb); EXPECT_EQ (v2.to_user ().bb, b1->bb); b1->bb += 1; EXPECT_EQ (v.to_user ().bb, b1->bb); EXPECT_EQ (v2.to_user ().bb, b1->bb - 1); b = B (); b.bb = 17; v = tl::Variant (&b, &b_class_instance, false); v2 = v; EXPECT_EQ (v.to_user ().bb, b.bb); EXPECT_EQ (v2.to_user ().bb, b.bb); b.bb += 1; EXPECT_EQ (v.to_user ().bb, b.bb); EXPECT_EQ (v2.to_user ().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 ().a, "u"); EXPECT_EQ (v2.to_user ().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 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 ().a, "x"); EXPECT_EQ (v2.to_user ().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 ().a, "x"); EXPECT_EQ (v2.to_user ().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); } // 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); } }