]> git.saurik.com Git - wxWidgets.git/blobdiff - tests/any/anytest.cpp
Several fixes for wxAffineMatrix2D transformations.
[wxWidgets.git] / tests / any / anytest.cpp
index 4b056916449cdcd787255be28dce1b28598fdf7b..7c6fdaa131cd9b31d71baf4faefd3c1b8488ebb4 100644 (file)
-///////////////////////////////////////////////////////////////////////////////\r
-// Name:        tests/any/anytest.cpp\r
-// Purpose:     Test the wxAny classes\r
-// Author:      Jaakko Salli\r
-// RCS-ID:      $Id$\r
-// Copyright:   (c) the wxWidgets team\r
-// Licence:     wxWindows licence\r
-///////////////////////////////////////////////////////////////////////////////\r
-\r
-#include "testprec.h"\r
-\r
-#ifdef __BORLANDC__\r
-#   pragma hdrstop\r
-#endif\r
-\r
-#if wxUSE_ANY\r
-\r
-#include "wx/any.h"\r
-#include "wx/datetime.h"\r
-\r
-#include <math.h>\r
-\r
-// ----------------------------------------------------------------------------\r
-// test class\r
-// ----------------------------------------------------------------------------\r
-\r
-class wxAnyTestCase : public CppUnit::TestCase\r
-{\r
-public:\r
-    wxAnyTestCase();\r
-\r
-private:\r
-    CPPUNIT_TEST_SUITE( wxAnyTestCase );\r
-        CPPUNIT_TEST( Equality );\r
-        CPPUNIT_TEST( As );\r
-        CPPUNIT_TEST( GetAs );\r
-        CPPUNIT_TEST( Null );\r
-        CPPUNIT_TEST( CustomTemplateSpecialization );\r
-    CPPUNIT_TEST_SUITE_END();\r
-\r
-    void Equality();\r
-    void As();\r
-    void GetAs();\r
-    void Null();\r
-    void CustomTemplateSpecialization();\r
-\r
-    wxDateTime m_testDateTime;\r
-\r
-    wxAny   m_anySignedChar1;\r
-    wxAny   m_anySignedShort1;\r
-    wxAny   m_anySignedInt1;\r
-    wxAny   m_anySignedLong1;\r
-    wxAny   m_anySignedLongLong1;\r
-    wxAny   m_anyUnsignedChar1;\r
-    wxAny   m_anyUnsignedShort1;\r
-    wxAny   m_anyUnsignedInt1;\r
-    wxAny   m_anyUnsignedLong1;\r
-    wxAny   m_anyUnsignedLongLong1;\r
-    wxAny   m_anyStringString1;\r
-    wxAny   m_anyCharString1;\r
-    wxAny   m_anyWcharString1;\r
-    wxAny   m_anyBool1;\r
-    wxAny   m_anyFloatDouble1;\r
-    wxAny   m_anyDoubleDouble1;\r
-    wxAny   m_anyWxObjectPtr1;\r
-    wxAny   m_anyVoidPtr1;\r
-    wxAny   m_anyDateTime1;\r
-\r
-    wxAny   m_anySignedChar2;\r
-    wxAny   m_anySignedShort2;\r
-    wxAny   m_anySignedInt2;\r
-    wxAny   m_anySignedLong2;\r
-    wxAny   m_anySignedLongLong2;\r
-    wxAny   m_anyUnsignedChar2;\r
-    wxAny   m_anyUnsignedShort2;\r
-    wxAny   m_anyUnsignedInt2;\r
-    wxAny   m_anyUnsignedLong2;\r
-    wxAny   m_anyUnsignedLongLong2;\r
-    wxAny   m_anyStringString2;\r
-    wxAny   m_anyCharString2;\r
-    wxAny   m_anyWcharString2;\r
-    wxAny   m_anyBool2;\r
-    wxAny   m_anyFloatDouble2;\r
-    wxAny   m_anyDoubleDouble2;\r
-    wxAny   m_anyWxObjectPtr2;\r
-    wxAny   m_anyVoidPtr2;\r
-    wxAny   m_anyDateTime2;\r
-\r
-    DECLARE_NO_COPY_CLASS(wxAnyTestCase)\r
-};\r
-\r
-// register in the unnamed registry so that these tests are run by default\r
-CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );\r
-\r
-// also include in it's own registry so that these tests can be run alone\r
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );\r
-\r
-// Let's use a number with first digit after decimal dot less than 5,\r
-// so that we don't have to worry about whether conversion from float\r
-// to int truncates or rounds.\r
-const double TEST_FLOAT_CONST = 123.456;\r
-\r
-const double FEQ_DELTA = 0.001;\r
-\r
-wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);\r
-void* dummyVoidPointer = reinterpret_cast<void*>(1234);\r
-\r
-\r
-//\r
-// Test both 'creation' methods\r
-wxAnyTestCase::wxAnyTestCase()\r
-    : m_anySignedChar1((signed char)15),\r
-      m_anySignedShort1((signed short)15),\r
-      m_anySignedInt1((signed int)15),\r
-      m_anySignedLong1((signed long)15),\r
-#ifdef wxLongLong_t\r
-      m_anySignedLongLong1((wxLongLong_t)15),\r
-#endif\r
-      m_anyUnsignedChar1((unsigned char)15),\r
-      m_anyUnsignedShort1((unsigned short)15),\r
-      m_anyUnsignedInt1((unsigned int)15),\r
-      m_anyUnsignedLong1((unsigned long)15),\r
-#ifdef wxLongLong_t\r
-      m_anyUnsignedLongLong1((wxULongLong_t)15),\r
-#endif\r
-      m_anyStringString1(wxString("abc")),\r
-      m_anyCharString1("abc"),\r
-      m_anyWcharString1(L"abc"),\r
-      m_anyBool1(true),\r
-      m_anyFloatDouble1((float)TEST_FLOAT_CONST),\r
-      m_anyDoubleDouble1((double)TEST_FLOAT_CONST),\r
-      m_anyWxObjectPtr1(dummyWxObjectPointer),\r
-      m_anyVoidPtr1(dummyVoidPointer),\r
-      m_anyDateTime1(wxDateTime::Now())\r
-{\r
-    m_testDateTime = wxDateTime::Now();\r
-    m_anySignedChar2 = (signed char)15;\r
-    m_anySignedShort2 = (signed short)15;\r
-    m_anySignedInt2 = (signed int)15;\r
-    m_anySignedLong2 = (signed long)15;\r
-#ifdef wxLongLong_t\r
-    m_anySignedLongLong2 = (wxLongLong_t)15;\r
-#endif\r
-    m_anyUnsignedChar2 = (unsigned char)15;\r
-    m_anyUnsignedShort2 = (unsigned short)15;\r
-    m_anyUnsignedInt2 = (unsigned int)15;\r
-    m_anyUnsignedLong2 = (unsigned long)15;\r
-#ifdef wxLongLong_t\r
-    m_anyUnsignedLongLong2 = (wxULongLong_t)15;\r
-#endif\r
-    m_anyStringString2 = wxString("abc");\r
-    m_anyCharString2 = "abc";\r
-    m_anyWcharString2 = L"abc";\r
-    m_anyBool2 = true;\r
-    m_anyFloatDouble2 = (float)TEST_FLOAT_CONST;\r
-    m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST;\r
-    m_anyDateTime2 = m_testDateTime;\r
-    m_anyWxObjectPtr2 = dummyWxObjectPointer;\r
-    m_anyVoidPtr2 = dummyVoidPointer;\r
-}\r
-\r
-void wxAnyTestCase::Equality()\r
-{\r
-    //\r
-    // Currently this should work\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);\r
-    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);\r
-    CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));\r
-    CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));\r
-    CPPUNIT_ASSERT(m_anyStringString1 == "abc");\r
-    CPPUNIT_ASSERT(m_anyStringString1 != "ABC");\r
-    CPPUNIT_ASSERT(m_anyStringString1 == L"abc");\r
-    CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");\r
-    CPPUNIT_ASSERT(m_anyBool1 == true);\r
-    CPPUNIT_ASSERT(m_anyBool1 != false);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),\r
-                                 wxANY_AS(m_anyDoubleDouble1, double),\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),\r
-                                 TEST_FLOAT_CONST,\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT(m_anyWxObjectPtr1.As<wxObject*>() == dummyWxObjectPointer);\r
-    CPPUNIT_ASSERT(m_anyVoidPtr1.As<void*>() == dummyVoidPointer);\r
-\r
-    CPPUNIT_ASSERT(m_anySignedLong2 == 15);\r
-    CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));\r
-    CPPUNIT_ASSERT(m_anyStringString2 == "abc");\r
-    CPPUNIT_ASSERT(m_anyStringString2 == L"abc");\r
-    CPPUNIT_ASSERT(m_anyBool2 == true);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),\r
-                                 wxANY_AS(m_anyDoubleDouble2, double),\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),\r
-                                 TEST_FLOAT_CONST,\r
-                                 FEQ_DELTA);\r
-    CPPUNIT_ASSERT(m_anyWxObjectPtr2.As<wxObject*>() == dummyWxObjectPointer);\r
-    CPPUNIT_ASSERT(m_anyVoidPtr2.As<void*>() == dummyVoidPointer);\r
-}\r
-\r
-void wxAnyTestCase::As()\r
-{\r
-    //\r
-    // Test getting C++ data from wxAny without dynamic conversion\r
-    signed char a = wxANY_AS(m_anySignedChar1, signed char);\r
-    CPPUNIT_ASSERT(a == (signed int)15);\r
-    signed short b = wxANY_AS(m_anySignedShort1, signed short);\r
-    CPPUNIT_ASSERT(b == (signed int)15);\r
-    signed int c = wxANY_AS(m_anySignedInt1, signed int);\r
-    CPPUNIT_ASSERT(c == (signed int)15);\r
-    signed long d = wxANY_AS(m_anySignedLong1, signed long);\r
-    CPPUNIT_ASSERT(d == (signed int)15);\r
-#ifdef wxLongLong_t\r
-    wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);\r
-    CPPUNIT_ASSERT(e == (signed int)15);\r
-#endif\r
-    unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);\r
-    CPPUNIT_ASSERT(f == (unsigned int)15);\r
-    unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);\r
-    CPPUNIT_ASSERT(g == (unsigned int)15);\r
-    unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);\r
-    CPPUNIT_ASSERT(h == (unsigned int)15);\r
-    unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);\r
-    CPPUNIT_ASSERT(i == (unsigned int)15);\r
-#ifdef wxLongLong_t\r
-    wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);\r
-    CPPUNIT_ASSERT(j == (unsigned int)15);\r
-#endif\r
-    wxString k = wxANY_AS(m_anyStringString1, wxString);\r
-    CPPUNIT_ASSERT(k == "abc");\r
-    wxString l = wxANY_AS(m_anyCharString1, wxString);\r
-    CPPUNIT_ASSERT(l == "abc");\r
-    wxString m = wxANY_AS(m_anyWcharString1, wxString);\r
-    CPPUNIT_ASSERT(m == "abc");\r
-    bool n = wxANY_AS(m_anyBool1, bool);\r
-    CPPUNIT_ASSERT(n);\r
-    float o = wxANY_AS(m_anyFloatDouble1, float);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA);\r
-    double p = wxANY_AS(m_anyDoubleDouble1, double);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA);\r
-    wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);\r
-    CPPUNIT_ASSERT(q == m_testDateTime);\r
-    wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);\r
-    CPPUNIT_ASSERT(r == dummyWxObjectPointer);\r
-    void* s = wxANY_AS(m_anyVoidPtr1, void*);\r
-    CPPUNIT_ASSERT(s == dummyVoidPointer);\r
-}\r
-\r
-void wxAnyTestCase::Null()\r
-{\r
-    wxAny a;\r
-    CPPUNIT_ASSERT(a.IsNull());\r
-    a = -127;\r
-    CPPUNIT_ASSERT(a == -127);\r
-    a.MakeNull();\r
-    CPPUNIT_ASSERT(a.IsNull());\r
-}\r
-\r
-void wxAnyTestCase::GetAs()\r
-{\r
-    //\r
-    // Test dynamic conversion\r
-    bool res;\r
-    long l = 0;\r
-    unsigned long ul = 0;\r
-    wxString s;\r
-    // Let's test against float instead of double, since the former\r
-    // is not the native underlying type the code converts to, but\r
-    // should still work, all the same.\r
-    float f = 0.0;\r
-    bool b = false;\r
-\r
-    // Conversions from signed long type\r
-    res = m_anySignedLong1.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));\r
-    res = m_anySignedLong1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(s == "15");\r
-    res = m_anySignedLong1.GetAs(&f);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);\r
-    res = m_anySignedLong1.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == true);\r
-\r
-    // Conversions from unsigned long type\r
-    res = m_anyUnsignedLong1.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(15));\r
-    res = m_anyUnsignedLong1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(s == "15");\r
-    res = m_anyUnsignedLong1.GetAs(&f);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);\r
-    res = m_anyUnsignedLong1.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == true);\r
-\r
-    // Conversions from default "abc" string to other types\r
-    // should not work.\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));\r
-    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));\r
-\r
-    // Let's test some other conversions from string that should work.\r
-    wxAny anyString;\r
-\r
-    anyString = "15";\r
-    res = anyString.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(15));\r
-    res = anyString.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));\r
-    res = anyString.GetAs(&f);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);\r
-    anyString = "TRUE";\r
-    res = anyString.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == true);\r
-    anyString = "0";\r
-    res = anyString.GetAs(&b);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(b == false);\r
-\r
-    // Conversions from bool type\r
-    res = m_anyBool1.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(1));\r
-    res = m_anyBool1.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));\r
-    res = m_anyBool1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(s == "true");\r
-    CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));\r
-\r
-    // Conversions from floating point type\r
-    res = m_anyDoubleDouble1.GetAs(&l);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT(l == static_cast<signed long>(123));\r
-    res = m_anyDoubleDouble1.GetAs(&ul);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));\r
-    res = m_anyDoubleDouble1.GetAs(&s);\r
-    CPPUNIT_ASSERT(res);\r
-    double d2;\r
-    res = s.ToDouble(&d2);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);\r
-}\r
-\r
-//\r
-// Test user data type specialization of wxAnyValueTypeImpl\r
-//\r
-\r
-class MyClass\r
-{\r
-public:\r
-    MyClass( int someValue = 32768 )\r
-    {\r
-        m_someValue = someValue;\r
-    }\r
-\r
-    wxString ToString()\r
-    {\r
-        return wxString::Format("%i", m_someValue);\r
-    }\r
-\r
-private:\r
-    int     m_someValue;\r
-};\r
-\r
-\r
-template<>\r
-class wxAnyValueTypeImpl<MyClass> :\r
-    public wxAnyValueTypeImplBase<MyClass>\r
-{\r
-    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-public:\r
-    wxAnyValueTypeImpl() :\r
-        wxAnyValueTypeImplBase<MyClass>() { }\r
-    virtual ~wxAnyValueTypeImpl() { }\r
-\r
-    virtual bool ConvertValue(const wxAnyValueBuffer& src,\r
-                              wxAnyValueType* dstType,\r
-                              wxAnyValueBuffer& dst) const\r
-    {\r
-        MyClass value = GetValue(src);\r
-\r
-        if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )\r
-        {\r
-            wxString s = value.ToString();\r
-            wxAnyValueTypeImpl<wxString>::SetValue(s, dst);\r
-        }\r
-        else\r
-            return false;\r
-\r
-        return true;\r
-    }\r
-};\r
-\r
-//\r
-// Following must be placed somewhere in your source code\r
-WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)\r
-\r
-void wxAnyTestCase::CustomTemplateSpecialization()\r
-{\r
-    // Do only a minimal CheckType() test, as dynamic type conversion already\r
-    // uses it a lot.\r
-    bool res;\r
-    MyClass myObject;\r
-    wxAny any = myObject;\r
-\r
-    CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );\r
-    MyClass myObject2 = wxANY_AS(any, MyClass);\r
-    wxUnusedVar(myObject2);\r
-\r
-    wxString str;\r
-    res = any.GetAs(&str);\r
-    CPPUNIT_ASSERT(res);\r
-    CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());\r
-}\r
-\r
-#endif // wxUSE_ANY\r
-\r
+///////////////////////////////////////////////////////////////////////////////
+// Name:        tests/any/anytest.cpp
+// Purpose:     Test the wxAny classes
+// Author:      Jaakko Salli
+// RCS-ID:      $Id$
+// Copyright:   (c) the wxWidgets team
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+#   pragma hdrstop
+#endif
+
+#if wxUSE_ANY
+
+#include "wx/any.h"
+#include "wx/datetime.h"
+#include "wx/object.h"
+#include "wx/vector.h"
+
+#include <math.h>
+
+// ----------------------------------------------------------------------------
+// test class
+// ----------------------------------------------------------------------------
+
+class wxAnyTestCase : public CppUnit::TestCase
+{
+public:
+    wxAnyTestCase();
+
+private:
+    CPPUNIT_TEST_SUITE( wxAnyTestCase );
+        CPPUNIT_TEST( CheckType );
+        CPPUNIT_TEST( Equality );
+        CPPUNIT_TEST( As );
+        CPPUNIT_TEST( GetAs );
+        CPPUNIT_TEST( Null );
+        CPPUNIT_TEST( wxVariantConversions );
+        CPPUNIT_TEST( CustomTemplateSpecialization );
+        CPPUNIT_TEST( Misc );
+    CPPUNIT_TEST_SUITE_END();
+
+    void CheckType();
+    void Equality();
+    void As();
+    void GetAs();
+    void Null();
+    void wxVariantConversions();
+    void CustomTemplateSpecialization();
+    void Misc();
+
+    wxDateTime m_testDateTime;
+
+    wxAny   m_anySignedChar1;
+    wxAny   m_anySignedShort1;
+    wxAny   m_anySignedInt1;
+    wxAny   m_anySignedLong1;
+    wxAny   m_anySignedLongLong1;
+    wxAny   m_anyUnsignedChar1;
+    wxAny   m_anyUnsignedShort1;
+    wxAny   m_anyUnsignedInt1;
+    wxAny   m_anyUnsignedLong1;
+    wxAny   m_anyUnsignedLongLong1;
+    wxAny   m_anyStringString1;
+    wxAny   m_anyCharString1;
+    wxAny   m_anyWcharString1;
+    wxAny   m_anyBool1;
+    wxAny   m_anyFloatDouble1;
+    wxAny   m_anyDoubleDouble1;
+    wxAny   m_anyWxObjectPtr1;
+    wxAny   m_anyVoidPtr1;
+    wxAny   m_anyDateTime1;
+    wxAny   m_anyUniChar1;
+
+    wxAny   m_anySignedChar2;
+    wxAny   m_anySignedShort2;
+    wxAny   m_anySignedInt2;
+    wxAny   m_anySignedLong2;
+    wxAny   m_anySignedLongLong2;
+    wxAny   m_anyUnsignedChar2;
+    wxAny   m_anyUnsignedShort2;
+    wxAny   m_anyUnsignedInt2;
+    wxAny   m_anyUnsignedLong2;
+    wxAny   m_anyUnsignedLongLong2;
+    wxAny   m_anyStringString2;
+    wxAny   m_anyCharString2;
+    wxAny   m_anyWcharString2;
+    wxAny   m_anyBool2;
+    wxAny   m_anyFloatDouble2;
+    wxAny   m_anyDoubleDouble2;
+    wxAny   m_anyWxObjectPtr2;
+    wxAny   m_anyVoidPtr2;
+    wxAny   m_anyDateTime2;
+
+    DECLARE_NO_COPY_CLASS(wxAnyTestCase)
+};
+
+// register in the unnamed registry so that these tests are run by default
+CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );
+
+// also include in its own registry so that these tests can be run alone
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );
+
+// Let's use a number with first digit after decimal dot less than 5,
+// so that we don't have to worry about whether conversion from float
+// to int truncates or rounds.
+const float TEST_FLOAT_CONST = 123.456f;
+const double TEST_DOUBLE_CONST = 123.456;
+
+const double FEQ_DELTA = 0.001;
+
+wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);
+void* dummyVoidPointer = reinterpret_cast<void*>(1234);
+
+
+//
+// Test both 'creation' methods
+wxAnyTestCase::wxAnyTestCase()
+    : m_anySignedChar1((signed char)15),
+      m_anySignedShort1((signed short)15),
+      m_anySignedInt1((signed int)15),
+      m_anySignedLong1((signed long)15),
+#ifdef wxLongLong_t
+      m_anySignedLongLong1((wxLongLong_t)15),
+#endif
+      m_anyUnsignedChar1((unsigned char)15),
+      m_anyUnsignedShort1((unsigned short)15),
+      m_anyUnsignedInt1((unsigned int)15),
+      m_anyUnsignedLong1((unsigned long)15),
+#ifdef wxLongLong_t
+      m_anyUnsignedLongLong1((wxULongLong_t)15),
+#endif
+      m_anyStringString1(wxString("abc")),
+      m_anyCharString1("abc"),
+      m_anyWcharString1(L"abc"),
+      m_anyBool1(true),
+      m_anyFloatDouble1(TEST_FLOAT_CONST),
+      m_anyDoubleDouble1(TEST_DOUBLE_CONST),
+      m_anyWxObjectPtr1(dummyWxObjectPointer),
+      m_anyVoidPtr1(dummyVoidPointer),
+      m_anyDateTime1(wxDateTime::Now())
+{
+    m_testDateTime = wxDateTime::Now();
+    m_anySignedChar2 = (signed char)15;
+    m_anySignedShort2 = (signed short)15;
+    m_anySignedInt2 = (signed int)15;
+    m_anySignedLong2 = (signed long)15;
+#ifdef wxLongLong_t
+    m_anySignedLongLong2 = (wxLongLong_t)15;
+#endif
+    m_anyUnsignedChar2 = (unsigned char)15;
+    m_anyUnsignedShort2 = (unsigned short)15;
+    m_anyUnsignedInt2 = (unsigned int)15;
+    m_anyUnsignedLong2 = (unsigned long)15;
+#ifdef wxLongLong_t
+    m_anyUnsignedLongLong2 = (wxULongLong_t)15;
+#endif
+    m_anyStringString2 = wxString("abc");
+    m_anyCharString2 = "abc";
+    m_anyWcharString2 = L"abc";
+    m_anyBool2 = true;
+    m_anyFloatDouble2 = TEST_FLOAT_CONST;
+    m_anyDoubleDouble2 = TEST_DOUBLE_CONST;
+    m_anyDateTime2 = m_testDateTime;
+    m_anyUniChar1 = wxUniChar('A');
+    m_anyWxObjectPtr2 = dummyWxObjectPointer;
+    m_anyVoidPtr2 = dummyVoidPointer;
+}
+
+void wxAnyTestCase::CheckType()
+{
+    wxAny nullAny;
+    CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(nullAny, wxString));
+
+    CPPUNIT_ASSERT(wxANY_CHECK_TYPE(m_anyCharString2, const char*));
+    CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyCharString2, wxString));
+    CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyCharString2, const wchar_t*));
+    CPPUNIT_ASSERT(wxANY_CHECK_TYPE(m_anyWcharString2, const wchar_t*));
+    CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyWcharString2, wxString));
+    CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyWcharString2, const char*));
+
+    // HasSameType()
+    CPPUNIT_ASSERT( m_anyWcharString1.HasSameType(m_anyWcharString2) );
+    CPPUNIT_ASSERT( !m_anyWcharString1.HasSameType(m_anyBool1) );
+}
+
+void wxAnyTestCase::Equality()
+{
+    //
+    // Currently this should work
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);
+    CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);
+    CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));
+    CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));
+    CPPUNIT_ASSERT(m_anyStringString1 == "abc");
+    CPPUNIT_ASSERT(m_anyStringString1 != "ABC");
+    CPPUNIT_ASSERT(m_anyStringString1 == L"abc");
+    CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");
+    CPPUNIT_ASSERT(m_anyBool1 == true);
+    CPPUNIT_ASSERT(m_anyBool1 != false);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
+                                 wxANY_AS(m_anyDoubleDouble1, double),
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
+                                 TEST_FLOAT_CONST,
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*)
+                        == dummyWxObjectPointer);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer);
+
+    CPPUNIT_ASSERT(m_anySignedLong2 == 15);
+    CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));
+    CPPUNIT_ASSERT(m_anyStringString2 == "abc");
+    CPPUNIT_ASSERT(m_anyStringString2 == L"abc");
+    CPPUNIT_ASSERT(m_anyBool2 == true);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
+                                 wxANY_AS(m_anyDoubleDouble2, double),
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
+                                 TEST_FLOAT_CONST,
+                                 FEQ_DELTA);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*)
+                        == dummyWxObjectPointer);
+    CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer);
+
+    // Test sub-type system type compatibility
+    CPPUNIT_ASSERT(m_anySignedShort1.GetType()->
+                  IsSameType(m_anySignedLongLong1.GetType()));
+    CPPUNIT_ASSERT(m_anyUnsignedShort1.GetType()->
+                   IsSameType(m_anyUnsignedLongLong1.GetType()));
+}
+
+void wxAnyTestCase::As()
+{
+    //
+    // Test getting C++ data from wxAny without dynamic conversion
+    signed char a = wxANY_AS(m_anySignedChar1, signed char);
+    CPPUNIT_ASSERT(a == (signed int)15);
+    signed short b = wxANY_AS(m_anySignedShort1, signed short);
+    CPPUNIT_ASSERT(b == (signed int)15);
+    signed int c = wxANY_AS(m_anySignedInt1, signed int);
+    CPPUNIT_ASSERT(c == (signed int)15);
+    signed long d = wxANY_AS(m_anySignedLong1, signed long);
+    CPPUNIT_ASSERT(d == (signed int)15);
+#ifdef wxLongLong_t
+    wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);
+    CPPUNIT_ASSERT(e == (signed int)15);
+#endif
+    unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);
+    CPPUNIT_ASSERT(f == (unsigned int)15);
+    unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);
+    CPPUNIT_ASSERT(g == (unsigned int)15);
+    unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);
+    CPPUNIT_ASSERT(h == (unsigned int)15);
+    unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);
+    CPPUNIT_ASSERT(i == (unsigned int)15);
+#ifdef wxLongLong_t
+    wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);
+    CPPUNIT_ASSERT(j == (unsigned int)15);
+#endif
+    wxString k = wxANY_AS(m_anyStringString1, wxString);
+    CPPUNIT_ASSERT(k == "abc");
+    wxString l = wxANY_AS(m_anyCharString1, wxString);
+    const char* cptr = wxANY_AS(m_anyCharString1, const char*);
+    CPPUNIT_ASSERT(l == "abc");
+    CPPUNIT_ASSERT(cptr);
+    wxString m = wxANY_AS(m_anyWcharString1, wxString);
+    const wchar_t* wcptr = wxANY_AS(m_anyWcharString1, const wchar_t*);
+    CPPUNIT_ASSERT(wcptr);
+    CPPUNIT_ASSERT(m == "abc");
+    bool n = wxANY_AS(m_anyBool1, bool);
+    CPPUNIT_ASSERT(n);
+
+    // Make sure the stored float that comes back is -identical-.
+    // So do not use delta comparison here.
+    float o = wxANY_AS(m_anyFloatDouble1, float);
+    CPPUNIT_ASSERT_EQUAL(o, TEST_FLOAT_CONST);
+
+    double p = wxANY_AS(m_anyDoubleDouble1, double);
+    CPPUNIT_ASSERT_EQUAL(p, TEST_DOUBLE_CONST);
+
+    wxUniChar chr = wxANY_AS(m_anyUniChar1, wxUniChar);
+    CPPUNIT_ASSERT(chr == 'A');
+    wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);
+    CPPUNIT_ASSERT(q == m_testDateTime);
+    wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);
+    CPPUNIT_ASSERT(r == dummyWxObjectPointer);
+    void* s = wxANY_AS(m_anyVoidPtr1, void*);
+    CPPUNIT_ASSERT(s == dummyVoidPointer);
+}
+
+void wxAnyTestCase::Null()
+{
+    wxAny a;
+    CPPUNIT_ASSERT(a.IsNull());
+    a = -127;
+    CPPUNIT_ASSERT(a == -127);
+    a.MakeNull();
+    CPPUNIT_ASSERT(a.IsNull());
+}
+
+void wxAnyTestCase::GetAs()
+{
+    //
+    // Test dynamic conversion
+    bool res;
+    long l = 0;
+    short int si = 0;
+    unsigned long ul = 0;
+    wxString s;
+    // Let's test against float instead of double, since the former
+    // is not the native underlying type the code converts to, but
+    // should still work, all the same.
+    float f = 0.0;
+    bool b = false;
+
+    // Conversions from signed long type
+    // The first check should be enough to make sure that the sub-type system
+    // has not failed.
+    res = m_anySignedLong1.GetAs(&si);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(si, 15);
+    res = m_anySignedLong1.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, 15UL);
+    res = m_anySignedLong1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(s == "15");
+    res = m_anySignedLong1.GetAs(&f);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
+    res = m_anySignedLong1.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == true);
+
+    // Conversions from unsigned long type
+    res = m_anyUnsignedLong1.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(15));
+    res = m_anyUnsignedLong1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(s == "15");
+    res = m_anyUnsignedLong1.GetAs(&f);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
+    res = m_anyUnsignedLong1.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == true);
+
+    // Conversions from default "abc" string to other types
+    // should not work.
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));
+    CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));
+
+    // Let's test some other conversions from string that should work.
+    wxAny anyString;
+
+    anyString = "15";
+    res = anyString.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(15));
+    res = anyString.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
+    res = anyString.GetAs(&f);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
+    anyString = "TRUE";
+    res = anyString.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == true);
+    anyString = "0";
+    res = anyString.GetAs(&b);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(b == false);
+
+    // Conversions from bool type
+    res = m_anyBool1.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(1));
+    res = m_anyBool1.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));
+    res = m_anyBool1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(s == "true");
+    CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));
+
+    // Conversions from floating point type
+    res = m_anyDoubleDouble1.GetAs(&l);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT(l == static_cast<signed long>(123));
+    res = m_anyDoubleDouble1.GetAs(&ul);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));
+    res = m_anyDoubleDouble1.GetAs(&s);
+    CPPUNIT_ASSERT(res);
+    double d2;
+    res = s.ToDouble(&d2);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);
+}
+
+
+//
+// Test user data type for wxAnyValueTypeImpl specialization
+// any hand-built wxVariantData. Also for inplace allocation
+// sanity checks.
+//
+
+class MyClass;
+
+static wxVector<MyClass*> gs_myClassInstances;
+
+class MyClass
+{
+public:
+    MyClass( int someValue = 32768 )
+    {
+        Init();
+        m_someValue = someValue;
+    }
+    MyClass( const MyClass& other )
+    {
+        Init();
+        m_someValue = other.m_someValue;
+    }
+    virtual ~MyClass()
+    {
+        for ( size_t i=0; i<gs_myClassInstances.size(); i++ )
+        {
+            if ( gs_myClassInstances[i] == this )
+            {
+                gs_myClassInstances.erase(gs_myClassInstances.begin()+i);
+            }
+        }
+    }
+
+    int GetValue() const
+    {
+        return m_someValue;
+    }
+
+    wxString ToString()
+    {
+        return wxString::Format("%i", m_someValue);
+    }
+
+private:
+    void Init()
+    {
+        // We use this for some sanity checking
+        gs_myClassInstances.push_back(this);
+    }
+
+    int     m_someValue;
+};
+
+
+#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
+}
+
+template<>
+class wxAnyValueTypeImpl<MyClass> :
+    public wxAnyValueTypeImplBase<MyClass>
+{
+    WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+public:
+    wxAnyValueTypeImpl() :
+        wxAnyValueTypeImplBase<MyClass>() { }
+    virtual ~wxAnyValueTypeImpl() { }
+
+    virtual bool ConvertValue(const wxAnyValueBuffer& src,
+                              wxAnyValueType* dstType,
+                              wxAnyValueBuffer& dst) const
+    {
+        MyClass value = GetValue(src);
+
+        if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
+        {
+            wxString s = value.ToString();
+            wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
+        }
+        else
+            return false;
+
+        return true;
+    }
+};
+
+//
+// Following must be placed somewhere in your source code
+WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
+
+void wxAnyTestCase::CustomTemplateSpecialization()
+{
+    // Do only a minimal CheckType() test, as dynamic type conversion already
+    // uses it a lot.
+    bool res;
+    MyClass myObject;
+    wxAny any = myObject;
+
+    CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );
+    MyClass myObject2 = wxANY_AS(any, MyClass);
+    wxUnusedVar(myObject2);
+
+    wxString str;
+    res = any.GetAs(&str);
+    CPPUNIT_ASSERT(res);
+    CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());
+}
+
+void wxAnyTestCase::Misc()
+{
+    // Do some (inplace) allocation sanity checks
+    {
+
+        // Do it inside a scope so we can easily test instance count
+        // afterwards
+        MyClass myObject(15);
+        wxAny any = myObject;
+
+        // There must be two instances - first in myObject,
+        // and second copied in any.
+        CPPUNIT_ASSERT_EQUAL(gs_myClassInstances.size(), 2);
+
+        // Check that it is allocated in-place, as supposed
+        if ( sizeof(MyClass) <= WX_ANY_VALUE_BUFFER_SIZE )
+        {
+            // Memory block of the instance second must be inside the any
+            size_t anyBegin = reinterpret_cast<size_t>(&any);
+            size_t anyEnd = anyBegin + sizeof(wxAny);
+            size_t pos = reinterpret_cast<size_t>(gs_myClassInstances[1]);
+            CPPUNIT_ASSERT( pos >= anyBegin );
+            CPPUNIT_ASSERT( pos < anyEnd );
+        }
+
+        wxAny any2 = any;
+        CPPUNIT_ASSERT( wxANY_AS(any2, MyClass).GetValue() == 15 );
+    }
+
+    // Make sure allocations and deallocations match
+    CPPUNIT_ASSERT_EQUAL(gs_myClassInstances.size(), 0);
+}
+
+#endif // wxUSE_ANY
+