]> git.saurik.com Git - wxWidgets.git/blame - include/wx/xtitypes.h
adding new files for xti merge
[wxWidgets.git] / include / wx / xtitypes.h
CommitLineData
cc3977bf
SC
1/////////////////////////////////////////////////////////////////////////////\r
2// Name: wx/xtitypes.h\r
3// Purpose: enum, set, basic types support\r
4// Author: Stefan Csomor\r
5// Modified by: Francesco Montorsi\r
6// Created: 27/07/03\r
7// RCS-ID: $Id: xti.h 47299 2007-07-10 15:58:27Z FM $\r
8// Copyright: (c) 1997 Julian Smart\r
9// (c) 2003 Stefan Csomor\r
10// Licence: wxWindows licence\r
11/////////////////////////////////////////////////////////////////////////////\r
12\r
13#ifndef _XTITYPES_H_\r
14#define _XTITYPES_H_\r
15\r
16#include "wx/defs.h"\r
17\r
18#if wxUSE_EXTENDED_RTTI\r
19\r
20#include "wx/string.h"\r
21#include "wx/hashmap.h"\r
22#include "wx/arrstr.h"\r
23#include "wx/flags.h"\r
24#include "wx/intl.h"\r
25#include "wx/log.h"\r
26#include <typeinfo>\r
27\r
28class WXDLLIMPEXP_BASE wxClassInfo;\r
29\r
30// ----------------------------------------------------------------------------\r
31// Enum Support\r
32//\r
33// In the header files XTI requires no change from pure c++ code, however in the\r
34// implementation, an enum needs to be enumerated eg:\r
35//\r
36// wxBEGIN_ENUM( wxFlavor )\r
37// wxENUM_MEMBER( Vanilla )\r
38// wxENUM_MEMBER( Chocolate )\r
39// wxENUM_MEMBER( Strawberry )\r
40// wxEND_ENUM( wxFlavor )\r
41// ----------------------------------------------------------------------------\r
42\r
43struct WXDLLIMPEXP_BASE wxEnumMemberData\r
44{\r
45 const wxChar* m_name;\r
46 int m_value;\r
47};\r
48\r
49class WXDLLIMPEXP_BASE wxEnumData\r
50{\r
51public:\r
52 wxEnumData( wxEnumMemberData* data );\r
53\r
54 // returns true if the member has been found and sets the int value\r
55 // pointed to accordingly (if ptr != null )\r
56 // if not found returns false, value left unchanged\r
57 bool HasEnumMemberValue( const wxChar *name, int *value = NULL ) const;\r
58\r
59 // returns the value of the member, if not found in debug mode an\r
60 // assert is issued, in release 0 is returned\r
61 int GetEnumMemberValue(const wxChar *name ) const;\r
62\r
63 // returns the name of the enum member having the passed in value\r
64 // returns an emtpy string if not found\r
65 const wxChar *GetEnumMemberName(int value) const;\r
66\r
67 // returns the number of members in this enum\r
68 int GetEnumCount() const { return m_count; }\r
69\r
70 // returns the value of the nth member\r
71 int GetEnumMemberValueByIndex( int n ) const;\r
72\r
73 // returns the value of the nth member\r
74 const wxChar *GetEnumMemberNameByIndex( int n ) const;\r
75\r
76private:\r
77 wxEnumMemberData *m_members;\r
78 int m_count;\r
79};\r
80\r
81#define wxBEGIN_ENUM( e ) \\r
82 wxEnumMemberData s_enumDataMembers##e[] = {\r
83\r
84#define wxENUM_MEMBER( v ) { wxT(#v), v },\r
85\r
86#define wxEND_ENUM( e ) \\r
87 { NULL, 0 } }; \\r
88 wxEnumData s_enumData##e( s_enumDataMembers##e ); \\r
89 wxEnumData *wxGetEnumData(e) { return &s_enumData##e; } \\r
90 template<> void wxStringReadValue(const wxString& s, e &data ) \\r
91 { data = (e) s_enumData##e.GetEnumMemberValue(s); } \\r
92 template<> void wxStringWriteValue(wxString &s, const e &data ) \\r
93 { s = s_enumData##e.GetEnumMemberName((int)data); } \\r
94 void FromLong##e( long data, wxVariantBase& result ) \\r
95 { result = wxVariantBase((e)data); } \\r
96 void ToLong##e( const wxVariantBase& data, long &result ) \\r
97 { result = (long) data.wxTEMPLATED_MEMBER_CALL(Get, e); } \\r
98 \\r
99 wxTO_STRING_IMP( e ) \\r
100 wxFROM_STRING_IMP( e ) \\r
101 wxEnumTypeInfo s_typeInfo##e(wxT_ENUM, &s_enumData##e, \\r
102 &wxTO_STRING( e ), &wxFROM_STRING( e ), &ToLong##e, \\r
103 &FromLong##e, typeid(e).name() );\r
104\r
105\r
106// ----------------------------------------------------------------------------\r
107// Set Support\r
108//\r
109// in the header :\r
110//\r
111// enum wxFlavor\r
112// {\r
113// Vanilla,\r
114// Chocolate,\r
115// Strawberry,\r
116// };\r
117//\r
118// typedef wxBitset<wxFlavor> wxCoupe;\r
119//\r
120// in the implementation file :\r
121//\r
122// wxBEGIN_ENUM( wxFlavor )\r
123// wxENUM_MEMBER( Vanilla )\r
124// wxENUM_MEMBER( Chocolate )\r
125// wxENUM_MEMBER( Strawberry )\r
126// wxEND_ENUM( wxFlavor )\r
127//\r
128// wxIMPLEMENT_SET_STREAMING( wxCoupe, wxFlavor )\r
129//\r
130// implementation note: no partial specialization for streaming, but a delegation \r
131// to a different class\r
132//\r
133// ----------------------------------------------------------------------------\r
134\r
135// in order to remove dependancy on string tokenizer\r
136void WXDLLIMPEXP_BASE wxSetStringToArray( const wxString &s, wxArrayString &array );\r
137\r
138template<typename e>\r
139void wxSetFromString(const wxString &s, wxBitset<e> &data )\r
140{\r
141 wxEnumData* edata = wxGetEnumData((e) 0);\r
142 data.reset();\r
143\r
144 wxArrayString array;\r
145 wxSetStringToArray( s, array );\r
146 wxString flag;\r
147 for ( int i = 0; i < array.Count(); ++i )\r
148 {\r
149 flag = array[i];\r
150 int ivalue;\r
151 if ( edata->HasEnumMemberValue( flag, &ivalue ) )\r
152 {\r
153 data.set( (e) ivalue );\r
154 }\r
155 }\r
156}\r
157\r
158template<typename e>\r
159void wxSetToString( wxString &s, const wxBitset<e> &data )\r
160{\r
161 wxEnumData* edata = wxGetEnumData((e) 0);\r
162 int count = edata->GetEnumCount();\r
163 int i;\r
164 s.Clear();\r
165 for ( i = 0; i < count; i++ )\r
166 {\r
167 e value = (e) edata->GetEnumMemberValueByIndex(i);\r
168 if ( data.test( value ) )\r
169 {\r
170 // this could also be done by the templated calls\r
171 if ( !s.empty() )\r
172 s += wxT("|");\r
173 s += edata->GetEnumMemberNameByIndex(i);\r
174 }\r
175 }\r
176}\r
177\r
178#define wxIMPLEMENT_SET_STREAMING(SetName,e) \\r
179 template<> void wxStringReadValue(const wxString &s, wxBitset<e> &data ) \\r
180 { wxSetFromString( s, data ); } \\r
181 template<> void wxStringWriteValue( wxString &s, const wxBitset<e> &data ) \\r
182 { wxSetToString( s, data ); } \\r
183 void FromLong##SetName( long data, wxVariantBase& result ) \\r
184 { result = wxVariantBase(SetName((unsigned long)data)); } \\r
185 void ToLong##SetName( const wxVariantBase& data, long &result ) \\r
186 { result = (long) data.wxTEMPLATED_MEMBER_CALL(Get, SetName).to_ulong(); } \\r
187 wxTO_STRING_IMP( SetName ) \\r
188 wxFROM_STRING_IMP( SetName ) \\r
189 wxEnumTypeInfo s_typeInfo##SetName(wxT_SET, &s_enumData##e, \\r
190 &wxTO_STRING( SetName ), &wxFROM_STRING( SetName ), \\r
191 &ToLong##SetName, &FromLong##SetName, typeid(SetName).name() );\r
192\r
193template<typename e>\r
194void wxFlagsFromString(const wxString &s, e &data )\r
195{\r
196 wxEnumData* edata = wxGetEnumData((e*) 0);\r
197 data.m_data = 0;\r
198\r
199 wxArrayString array;\r
200 wxSetStringToArray( s, array );\r
201 wxString flag;\r
202 for ( size_t i = 0; i < array.Count(); ++i )\r
203 {\r
204 flag = array[i];\r
205 int ivalue;\r
206 if ( edata->HasEnumMemberValue( flag, &ivalue ) )\r
207 {\r
208 data.m_data |= ivalue;\r
209 }\r
210 }\r
211}\r
212\r
213template<typename e>\r
214void wxFlagsToString( wxString &s, const e& data )\r
215{\r
216 wxEnumData* edata = wxGetEnumData((e*) 0);\r
217 int count = edata->GetEnumCount();\r
218 int i;\r
219 s.Clear();\r
220 long dataValue = data.m_data;\r
221 for ( i = 0; i < count; i++ )\r
222 {\r
223 int value = edata->GetEnumMemberValueByIndex(i);\r
224 // make this to allow for multi-bit constants to work\r
225 if ( value && ( dataValue & value ) == value )\r
226 {\r
227 // clear the flags we just set\r
228 dataValue &= ~value;\r
229 // this could also be done by the templated calls\r
230 if ( !s.empty() )\r
231 s +=wxT("|");\r
232 s += edata->GetEnumMemberNameByIndex(i);\r
233 }\r
234 }\r
235}\r
236\r
237#define wxBEGIN_FLAGS( e ) \\r
238 wxEnumMemberData s_enumDataMembers##e[] = {\r
239\r
240#define wxFLAGS_MEMBER( v ) { wxT(#v), v },\r
241\r
242#define wxEND_FLAGS( e ) \\r
243 { NULL, 0 } }; \\r
244 wxEnumData s_enumData##e( s_enumDataMembers##e ); \\r
245 wxEnumData *wxGetEnumData(e*) { return &s_enumData##e; } \\r
246 template<> void wxStringReadValue(const wxString &s, e &data ) \\r
247 { wxFlagsFromString<e>( s, data ); } \\r
248 template<> void wxStringWriteValue( wxString &s, const e& data ) \\r
249 { wxFlagsToString<e>( s, data ); } \\r
250 void FromLong##e( long data, wxVariantBase& result ) \\r
251 { result = wxVariantBase(e(data)); } \\r
252 void ToLong##e( const wxVariantBase& data, long &result ) \\r
253 { result = (long) data.wxTEMPLATED_MEMBER_CALL(Get, e).m_data; } \\r
254 wxTO_STRING_IMP( e ) \\r
255 wxFROM_STRING_IMP( e ) \\r
256 wxEnumTypeInfo s_typeInfo##e(wxT_SET, &s_enumData##e, \\r
257 &wxTO_STRING( e ), &wxFROM_STRING( e ), &ToLong##e, \\r
258 &FromLong##e, typeid(e).name() );\r
259\r
260// ----------------------------------------------------------------------------\r
261// Type Information\r
262// ----------------------------------------------------------------------------\r
263\r
264// All data exposed by the RTTI is characterized using the following classes.\r
265// The first characterization is done by wxTypeKind. All enums up to and including\r
266// wxT_CUSTOM represent so called simple types. These cannot be divided any further.\r
267// They can be converted to and from wxStrings, that's all.\r
268// Other wxTypeKinds can instead be splitted recursively into smaller parts until\r
269// the simple types are reached.\r
270\r
271enum wxTypeKind\r
272{\r
273 wxT_VOID = 0, // unknown type\r
274 wxT_BOOL,\r
275 wxT_CHAR,\r
276 wxT_UCHAR,\r
277 wxT_INT,\r
278 wxT_UINT,\r
279 wxT_LONG,\r
280 wxT_ULONG,\r
281 wxT_FLOAT,\r
282 wxT_DOUBLE,\r
283 wxT_STRING, // must be wxString\r
284 wxT_SET, // must be wxBitset<> template\r
285 wxT_ENUM,\r
286 wxT_CUSTOM, // user defined type (e.g. wxPoint)\r
287\r
288 wxT_LAST_SIMPLE_TYPE_KIND = wxT_CUSTOM,\r
289\r
290 wxT_OBJECT_PTR, // object reference\r
291 wxT_OBJECT, // embedded object\r
292 wxT_COLLECTION, // collection\r
293\r
294 wxT_DELEGATE, // for connecting against an event source\r
295\r
296 wxT_LAST_TYPE_KIND = wxT_DELEGATE // sentinel for bad data, asserts, debugging\r
297};\r
298\r
299class WXDLLIMPEXP_BASE wxVariantBase;\r
300class WXDLLIMPEXP_BASE wxTypeInfo;\r
301\r
302WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxTypeInfo*, wxTypeInfoMap, class WXDLLIMPEXP_BASE );\r
303\r
304class WXDLLIMPEXP_BASE wxTypeInfo\r
305{\r
306public:\r
307 typedef void (*wxVariant2StringFnc)( const wxVariantBase& data, wxString &result );\r
308 typedef void (*wxString2VariantFnc)( const wxString& data, wxVariantBase &result );\r
309\r
310 wxTypeInfo(wxTypeKind kind,\r
311 wxVariant2StringFnc to = NULL, wxString2VariantFnc from = NULL,\r
312 const wxString &name = wxEmptyString):\r
313 m_toString(to), m_fromString(from), m_kind(kind), m_name(name)\r
314 {\r
315 Register();\r
316 }\r
317#if wxUSE_UNICODE\r
318 wxTypeInfo(wxTypeKind kind,\r
319 wxVariant2StringFnc to, wxString2VariantFnc from,\r
320 const char *name):\r
321 m_toString(to), m_fromString(from), m_kind(kind), \r
322 m_name(wxString::FromAscii(name))\r
323 {\r
324 Register();\r
325 }\r
326#endif\r
327\r
328 virtual ~wxTypeInfo()\r
329 {\r
330 Unregister();\r
331 }\r
332\r
333 // return the kind of this type (wxT_... constants)\r
334 wxTypeKind GetKind() const { return m_kind; }\r
335\r
336 // returns the unique name of this type\r
337 const wxString& GetTypeName() const { return m_name; }\r
338\r
339 // is this type a delegate type\r
340 bool IsDelegateType() const { return m_kind == wxT_DELEGATE; }\r
341\r
342 // is this type a custom type\r
343 bool IsCustomType() const { return m_kind == wxT_CUSTOM; }\r
344\r
345 // is this type an object type\r
346 bool IsObjectType() const { return m_kind == wxT_OBJECT || m_kind == wxT_OBJECT_PTR; }\r
347\r
348 // can the content of this type be converted to and from strings ?\r
349 bool HasStringConverters() const { return m_toString != NULL && m_fromString != NULL; }\r
350\r
351 // convert a wxVariantBase holding data of this type into a string\r
352 void ConvertToString( const wxVariantBase& data, wxString &result ) const\r
353 { \r
354 if ( m_toString ) \r
355 (*m_toString)( data, result ); \r
356 else \r
357 wxLogError( wxGetTranslation(_T("String conversions not supported")) ); \r
358 }\r
359\r
360 // convert a string into a wxVariantBase holding the corresponding data in this type\r
361 void ConvertFromString( const wxString& data, wxVariantBase &result ) const\r
362 { \r
363 if( m_fromString ) \r
364 (*m_fromString)( data, result ); \r
365 else \r
366 wxLogError( wxGetTranslation(_T("String conversions not supported")) ); \r
367 }\r
368\r
369 // statics:\r
370\r
371#if wxUSE_UNICODE\r
372 static wxTypeInfo *FindType(const char *typeName) \r
373 { return FindType( wxString::FromAscii(typeName) ); }\r
374#endif\r
375 static wxTypeInfo *FindType(const wxChar *typeName);\r
376 static wxTypeInfo *FindType(const wxString& typeName)\r
377 {\r
378#if wxUSE_UNICODE\r
379 return FindType( typeName.wchar_str() );\r
380#else\r
381 return FindType( typeName.char_str() );\r
382#endif\r
383 }\r
384\r
385private:\r
386 void Register();\r
387 void Unregister();\r
388\r
389 wxVariant2StringFnc m_toString;\r
390 wxString2VariantFnc m_fromString;\r
391\r
392 wxTypeKind m_kind;\r
393 wxString m_name;\r
394\r
395 // the static list of all types we know about\r
396 static wxTypeInfoMap* ms_typeTable;\r
397};\r
398\r
399class WXDLLIMPEXP_BASE wxBuiltInTypeInfo : public wxTypeInfo\r
400{\r
401public:\r
402 wxBuiltInTypeInfo( wxTypeKind kind, wxVariant2StringFnc to = NULL, \r
403 wxString2VariantFnc from = NULL, \r
404 const wxString &name = wxEmptyString ) :\r
405 wxTypeInfo( kind, to, from, name )\r
406 { wxASSERT_MSG( GetKind() < wxT_SET, wxT("Illegal Kind for Base Type") ); }\r
407\r
408#if wxUSE_UNICODE\r
409 wxBuiltInTypeInfo( wxTypeKind kind, wxVariant2StringFnc to, \r
410 wxString2VariantFnc from , const char *name ) :\r
411 wxTypeInfo( kind, to, from, name )\r
412 { wxASSERT_MSG( GetKind() < wxT_SET, wxT("Illegal Kind for Base Type") ); }\r
413#endif\r
414};\r
415\r
416class WXDLLIMPEXP_BASE wxCustomTypeInfo : public wxTypeInfo\r
417{\r
418public:\r
419 wxCustomTypeInfo( const wxString &name, wxVariant2StringFnc to, \r
420 wxString2VariantFnc from ) :\r
421 wxTypeInfo( wxT_CUSTOM, to, from, name )\r
422 {}\r
423\r
424#if wxUSE_UNICODE\r
425 wxCustomTypeInfo( const char *name , wxVariant2StringFnc to, \r
426 wxString2VariantFnc from ) :\r
427 wxTypeInfo( wxT_CUSTOM, to, from, name )\r
428 {}\r
429#endif\r
430};\r
431\r
432class WXDLLIMPEXP_BASE wxEnumTypeInfo : public wxTypeInfo\r
433{\r
434public:\r
435 typedef void (*converterToLong_t)( const wxVariantBase& data, long &result );\r
436 typedef void (*converterFromLong_t)( long data, wxVariantBase &result );\r
437\r
438 wxEnumTypeInfo( wxTypeKind kind, wxEnumData* enumInfo, wxVariant2StringFnc to,\r
439 wxString2VariantFnc from, converterToLong_t toLong,\r
440 converterFromLong_t fromLong, const wxString &name ) :\r
441 wxTypeInfo( kind, to, from, name ), m_toLong( toLong ), m_fromLong( fromLong )\r
442 { \r
443 wxASSERT_MSG( kind == wxT_ENUM || kind == wxT_SET,\r
444 wxT("Illegal Kind for Enum Type")); \r
445 m_enumInfo = enumInfo; \r
446 }\r
447\r
448#if wxUSE_UNICODE\r
449 wxEnumTypeInfo( wxTypeKind kind, wxEnumData* enumInfo, wxVariant2StringFnc to,\r
450 wxString2VariantFnc from, converterToLong_t toLong,\r
451 converterFromLong_t fromLong, const char * name ) :\r
452 wxTypeInfo( kind, to, from, name ), m_toLong( toLong ), m_fromLong( fromLong )\r
453 {\r
454 wxASSERT_MSG( kind == wxT_ENUM || kind == wxT_SET, \r
455 wxT("Illegal Kind for Enum Type")); \r
456 m_enumInfo = enumInfo; \r
457 }\r
458#endif\r
459 const wxEnumData* GetEnumData() const { return m_enumInfo; }\r
460\r
461 // convert a wxVariantBase holding data of this type into a long\r
462 void ConvertToLong( const wxVariantBase& data, long &result ) const\r
463 { \r
464 if( m_toLong ) \r
465 (*m_toLong)( data, result ); \r
466 else \r
467 wxLogError( wxGetTranslation(_T("Long Conversions not supported")) ); \r
468 }\r
469\r
470 // convert a long into a wxVariantBase holding the corresponding data in this type\r
471 void ConvertFromLong( long data, wxVariantBase &result ) const\r
472 { \r
473 if( m_fromLong ) \r
474 (*m_fromLong)( data, result ); \r
475 else \r
476 wxLogError( wxGetTranslation(_T("Long Conversions not supported")) ); \r
477 }\r
478\r
479private:\r
480 converterToLong_t m_toLong;\r
481 converterFromLong_t m_fromLong;\r
482\r
483 wxEnumData *m_enumInfo; // Kind == wxT_ENUM or Kind == wxT_SET\r
484};\r
485\r
486class WXDLLIMPEXP_BASE wxClassTypeInfo : public wxTypeInfo\r
487{\r
488public:\r
489 wxClassTypeInfo( wxTypeKind kind, wxClassInfo* classInfo, \r
490 wxVariant2StringFnc to = NULL, wxString2VariantFnc from = NULL, \r
491 const wxString &name = wxEmptyString);\r
492\r
493#if wxUSE_UNICODE\r
494 wxClassTypeInfo( wxTypeKind kind, wxClassInfo* classInfo, wxVariant2StringFnc to,\r
495 wxString2VariantFnc from , const char *name );\r
496#endif\r
497\r
498 const wxClassInfo *GetClassInfo() const { return m_classInfo; }\r
499\r
500private:\r
501 wxClassInfo *m_classInfo; // Kind == wxT_OBJECT - could be NULL\r
502};\r
503\r
504class WXDLLIMPEXP_BASE wxCollectionTypeInfo : public wxTypeInfo\r
505{\r
506public:\r
507 wxCollectionTypeInfo( const wxString &elementName, wxVariant2StringFnc to,\r
508 wxString2VariantFnc from , const wxString &name) :\r
509 wxTypeInfo( wxT_COLLECTION, to, from, name )\r
510 { m_elementTypeName = elementName; m_elementType = NULL; }\r
511\r
512#if wxUSE_UNICODE\r
513 wxCollectionTypeInfo( const char *elementName, wxVariant2StringFnc to, \r
514 wxString2VariantFnc from , const char *name ) :\r
515 wxTypeInfo( wxT_COLLECTION, to, from, name )\r
516 { m_elementTypeName = wxString::FromAscii( elementName ); m_elementType = NULL; }\r
517#endif\r
518\r
519 const wxTypeInfo* GetElementType() const\r
520 {\r
521 if ( m_elementType == NULL )\r
522 m_elementType = wxTypeInfo::FindType( m_elementTypeName );\r
523 return m_elementType; \r
524 }\r
525\r
526private:\r
527 mutable wxTypeInfo * m_elementType;\r
528 wxString m_elementTypeName;\r
529};\r
530\r
531class WXDLLIMPEXP_BASE wxEventSourceTypeInfo : public wxTypeInfo\r
532{\r
533public:\r
534 wxEventSourceTypeInfo( int eventType, wxClassInfo* eventClass, \r
535 wxVariant2StringFnc to = NULL, \r
536 wxString2VariantFnc from = NULL );\r
537 wxEventSourceTypeInfo( int eventType, int lastEventType, wxClassInfo* eventClass, \r
538 wxVariant2StringFnc to = NULL, wxString2VariantFnc from = NULL );\r
539\r
540 int GetEventType() const { return m_eventType; }\r
541 int GetLastEventType() const { return m_lastEventType; }\r
542 const wxClassInfo* GetEventClass() const { return m_eventClass; }\r
543\r
544private:\r
545 const wxClassInfo *m_eventClass; // (extended will merge into classinfo)\r
546 int m_eventType;\r
547 int m_lastEventType;\r
548};\r
549\r
550template<typename T> const wxTypeInfo* wxGetTypeInfo( T * ) \\r
551 { return wxTypeInfo::FindType(typeid(T).name()); }\r
552\r
553// this macro is for usage with custom, non-object derived classes and structs, \r
554// wxPoint is such a custom type\r
555\r
556#if wxUSE_FUNC_TEMPLATE_POINTER\r
557 #define wxCUSTOM_TYPE_INFO( e, toString, fromString ) \\r
558 wxCustomTypeInfo s_typeInfo##e(typeid(e).name(), &toString, &fromString);\r
559#else\r
560 #define wxCUSTOM_TYPE_INFO( e, toString, fromString ) \\r
561 void ToString##e( const wxVariantBase& data, wxString &result ) \\r
562 { toString(data, result); } \\r
563 void FromString##e( const wxString& data, wxVariantBase &result ) \\r
564 { fromString(data, result); } \\r
565 wxCustomTypeInfo s_typeInfo##e(typeid(e).name(), \\r
566 &ToString##e, &FromString##e);\r
567#endif\r
568\r
569#define wxCOLLECTION_TYPE_INFO( element, collection ) \\r
570 wxCollectionTypeInfo s_typeInfo##collection( typeid(element).name(), \\r
571 NULL, NULL, typeid(collection).name() );\r
572\r
573// sometimes a compiler invents specializations that are nowhere called, \r
574// use this macro to satisfy the refs, currently we don't have to play \r
575// tricks, but if we will have to according to the compiler, we will use \r
576// that macro for that\r
577\r
578#define wxILLEGAL_TYPE_SPECIALIZATION( a )\r
579\r
580#endif // wxUSE_EXTENDED_RTTI\r
581#endif // _XTITYPES_H_\r