1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/any/anytest.cpp
3 // Purpose: Test the wxAny classes
4 // Author: Jaakko Salli
6 // Copyright: (c) the wxWidgets team
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
19 #include "wx/datetime.h"
20 #include "wx/object.h"
21 #include "wx/vector.h"
25 // ----------------------------------------------------------------------------
27 // ----------------------------------------------------------------------------
29 class wxAnyTestCase
: public CppUnit::TestCase
35 CPPUNIT_TEST_SUITE( wxAnyTestCase
);
36 CPPUNIT_TEST( CheckType
);
37 CPPUNIT_TEST( Equality
);
38 // FIXME: One of these tests might result in heap corruption under PPC
39 // OS X, disable them to at least allow the subsequent tests to
40 // run as otherwise the test program just crashes.
43 CPPUNIT_TEST( GetAs
);
45 CPPUNIT_TEST( wxVariantConversions
);
46 CPPUNIT_TEST( CustomTemplateSpecialization
);
49 CPPUNIT_TEST_SUITE_END();
56 void wxVariantConversions();
57 void CustomTemplateSpecialization();
60 wxDateTime m_testDateTime
;
62 wxAny m_anySignedChar1
;
63 wxAny m_anySignedShort1
;
64 wxAny m_anySignedInt1
;
65 wxAny m_anySignedLong1
;
66 wxAny m_anySignedLongLong1
;
67 wxAny m_anyUnsignedChar1
;
68 wxAny m_anyUnsignedShort1
;
69 wxAny m_anyUnsignedInt1
;
70 wxAny m_anyUnsignedLong1
;
71 wxAny m_anyUnsignedLongLong1
;
72 wxAny m_anyStringString1
;
73 wxAny m_anyCharString1
;
74 wxAny m_anyWcharString1
;
76 wxAny m_anyFloatDouble1
;
77 wxAny m_anyDoubleDouble1
;
78 wxAny m_anyWxObjectPtr1
;
83 wxAny m_anySignedChar2
;
84 wxAny m_anySignedShort2
;
85 wxAny m_anySignedInt2
;
86 wxAny m_anySignedLong2
;
87 wxAny m_anySignedLongLong2
;
88 wxAny m_anyUnsignedChar2
;
89 wxAny m_anyUnsignedShort2
;
90 wxAny m_anyUnsignedInt2
;
91 wxAny m_anyUnsignedLong2
;
92 wxAny m_anyUnsignedLongLong2
;
93 wxAny m_anyStringString2
;
94 wxAny m_anyCharString2
;
95 wxAny m_anyWcharString2
;
97 wxAny m_anyFloatDouble2
;
98 wxAny m_anyDoubleDouble2
;
99 wxAny m_anyWxObjectPtr2
;
101 wxAny m_anyDateTime2
;
103 DECLARE_NO_COPY_CLASS(wxAnyTestCase
)
106 // register in the unnamed registry so that these tests are run by default
107 CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase
);
109 // also include in its own registry so that these tests can be run alone
110 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase
, "wxAnyTestCase" );
112 // Let's use a number with first digit after decimal dot less than 5,
113 // so that we don't have to worry about whether conversion from float
114 // to int truncates or rounds.
115 const float TEST_FLOAT_CONST
= 123.456f
;
116 const double TEST_DOUBLE_CONST
= 123.456;
118 const double FEQ_DELTA
= 0.001;
120 wxObject
* dummyWxObjectPointer
= reinterpret_cast<wxObject
*>(1234);
121 void* dummyVoidPointer
= reinterpret_cast<void*>(1234);
125 // Test both 'creation' methods
126 wxAnyTestCase::wxAnyTestCase()
127 : m_anySignedChar1((signed char)15),
128 m_anySignedShort1((signed short)15),
129 m_anySignedInt1((signed int)15),
130 m_anySignedLong1((signed long)15),
132 m_anySignedLongLong1((wxLongLong_t
)15),
134 m_anyUnsignedChar1((unsigned char)15),
135 m_anyUnsignedShort1((unsigned short)15),
136 m_anyUnsignedInt1((unsigned int)15),
137 m_anyUnsignedLong1((unsigned long)15),
139 m_anyUnsignedLongLong1((wxULongLong_t
)15),
141 m_anyStringString1(wxString("abc")),
142 m_anyCharString1("abc"),
143 m_anyWcharString1(L
"abc"),
145 m_anyFloatDouble1(TEST_FLOAT_CONST
),
146 m_anyDoubleDouble1(TEST_DOUBLE_CONST
),
147 m_anyWxObjectPtr1(dummyWxObjectPointer
),
148 m_anyVoidPtr1(dummyVoidPointer
),
149 m_anyDateTime1(wxDateTime::Now())
151 m_testDateTime
= wxDateTime::Now();
152 m_anySignedChar2
= (signed char)15;
153 m_anySignedShort2
= (signed short)15;
154 m_anySignedInt2
= (signed int)15;
155 m_anySignedLong2
= (signed long)15;
157 m_anySignedLongLong2
= (wxLongLong_t
)15;
159 m_anyUnsignedChar2
= (unsigned char)15;
160 m_anyUnsignedShort2
= (unsigned short)15;
161 m_anyUnsignedInt2
= (unsigned int)15;
162 m_anyUnsignedLong2
= (unsigned long)15;
164 m_anyUnsignedLongLong2
= (wxULongLong_t
)15;
166 m_anyStringString2
= wxString("abc");
167 m_anyCharString2
= "abc";
168 m_anyWcharString2
= L
"abc";
170 m_anyFloatDouble2
= TEST_FLOAT_CONST
;
171 m_anyDoubleDouble2
= TEST_DOUBLE_CONST
;
172 m_anyDateTime2
= m_testDateTime
;
173 m_anyUniChar1
= wxUniChar('A');
174 m_anyWxObjectPtr2
= dummyWxObjectPointer
;
175 m_anyVoidPtr2
= dummyVoidPointer
;
178 void wxAnyTestCase::CheckType()
181 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(nullAny
, wxString
));
183 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(m_anyCharString2
, const char*));
184 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyCharString2
, wxString
));
185 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyCharString2
, const wchar_t*));
186 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(m_anyWcharString2
, const wchar_t*));
187 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyWcharString2
, wxString
));
188 CPPUNIT_ASSERT(!wxANY_CHECK_TYPE(m_anyWcharString2
, const char*));
191 CPPUNIT_ASSERT( m_anyWcharString1
.HasSameType(m_anyWcharString2
) );
192 CPPUNIT_ASSERT( !m_anyWcharString1
.HasSameType(m_anyBool1
) );
195 void wxAnyTestCase::Equality()
198 // Currently this should work
199 CPPUNIT_ASSERT(m_anyUnsignedLong1
== 15L);
200 CPPUNIT_ASSERT(m_anyUnsignedLong1
!= 30L);
201 CPPUNIT_ASSERT(m_anyUnsignedLong1
== 15UL);
202 CPPUNIT_ASSERT(m_anyUnsignedLong1
!= 30UL);
203 CPPUNIT_ASSERT(m_anyStringString1
== wxString("abc"));
204 CPPUNIT_ASSERT(m_anyStringString1
!= wxString("ABC"));
205 CPPUNIT_ASSERT(m_anyStringString1
== "abc");
206 CPPUNIT_ASSERT(m_anyStringString1
!= "ABC");
207 CPPUNIT_ASSERT(m_anyStringString1
== L
"abc");
208 CPPUNIT_ASSERT(m_anyStringString1
!= L
"ABC");
209 CPPUNIT_ASSERT(m_anyBool1
== true);
210 CPPUNIT_ASSERT(m_anyBool1
!= false);
211 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1
, double),
212 wxANY_AS(m_anyDoubleDouble1
, double),
214 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1
, double),
217 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1
, wxObject
*)
218 == dummyWxObjectPointer
);
219 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1
, void*) == dummyVoidPointer
);
221 CPPUNIT_ASSERT(m_anySignedLong2
== 15);
222 CPPUNIT_ASSERT(m_anyStringString2
== wxString("abc"));
223 CPPUNIT_ASSERT(m_anyStringString2
== "abc");
224 CPPUNIT_ASSERT(m_anyStringString2
== L
"abc");
225 CPPUNIT_ASSERT(m_anyBool2
== true);
226 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2
, double),
227 wxANY_AS(m_anyDoubleDouble2
, double),
229 CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2
, double),
232 CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2
, wxObject
*)
233 == dummyWxObjectPointer
);
234 CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2
, void*) == dummyVoidPointer
);
236 // Test sub-type system type compatibility
237 CPPUNIT_ASSERT(m_anySignedShort1
.GetType()->
238 IsSameType(m_anySignedLongLong1
.GetType()));
239 CPPUNIT_ASSERT(m_anyUnsignedShort1
.GetType()->
240 IsSameType(m_anyUnsignedLongLong1
.GetType()));
243 void wxAnyTestCase::As()
246 // Test getting C++ data from wxAny without dynamic conversion
247 signed char a
= wxANY_AS(m_anySignedChar1
, signed char);
248 CPPUNIT_ASSERT(a
== (signed int)15);
249 signed short b
= wxANY_AS(m_anySignedShort1
, signed short);
250 CPPUNIT_ASSERT(b
== (signed int)15);
251 signed int c
= wxANY_AS(m_anySignedInt1
, signed int);
252 CPPUNIT_ASSERT(c
== (signed int)15);
253 signed long d
= wxANY_AS(m_anySignedLong1
, signed long);
254 CPPUNIT_ASSERT(d
== (signed int)15);
256 wxLongLong_t e
= wxANY_AS(m_anySignedLongLong1
, wxLongLong_t
);
257 CPPUNIT_ASSERT(e
== (signed int)15);
259 unsigned char f
= wxANY_AS(m_anyUnsignedChar1
, unsigned char);
260 CPPUNIT_ASSERT(f
== (unsigned int)15);
261 unsigned short g
= wxANY_AS(m_anyUnsignedShort1
, unsigned short);
262 CPPUNIT_ASSERT(g
== (unsigned int)15);
263 unsigned int h
= wxANY_AS(m_anyUnsignedInt1
, unsigned int);
264 CPPUNIT_ASSERT(h
== (unsigned int)15);
265 unsigned long i
= wxANY_AS(m_anyUnsignedLong1
, unsigned long);
266 CPPUNIT_ASSERT(i
== (unsigned int)15);
268 wxULongLong_t j
= wxANY_AS(m_anyUnsignedLongLong1
, wxULongLong_t
);
269 CPPUNIT_ASSERT(j
== (unsigned int)15);
271 wxString k
= wxANY_AS(m_anyStringString1
, wxString
);
272 CPPUNIT_ASSERT(k
== "abc");
273 wxString l
= wxANY_AS(m_anyCharString1
, wxString
);
274 const char* cptr
= wxANY_AS(m_anyCharString1
, const char*);
275 CPPUNIT_ASSERT(l
== "abc");
276 CPPUNIT_ASSERT(cptr
);
277 wxString m
= wxANY_AS(m_anyWcharString1
, wxString
);
278 const wchar_t* wcptr
= wxANY_AS(m_anyWcharString1
, const wchar_t*);
279 CPPUNIT_ASSERT(wcptr
);
280 CPPUNIT_ASSERT(m
== "abc");
281 bool n
= wxANY_AS(m_anyBool1
, bool);
284 // Make sure the stored float that comes back is -identical-.
285 // So do not use delta comparison here.
286 float o
= wxANY_AS(m_anyFloatDouble1
, float);
287 CPPUNIT_ASSERT_EQUAL(o
, TEST_FLOAT_CONST
);
289 double p
= wxANY_AS(m_anyDoubleDouble1
, double);
290 CPPUNIT_ASSERT_EQUAL(p
, TEST_DOUBLE_CONST
);
292 wxUniChar chr
= wxANY_AS(m_anyUniChar1
, wxUniChar
);
293 CPPUNIT_ASSERT(chr
== 'A');
294 wxDateTime q
= wxANY_AS(m_anyDateTime1
, wxDateTime
);
295 CPPUNIT_ASSERT(q
== m_testDateTime
);
296 wxObject
* r
= wxANY_AS(m_anyWxObjectPtr1
, wxObject
*);
297 CPPUNIT_ASSERT(r
== dummyWxObjectPointer
);
298 void* s
= wxANY_AS(m_anyVoidPtr1
, void*);
299 CPPUNIT_ASSERT(s
== dummyVoidPointer
);
302 void wxAnyTestCase::Null()
305 CPPUNIT_ASSERT(a
.IsNull());
307 CPPUNIT_ASSERT(a
== -127);
309 CPPUNIT_ASSERT(a
.IsNull());
312 void wxAnyTestCase::GetAs()
315 // Test dynamic conversion
319 unsigned long ul
= 0;
321 // Let's test against float instead of double, since the former
322 // is not the native underlying type the code converts to, but
323 // should still work, all the same.
327 // Conversions from signed long type
328 // The first check should be enough to make sure that the sub-type system
330 res
= m_anySignedLong1
.GetAs(&si
);
332 CPPUNIT_ASSERT_EQUAL(si
, 15);
333 res
= m_anySignedLong1
.GetAs(&ul
);
335 CPPUNIT_ASSERT_EQUAL(ul
, 15UL);
336 res
= m_anySignedLong1
.GetAs(&s
);
338 CPPUNIT_ASSERT(s
== "15");
339 res
= m_anySignedLong1
.GetAs(&f
);
341 CPPUNIT_ASSERT_DOUBLES_EQUAL(f
, 15.0, FEQ_DELTA
);
342 res
= m_anySignedLong1
.GetAs(&b
);
344 CPPUNIT_ASSERT(b
== true);
346 // Conversions from unsigned long type
347 res
= m_anyUnsignedLong1
.GetAs(&l
);
349 CPPUNIT_ASSERT(l
== static_cast<signed long>(15));
350 res
= m_anyUnsignedLong1
.GetAs(&s
);
352 CPPUNIT_ASSERT(s
== "15");
353 res
= m_anyUnsignedLong1
.GetAs(&f
);
355 CPPUNIT_ASSERT_DOUBLES_EQUAL(f
, 15.0, FEQ_DELTA
);
356 res
= m_anyUnsignedLong1
.GetAs(&b
);
358 CPPUNIT_ASSERT(b
== true);
360 // Conversions from default "abc" string to other types
362 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&l
));
363 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&ul
));
364 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&f
));
365 CPPUNIT_ASSERT(!m_anyStringString1
.GetAs(&b
));
367 // Let's test some other conversions from string that should work.
371 res
= anyString
.GetAs(&l
);
373 CPPUNIT_ASSERT(l
== static_cast<signed long>(15));
374 res
= anyString
.GetAs(&ul
);
376 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(15));
377 res
= anyString
.GetAs(&f
);
379 CPPUNIT_ASSERT_DOUBLES_EQUAL(f
, 15.0, FEQ_DELTA
);
381 res
= anyString
.GetAs(&b
);
383 CPPUNIT_ASSERT(b
== true);
385 res
= anyString
.GetAs(&b
);
387 CPPUNIT_ASSERT(b
== false);
389 // Conversions from bool type
390 res
= m_anyBool1
.GetAs(&l
);
392 CPPUNIT_ASSERT(l
== static_cast<signed long>(1));
393 res
= m_anyBool1
.GetAs(&ul
);
395 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(1));
396 res
= m_anyBool1
.GetAs(&s
);
398 CPPUNIT_ASSERT(s
== "true");
399 CPPUNIT_ASSERT(!m_anyBool1
.GetAs(&f
));
401 // Conversions from floating point type
402 res
= m_anyDoubleDouble1
.GetAs(&l
);
404 CPPUNIT_ASSERT(l
== static_cast<signed long>(123));
405 res
= m_anyDoubleDouble1
.GetAs(&ul
);
407 CPPUNIT_ASSERT_EQUAL(ul
, static_cast<unsigned long>(123));
408 res
= m_anyDoubleDouble1
.GetAs(&s
);
411 res
= s
.ToDouble(&d2
);
413 CPPUNIT_ASSERT_DOUBLES_EQUAL(d2
, TEST_FLOAT_CONST
, FEQ_DELTA
);
418 // Test user data type for wxAnyValueTypeImpl specialization
419 // any hand-built wxVariantData. Also for inplace allocation
425 static wxVector
<MyClass
*> gs_myClassInstances
;
430 MyClass( int someValue
= 32768 )
433 m_someValue
= someValue
;
435 MyClass( const MyClass
& other
)
438 m_someValue
= other
.m_someValue
;
442 for ( size_t i
=0; i
<gs_myClassInstances
.size(); i
++ )
444 if ( gs_myClassInstances
[i
] == this )
446 gs_myClassInstances
.erase(gs_myClassInstances
.begin()+i
);
458 return wxString::Format("%i", m_someValue
);
464 // We use this for some sanity checking
465 gs_myClassInstances
.push_back(this);
474 // For testing purposes, create dummy variant data implementation
475 // that does not have wxAny conversion code
476 class wxMyVariantData
: public wxVariantData
479 wxMyVariantData(const MyClass
& value
)
484 virtual bool Eq(wxVariantData
& WXUNUSED(data
)) const
489 // What type is it? Return a string name.
490 virtual wxString
GetType() const { return "MyClass"; }
492 virtual wxVariantData
* Clone() const
494 return new wxMyVariantData(m_value
);
501 #endif // wxUSE_VARIANT
504 void wxAnyTestCase::wxVariantConversions()
508 // Test various conversions to and from wxVariant
512 // Prepare wxVariants
513 wxVariant
vLong(123L);
514 wxVariant
vString("ABC");
515 wxVariant
vDouble(TEST_FLOAT_CONST
);
516 wxVariant
vBool((bool)true);
517 wxVariant
vChar('A');
519 wxVariant
vLongLong(wxLongLong(wxLL(0xAABBBBCCCC)));
520 wxVariant
vULongLong(wxULongLong(wxULL(123456)));
522 wxArrayString arrstr
;
523 arrstr
.push_back("test string");
524 wxVariant
vArrayString(arrstr
);
525 wxVariant
vDateTime(m_testDateTime
);
526 wxVariant
vVoidPtr(dummyVoidPointer
);
527 wxVariant
vCustomType(new wxMyVariantData(MyClass(101)));
534 // Convert to wxAnys, and then back to wxVariants
538 CPPUNIT_ASSERT(any
== 123L);
539 res
= any
.GetAs(&variant
);
541 CPPUNIT_ASSERT(variant
== 123L);
543 // Make sure integer variant has correct type information
544 CPPUNIT_ASSERT(variant
.GetLong() == 123);
545 CPPUNIT_ASSERT(variant
.GetType() == "long");
547 // Unsigned long wxAny should convert to "ulonglong" wxVariant
549 res
= any
.GetAs(&variant
);
551 CPPUNIT_ASSERT(variant
.GetType() == "ulonglong");
552 CPPUNIT_ASSERT(variant
.GetLong() == 1000);
555 CPPUNIT_ASSERT(any
== "ABC");
556 res
= any
.GetAs(&variant
);
558 CPPUNIT_ASSERT(variant
.GetString() == "ABC");
560 // Must be able to build string wxVariant from wxAny built from
563 res
= any
.GetAs(&variant
);
565 CPPUNIT_ASSERT(variant
.GetType() == "string");
566 CPPUNIT_ASSERT(variant
.GetString() == "ABC");
568 res
= any
.GetAs(&variant
);
570 CPPUNIT_ASSERT(variant
.GetType() == "string");
572 CPPUNIT_ASSERT(variant
.GetString() == L
"ABC");
576 double d
= wxANY_AS(any
, double);
577 CPPUNIT_ASSERT_DOUBLES_EQUAL(d
, TEST_FLOAT_CONST
, FEQ_DELTA
);
578 res
= any
.GetAs(&variant
);
580 CPPUNIT_ASSERT_DOUBLES_EQUAL(variant
.GetDouble(),
585 CPPUNIT_ASSERT(wxANY_AS(any
, bool) == true);
586 res
= any
.GetAs(&variant
);
588 CPPUNIT_ASSERT(variant
.GetBool() == true);
591 //CPPUNIT_ASSERT(wxANY_AS(any, wxUniChar) == 'A');
592 res
= any
.GetAs(&variant
);
594 CPPUNIT_ASSERT(variant
.GetChar() == 'A');
597 any
= wxAny(vLongLong
);
598 CPPUNIT_ASSERT(any
== wxLL(0xAABBBBCCCC));
599 res
= any
.GetAs(&variant
);
601 CPPUNIT_ASSERT(variant
.GetType() == "longlong");
602 CPPUNIT_ASSERT(variant
.GetLongLong() == wxLongLong(wxLL(0xAABBBBCCCC)));
604 #if LONG_MAX == wxINT64_MAX
605 // As a sanity check, test that wxVariant of type 'long' converts
606 // seamlessly to 'longlong' (on some 64-bit systems)
608 res
= any
.GetAs(&variant
);
609 CPPUNIT_ASSERT(variant
.GetLongLong() == wxLongLong(wxLL(0xAABBBBCCCC)));
612 any
= wxAny(vULongLong
);
613 CPPUNIT_ASSERT(any
== wxLL(123456));
614 res
= any
.GetAs(&variant
);
616 CPPUNIT_ASSERT(variant
.GetType() == "ulonglong");
617 CPPUNIT_ASSERT(variant
.GetULongLong() == wxULongLong(wxULL(123456)));
620 // Cannot test equality for the rest, just test that they convert
622 any
= wxAny(vArrayString
);
623 res
= any
.GetAs(&variant
);
625 wxArrayString arrstr2
= variant
.GetArrayString();
626 CPPUNIT_ASSERT(arrstr2
== arrstr
);
628 any
= m_testDateTime
;
629 CPPUNIT_ASSERT(wxANY_AS(any
, wxDateTime
) == m_testDateTime
);
630 any
= wxAny(vDateTime
);
631 CPPUNIT_ASSERT(wxANY_AS(any
, wxDateTime
) == m_testDateTime
);
632 res
= any
.GetAs(&variant
);
634 CPPUNIT_ASSERT(variant
== m_testDateTime
);
636 any
= wxAny(vVoidPtr
);
637 res
= any
.GetAs(&variant
);
639 CPPUNIT_ASSERT(variant
.GetVoidPtr() == dummyVoidPointer
);
642 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any
, wxAnyList
));
643 wxAnyList anyList
= wxANY_AS(any
, wxAnyList
);
644 CPPUNIT_ASSERT(anyList
.GetCount() == 2);
645 CPPUNIT_ASSERT(wxANY_AS((*anyList
[0]), int) == 15);
646 CPPUNIT_ASSERT(wxANY_AS((*anyList
[1]), wxString
) == "abc");
647 res
= any
.GetAs(&variant
);
649 CPPUNIT_ASSERT(variant
.GetType() == "list");
650 CPPUNIT_ASSERT(variant
.GetCount() == 2);
651 CPPUNIT_ASSERT(variant
[0].GetLong() == 15);
652 CPPUNIT_ASSERT(variant
[1].GetString() == "abc");
654 any
= wxAny(vCustomType
);
655 CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any
, wxVariantData
*));
656 res
= any
.GetAs(&variant
);
658 CPPUNIT_ASSERT(variant
.GetType() == "MyClass");
660 #endif // wxUSE_VARIANT
664 class wxAnyValueTypeImpl
<MyClass
> :
665 public wxAnyValueTypeImplBase
<MyClass
>
667 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<MyClass
>)
669 wxAnyValueTypeImpl() :
670 wxAnyValueTypeImplBase
<MyClass
>() { }
671 virtual ~wxAnyValueTypeImpl() { }
673 virtual bool ConvertValue(const wxAnyValueBuffer
& src
,
674 wxAnyValueType
* dstType
,
675 wxAnyValueBuffer
& dst
) const
677 MyClass value
= GetValue(src
);
679 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType
, wxString
) )
681 wxString s
= value
.ToString();
682 wxAnyValueTypeImpl
<wxString
>::SetValue(s
, dst
);
692 // Following must be placed somewhere in your source code
693 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl
<MyClass
>)
695 void wxAnyTestCase::CustomTemplateSpecialization()
697 // Do only a minimal CheckType() test, as dynamic type conversion already
701 wxAny any
= myObject
;
703 CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any
, MyClass
) );
704 MyClass myObject2
= wxANY_AS(any
, MyClass
);
705 wxUnusedVar(myObject2
);
708 res
= any
.GetAs(&str
);
710 CPPUNIT_ASSERT_EQUAL(str
, myObject
.ToString());
713 void wxAnyTestCase::Misc()
715 // Do some (inplace) allocation sanity checks
718 // Do it inside a scope so we can easily test instance count
720 MyClass
myObject(15);
721 wxAny any
= myObject
;
723 // There must be two instances - first in myObject,
724 // and second copied in any.
725 CPPUNIT_ASSERT_EQUAL(gs_myClassInstances
.size(), 2);
727 // Check that it is allocated in-place, as supposed
728 if ( sizeof(MyClass
) <= WX_ANY_VALUE_BUFFER_SIZE
)
730 // Memory block of the instance second must be inside the any
731 size_t anyBegin
= reinterpret_cast<size_t>(&any
);
732 size_t anyEnd
= anyBegin
+ sizeof(wxAny
);
733 size_t pos
= reinterpret_cast<size_t>(gs_myClassInstances
[1]);
734 CPPUNIT_ASSERT( pos
>= anyBegin
);
735 CPPUNIT_ASSERT( pos
< anyEnd
);
739 CPPUNIT_ASSERT( wxANY_AS(any2
, MyClass
).GetValue() == 15 );
742 // Make sure allocations and deallocations match
743 CPPUNIT_ASSERT_EQUAL(gs_myClassInstances
.size(), 0);