+#if wxUSE_VARIANT
+
+// For testing purposes, create dummy variant data implementation
+// that does not have wxAny conversion code
+class wxMyVariantData : public wxVariantData
+{
+public:
+ wxMyVariantData(const MyClass& value)
+ {
+ m_value = value;
+ }
+
+ virtual bool Eq(wxVariantData& WXUNUSED(data)) const
+ {
+ return false;
+ }
+
+ // What type is it? Return a string name.
+ virtual wxString GetType() const { return "MyClass"; }
+
+ virtual wxVariantData* Clone() const
+ {
+ return new wxMyVariantData(m_value);
+ }
+
+protected:
+ MyClass m_value;
+};
+
+#endif // wxUSE_VARIANT
+
+
+void wxAnyTestCase::wxVariantConversions()
+{
+#if wxUSE_VARIANT
+ //
+ // Test various conversions to and from wxVariant
+ //
+ bool res;
+
+ // Prepare wxVariants
+ wxVariant vLong(123L);
+ wxVariant vString("ABC");
+ wxVariant vDouble(TEST_FLOAT_CONST);
+ wxVariant vBool((bool)true);
+ wxVariant vChar('A');
+#ifdef wxLongLong_t
+ wxVariant vLongLong(wxLongLong(wxLL(0xAABBBBCCCC)));
+ wxVariant vULongLong(wxULongLong(wxULL(123456)));
+#endif
+ wxArrayString arrstr;
+ arrstr.push_back("test string");
+ wxVariant vArrayString(arrstr);
+ wxVariant vDateTime(m_testDateTime);
+ wxVariant vVoidPtr(dummyVoidPointer);
+ wxVariant vCustomType(new wxMyVariantData(MyClass(101)));
+ wxVariant vList;
+
+ vList.NullList();
+ vList.Append(15);
+ vList.Append("abc");
+
+ // Convert to wxAnys, and then back to wxVariants
+ wxVariant variant;
+
+ wxAny any(vLong);
+ CPPUNIT_ASSERT(any == 123L);
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant == 123L);
+
+ // Make sure integer variant has correct type information
+ CPPUNIT_ASSERT(variant.GetLong() == 123);
+ CPPUNIT_ASSERT(variant.GetType() == "long");
+
+ // Unsigned long wxAny should convert to "ulonglong" wxVariant
+ any = 1000UL;
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "ulonglong");
+ CPPUNIT_ASSERT(variant.GetLong() == 1000);
+
+ any = vString;
+ CPPUNIT_ASSERT(any == "ABC");
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetString() == "ABC");
+
+ // Must be able to build string wxVariant from wxAny built from
+ // string literal
+ any = "ABC";
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "string");
+ CPPUNIT_ASSERT(variant.GetString() == "ABC");
+ any = L"ABC";
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "string");
+#if wxUSE_UNICODE
+ CPPUNIT_ASSERT(variant.GetString() == L"ABC");
+#endif
+
+ any = vDouble;
+ double d = wxANY_AS(any, double);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(d, TEST_FLOAT_CONST, FEQ_DELTA);
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(variant.GetDouble(),
+ TEST_FLOAT_CONST,
+ FEQ_DELTA);
+
+ any = vBool;
+ CPPUNIT_ASSERT(wxANY_AS(any, bool) == true);
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetBool() == true);
+
+ any = wxAny(vChar);
+ //CPPUNIT_ASSERT(wxANY_AS(any, wxUniChar) == 'A');
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetChar() == 'A');
+
+#ifdef wxLongLong_t
+ any = wxAny(vLongLong);
+ CPPUNIT_ASSERT(any == wxLL(0xAABBBBCCCC));
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "longlong");
+ CPPUNIT_ASSERT(variant.GetLongLong() == wxLongLong(wxLL(0xAABBBBCCCC)));
+
+#if LONG_MAX == wxINT64_MAX
+ // As a sanity check, test that wxVariant of type 'long' converts
+ // seamlessly to 'longlong' (on some 64-bit systems)
+ any = 0xAABBBBCCCCL;
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(variant.GetLongLong() == wxLongLong(wxLL(0xAABBBBCCCC)));
+#endif
+
+ any = wxAny(vULongLong);
+ CPPUNIT_ASSERT(any == wxLL(123456));
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "ulonglong");
+ CPPUNIT_ASSERT(variant.GetULongLong() == wxULongLong(wxULL(123456)));
+#endif
+
+ // Cannot test equality for the rest, just test that they convert
+ // back correctly.
+ any = wxAny(vArrayString);
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ wxArrayString arrstr2 = variant.GetArrayString();
+ CPPUNIT_ASSERT(arrstr2 == arrstr);
+
+ any = m_testDateTime;
+ CPPUNIT_ASSERT(wxANY_AS(any, wxDateTime) == m_testDateTime);
+ any = wxAny(vDateTime);
+ CPPUNIT_ASSERT(wxANY_AS(any, wxDateTime) == m_testDateTime);
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant == m_testDateTime);
+
+ any = wxAny(vVoidPtr);
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetVoidPtr() == dummyVoidPointer);
+
+ any = wxAny(vList);
+ CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxAnyList));
+ wxAnyList anyList = wxANY_AS(any, wxAnyList);
+ CPPUNIT_ASSERT(anyList.GetCount() == 2);
+ CPPUNIT_ASSERT(wxANY_AS((*anyList[0]), int) == 15);
+ CPPUNIT_ASSERT(wxANY_AS((*anyList[1]), wxString) == "abc");
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "list");
+ CPPUNIT_ASSERT(variant.GetCount() == 2);
+ CPPUNIT_ASSERT(variant[0].GetLong() == 15);
+ CPPUNIT_ASSERT(variant[1].GetString() == "abc");
+
+ any = wxAny(vCustomType);
+ CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxVariantData*));
+ res = any.GetAs(&variant);
+ CPPUNIT_ASSERT(res);
+ CPPUNIT_ASSERT(variant.GetType() == "MyClass");
+
+#endif // wxUSE_VARIANT
+}
+