diff --git a/Makefile.in b/Makefile.in
index c513f1343d..61f9b7d1f7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -426,6 +426,7 @@ ALL_BASE_HEADERS = \
wx/tokenzr.h \
wx/tracker.h \
wx/txtstrm.h \
+ wx/typeinfo.h \
wx/types.h \
wx/unichar.h \
wx/uri.h \
@@ -589,6 +590,7 @@ ALL_PORTS_BASE_HEADERS = \
wx/tokenzr.h \
wx/tracker.h \
wx/txtstrm.h \
+ wx/typeinfo.h \
wx/types.h \
wx/unichar.h \
wx/uri.h \
diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl
index 723c94b65d..7686643cf4 100644
--- a/build/bakefiles/files.bkl
+++ b/build/bakefiles/files.bkl
@@ -519,6 +519,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/tokenzr.h
wx/tracker.h
wx/txtstrm.h
+ wx/typeinfo.h
wx/types.h
wx/unichar.h
wx/uri.h
diff --git a/build/msw/wx_base.dsp b/build/msw/wx_base.dsp
index 88d503cbb5..d6ab5d2a60 100644
--- a/build/msw/wx_base.dsp
+++ b/build/msw/wx_base.dsp
@@ -1539,6 +1539,10 @@ SOURCE=..\..\include\wx\txtstrm.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\typeinfo.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\types.h
# End Source File
# Begin Source File
diff --git a/build/msw/wx_vc7_base.vcproj b/build/msw/wx_vc7_base.vcproj
index 8fc8a09d91..b4b1aa9261 100644
--- a/build/msw/wx_vc7_base.vcproj
+++ b/build/msw/wx_vc7_base.vcproj
@@ -1586,6 +1586,9 @@
+
+
diff --git a/build/msw/wx_vc8_base.vcproj b/build/msw/wx_vc8_base.vcproj
index 66a707f953..32c8d3823f 100644
--- a/build/msw/wx_vc8_base.vcproj
+++ b/build/msw/wx_vc8_base.vcproj
@@ -2133,6 +2133,10 @@
RelativePath="..\..\include\wx\txtstrm.h"
>
+
+
diff --git a/build/msw/wx_vc9_base.vcproj b/build/msw/wx_vc9_base.vcproj
index d821e12403..11124cd859 100644
--- a/build/msw/wx_vc9_base.vcproj
+++ b/build/msw/wx_vc9_base.vcproj
@@ -2129,6 +2129,10 @@
RelativePath="..\..\include\wx\txtstrm.h"
>
+
+
diff --git a/include/wx/any.h b/include/wx/any.h
index 52d8480b66..b99e84bb99 100644
--- a/include/wx/any.h
+++ b/include/wx/any.h
@@ -19,6 +19,7 @@
#include "wx/string.h"
#include "wx/meta/movable.h"
#include "wx/meta/if.h"
+#include "wx/typeinfo.h"
// Size of the wxAny value buffer.
@@ -43,9 +44,6 @@ union wxAnyValueBuffer
wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
};
-typedef void (*wxAnyClassInfo)();
-
-
//
// wxAnyValueType is base class for value type functionality for C++ data
// types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
@@ -53,6 +51,7 @@ typedef void (*wxAnyClassInfo)();
//
class WXDLLIMPEXP_BASE wxAnyValueType
{
+ WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
public:
/**
Default constructor.
@@ -66,11 +65,6 @@ public:
{
}
- /**
- This function is used for internal type matching.
- */
- virtual wxAnyClassInfo GetClassInfo() const = 0;
-
/**
This function is used for internal type matching.
*/
@@ -125,28 +119,22 @@ private:
#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
wxAnyValueTypeImpl::IsSameClass(valueTypePtr)
- //valueTypePtr->CheckType(static_cast(NULL))
-
/**
Helper macro for defining user value types.
- NB: We really cannot compare sm_classInfo directly in IsSameClass(),
- but instead call sm_instance->GetClassInfo(). The former technique
- broke at least on GCC 4.2 (but worked on VC8 shared build).
+ Even though C++ RTTI would be fully available to use, we'd have to to
+ facilitate sub-type system which allows, for instance, wxAny with
+ signed short '15' to be treated equal to wxAny with signed long long '15'.
+ Having sm_instance is important here.
*/
#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
friend class wxAny; \
+ WX_DECLARE_TYPEINFO_INLINE(CLS) \
public: \
- static void sm_classInfo() {} \
- \
- virtual wxAnyClassInfo GetClassInfo() const \
- { \
- return sm_classInfo; \
- } \
static bool IsSameClass(const wxAnyValueType* otherType) \
{ \
- return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \
+ return wxTypeId(*sm_instance) == wxTypeId(*otherType); \
} \
virtual bool IsSameType(const wxAnyValueType* otherType) const \
{ \
diff --git a/include/wx/event.h b/include/wx/event.h
index 42d24634e4..79534fa7ee 100644
--- a/include/wx/event.h
+++ b/include/wx/event.h
@@ -153,6 +153,8 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
#ifdef wxHAS_EVENT_BIND
+#include "wx/typeinfo.h"
+
// The tag is a type associated to the event type (which is an integer itself,
// in spite of its name) value. It exists in order to be used as a template
// parameter and provide a mapping between the event type values and their
@@ -189,16 +191,6 @@ typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
// compiler we can restore its old definition for it.
typedef wxEventFunction wxObjectEventFunction;
-
-// wxEventFunctorClassInfo is used as a unique identifier for wxEventFunctor-
-// derived classes; it is more light weight than wxClassInfo and can be used in
-// template classes
-typedef void (*wxEventFunctorClassInfo)();
-
-// this macro must be used in wxEventFunctor-derived classes
-#define wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( classInfoName ) \
- static void classInfoName() {}
-
// The event functor which is stored in the static and dynamic event tables:
class WXDLLIMPEXP_BASE wxEventFunctor
{
@@ -212,11 +204,6 @@ public:
// finding it in an event table in Unbind(), by the given functor:
virtual bool IsMatching(const wxEventFunctor& functor) const = 0;
- // Test whether the given class info is the same as from this functor. This
- // allows us in IsMatching to safely downcast the given wxEventFunctor without
- // the usage of dynamic_cast<>().
- virtual bool IsSameClass(wxEventFunctorClassInfo classInfo) const = 0;
-
// If the functor holds an wxEvtHandler, then get access to it and track
// its lifetime with wxEventConnectionRef:
virtual wxEvtHandler *GetEvtHandler() const
@@ -228,6 +215,9 @@ public:
// wxEventFunction:
virtual wxEventFunction GetEvtMethod() const
{ return NULL; }
+
+private:
+ WX_DECLARE_ABSTRACT_TYPEINFO(wxEventFunctor)
};
// A plain method functor for the untyped legacy event types:
@@ -247,7 +237,7 @@ public:
virtual bool IsMatching(const wxEventFunctor& functor) const
{
- if ( functor.IsSameClass( sm_classInfo ))
+ if ( wxTypeId(functor) == wxTypeId(*this) )
{
const wxObjectEventFunctor &other =
static_cast< const wxObjectEventFunctor & >( functor );
@@ -262,9 +252,6 @@ public:
return false;
}
- virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
- { return sm_classInfo == otherClassInfo; }
-
virtual wxEvtHandler *GetEvtHandler() const
{ return m_handler; }
@@ -275,7 +262,10 @@ private:
wxEvtHandler *m_handler;
wxEventFunction m_method;
- wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
+ // Provide a dummy default ctor for type info purposes
+ wxObjectEventFunctor() { }
+
+ WX_DECLARE_TYPEINFO_INLINE(wxObjectEventFunctor)
};
// Create a functor for the legacy events: used by Connect()
@@ -424,22 +414,19 @@ public:
virtual bool IsMatching(const wxEventFunctor& functor) const
{
- if ( !functor.IsSameClass(sm_classInfo) )
+ if ( wxTypeId(functor) != wxTypeId(*this) )
return false;
typedef wxEventFunctorMethod
ThisFunctor;
- // the cast is valid because IsSameClass() returned true above
+ // the cast is valid because wxTypeId()s matched above
const ThisFunctor& other = static_cast(functor);
return (m_method == other.m_method || other.m_method == NULL) &&
(m_handler == other.m_handler || other.m_handler == NULL);
}
- virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
- { return sm_classInfo == otherClassInfo; }
-
virtual wxEvtHandler *GetEvtHandler() const
{ return this->ConvertToEvtHandler(m_handler); }
@@ -450,7 +437,12 @@ private:
EventHandler *m_handler;
void (Class::*m_method)(EventArg&);
- wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
+ // Provide a dummy default ctor for type info purposes
+ wxEventFunctorMethod() { }
+
+ typedef wxEventFunctorMethod thisClass;
+ WX_DECLARE_TYPEINFO_INLINE(thisClass)
};
@@ -488,7 +480,7 @@ public:
virtual bool IsMatching(const wxEventFunctor &functor) const
{
- if ( !functor.IsSameClass(sm_classInfo) )
+ if ( wxTypeId(functor) != wxTypeId(*this) )
return false;
typedef wxEventFunctorFunction ThisFunctor;
@@ -498,13 +490,14 @@ public:
return m_handler == other.m_handler;
}
- virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
- { return sm_classInfo == otherClassInfo; }
-
private:
void (*m_handler)(EventArg&);
- wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
+ // Provide a dummy default ctor for type info purposes
+ wxEventFunctorFunction() { }
+
+ typedef wxEventFunctorFunction thisClass;
+ WX_DECLARE_TYPEINFO_INLINE(thisClass)
};
@@ -532,7 +525,7 @@ public:
virtual bool IsMatching(const wxEventFunctor &functor) const
{
- if ( !functor.IsSameClass(sm_classInfo) )
+ if ( wxTypeId(functor) != wxTypeId(*this) )
return false;
typedef wxEventFunctorFunctor FunctorThis;
@@ -544,9 +537,6 @@ public:
return m_handlerAddr == other.m_handlerAddr;
}
- virtual bool IsSameClass( wxEventFunctorClassInfo otherClassInfo ) const
- { return sm_classInfo == otherClassInfo; }
-
private:
// Store a copy of the functor to prevent using/calling an already
// destroyed instance:
@@ -555,7 +545,11 @@ private:
// Use the address of the original functor for comparison in IsMatching:
const void *m_handlerAddr;
- wxDEFINE_EVENT_FUNCTOR_CLASS_INFO( sm_classInfo );
+ // Provide a dummy default ctor for type info purposes
+ wxEventFunctorFunctor() { }
+
+ typedef wxEventFunctorFunctor thisClass;
+ WX_DECLARE_TYPEINFO_INLINE(thisClass)
};
// Create functors for the templatized events, either allocated on the heap for
diff --git a/include/wx/typeinfo.h b/include/wx/typeinfo.h
new file mode 100644
index 0000000000..c1efb1b0c9
--- /dev/null
+++ b/include/wx/typeinfo.h
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/typeinfo.h
+// Purpose: wxTypeId implementation
+// Author: Jaakko Salli
+// Created: 2009-11-19
+// RCS-ID: $Id$
+// Copyright: (c) wxWidgets Team
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_TYPEINFO_H_
+#define _WX_TYPEINFO_H_
+
+//
+// This file defines wxTypeId macro that should be used internally in
+// wxWidgets instead of typeid(), for compatibility with builds that do
+// not implement C++ RTTI. Also, type defining macros in this file are also
+// intended for internal use only at this time and may change in future
+// versions.
+//
+
+#include "wx/defs.h"
+
+#ifndef wxNO_RTTI
+
+#include
+#include
+
+#define _WX_DECLARE_TYPEINFO_CUSTOM(CLS, IDENTFUNC)
+#define WX_DECLARE_TYPEINFO_INLINE(CLS)
+#define WX_DECLARE_TYPEINFO(CLS)
+#define WX_DEFINE_TYPEINFO(CLS)
+#define WX_DECLARE_ABSTRACT_TYPEINFO(CLS)
+
+//
+// For improved type-safety, let's make the check using class name
+// comparison. Most modern compilers already do this, but we cannot
+// rely on all supported compilers to work this well. However, in
+// cases where we'd know that typeid() would be flawless (as such),
+// wxTypeId could of course simply be defined as typeid.
+//
+
+class wxTypeInfo
+{
+public:
+ wxTypeInfo(const char* className)
+ {
+ m_className = className;
+ }
+
+ bool operator==(const wxTypeInfo& other)
+ {
+ return strcmp(m_className, other.m_className) == 0;
+ }
+
+ bool operator!=(const wxTypeInfo& other)
+ {
+ return strcmp(m_className, other.m_className) != 0;
+ }
+private:
+ const char* m_className;
+};
+
+#define wxTypeId(OBJ) wxTypeInfo(typeid(OBJ).name())
+
+#else // if !wxNO_RTTI
+
+//
+// When C++ RTTI is not available, we will have to make the type comparison
+// using pointer to a dummy static member function. This will fail if
+// declared type is used across DLL boundaries, although using
+// WX_DECLARE_TYPEINFO() and WX_DEFINE_TYPEINFO() pair instead of
+// WX_DECLARE_TYPEINFO_INLINE() should fix this. However, that approach is
+// usually not possible when type info needs to be declared for a template
+// class.
+//
+
+typedef void (*wxTypeIdentifier)();
+
+// Use this macro to declare type info with specified static function
+// IDENTFUNC used as type identifier. Usually you should only use
+// WX_DECLARE_TYPEINFO() or WX_DECLARE_TYPEINFO_INLINE() however.
+#define _WX_DECLARE_TYPEINFO_CUSTOM(CLS, IDENTFUNC) \
+public: \
+ virtual wxTypeIdentifier GetWxTypeId() const \
+ { \
+ return reinterpret_cast \
+ (&IDENTFUNC); \
+ }
+
+// Use this macro to declare type info with externally specified
+// type identifier, defined with WX_DEFINE_TYPEINFO().
+#define WX_DECLARE_TYPEINFO(CLS) \
+private: \
+ static CLS sm_wxClassInfo(); \
+_WX_DECLARE_TYPEINFO_CUSTOM(CLS, sm_wxClassInfo)
+
+// Use this macro to implement type identifier function required by
+// WX_DECLARE_TYPEINFO().
+// NOTE: CLS is required to have default ctor. If it doesn't
+// already, you should provide a private dummy one.
+#define WX_DEFINE_TYPEINFO(CLS) \
+CLS CLS::sm_wxClassInfo() { return CLS(); }
+
+// Use this macro to declare type info fully inline in class.
+// NOTE: CLS is required to have default ctor. If it doesn't
+// already, you should provide a private dummy one.
+#define WX_DECLARE_TYPEINFO_INLINE(CLS) \
+private: \
+ static CLS sm_wxClassInfo() { return CLS(); } \
+_WX_DECLARE_TYPEINFO_CUSTOM(CLS, sm_wxClassInfo)
+
+#define wxTypeId(OBJ) (OBJ).GetWxTypeId()
+
+// Because abstract classes cannot be instantiated, we use
+// this macro to define pure virtual type interface for them.
+#define WX_DECLARE_ABSTRACT_TYPEINFO(CLS) \
+public: \
+ virtual wxTypeIdentifier GetWxTypeId() const = 0;
+
+#endif // wxNO_RTTI/!wxNO_RTTI
+
+#endif // _WX_TYPEINFO_H_
diff --git a/interface/wx/any.h b/interface/wx/any.h
index d8e69cbc58..eee17db785 100644
--- a/interface/wx/any.h
+++ b/interface/wx/any.h
@@ -63,25 +63,6 @@
Note that pointers to any and all classes are already automatically
declared as movable data.
- @warning Caveat with shared libraries (DLLs): If you have a scenario where
- you use wxAny across application's shared library and application
- itself (or, with another of your shared libraries), then you must
- use wxDECLARE_ANY_TYPE() macro in your shared library code to
- correctly make sure that the wxAnyValueType implementation is
- generated correctly. Failure to do this will result in breakage
- of the wxAny type recognition with type in question. Below is an
- example how to use the macro.
- @code
- // In your shared library/DLL-only
- wxDECLARE_ANY_TYPE(MyClass, WXEXPORT)
-
- // In your shared library/DLL source code
- WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl)
-
- // In code using said shared library/DLL
- wxDECLARE_ANY_TYPE(MyClass, WXIMPORT)
- @endcode
-
@library{wxbase}
@category{data}
@@ -433,11 +414,6 @@ public:
*/
virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
- /**
- This function is used for internal type matching.
- */
- virtual wxAnyClassInfo GetClassInfo() const = 0;
-
/**
This function is used for internal type matching.
*/
diff --git a/tests/Makefile.in b/tests/Makefile.in
index cc84cf2bb0..2c566486ec 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -82,6 +82,7 @@ TEST_OBJECTS = \
test_convautotest.o \
test_mbconvtest.o \
test_misctests.o \
+ test_typeinfotest.o \
test_ipc.o \
test_socket.o \
test_regextest.o \
@@ -434,6 +435,9 @@ test_mbconvtest.o: $(srcdir)/mbconv/mbconvtest.cpp $(TEST_ODEP)
test_misctests.o: $(srcdir)/misc/misctests.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/misc/misctests.cpp
+test_typeinfotest.o: $(srcdir)/misc/typeinfotest.cpp $(TEST_ODEP)
+ $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/misc/typeinfotest.cpp
+
test_ipc.o: $(srcdir)/net/ipc.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/net/ipc.cpp
diff --git a/tests/any/anytest.cpp b/tests/any/anytest.cpp
index 792f1576a8..afffedaabc 100644
--- a/tests/any/anytest.cpp
+++ b/tests/any/anytest.cpp
@@ -200,6 +200,12 @@ void wxAnyTestCase::Equality()
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()
@@ -266,6 +272,7 @@ 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
@@ -275,9 +282,14 @@ void wxAnyTestCase::GetAs()
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, static_cast(15));
+ CPPUNIT_ASSERT_EQUAL(ul, 15UL);
res = m_anySignedLong1.GetAs(&s);
CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(s == "15");
diff --git a/tests/makefile.bcc b/tests/makefile.bcc
index e399701b58..66d0c7667f 100644
--- a/tests/makefile.bcc
+++ b/tests/makefile.bcc
@@ -66,6 +66,7 @@ TEST_OBJECTS = \
$(OBJS)\test_convautotest.obj \
$(OBJS)\test_mbconvtest.obj \
$(OBJS)\test_misctests.obj \
+ $(OBJS)\test_typeinfotest.obj \
$(OBJS)\test_ipc.obj \
$(OBJS)\test_socket.obj \
$(OBJS)\test_regextest.obj \
@@ -479,6 +480,9 @@ $(OBJS)\test_mbconvtest.obj: .\mbconv\mbconvtest.cpp
$(OBJS)\test_misctests.obj: .\misc\misctests.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\misctests.cpp
+$(OBJS)\test_typeinfotest.obj: .\misc\typeinfotest.cpp
+ $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\typeinfotest.cpp
+
$(OBJS)\test_ipc.obj: .\net\ipc.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\net\ipc.cpp
diff --git a/tests/makefile.gcc b/tests/makefile.gcc
index e267348e1d..587fc3448e 100644
--- a/tests/makefile.gcc
+++ b/tests/makefile.gcc
@@ -58,6 +58,7 @@ TEST_OBJECTS = \
$(OBJS)\test_convautotest.o \
$(OBJS)\test_mbconvtest.o \
$(OBJS)\test_misctests.o \
+ $(OBJS)\test_typeinfotest.o \
$(OBJS)\test_ipc.o \
$(OBJS)\test_socket.o \
$(OBJS)\test_regextest.o \
@@ -460,6 +461,9 @@ $(OBJS)\test_mbconvtest.o: ./mbconv/mbconvtest.cpp
$(OBJS)\test_misctests.o: ./misc/misctests.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\test_typeinfotest.o: ./misc/typeinfotest.cpp
+ $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\test_ipc.o: ./net/ipc.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
diff --git a/tests/makefile.vc b/tests/makefile.vc
index 2f874658f9..5a9c367b05 100644
--- a/tests/makefile.vc
+++ b/tests/makefile.vc
@@ -60,6 +60,7 @@ TEST_OBJECTS = \
$(OBJS)\test_convautotest.obj \
$(OBJS)\test_mbconvtest.obj \
$(OBJS)\test_misctests.obj \
+ $(OBJS)\test_typeinfotest.obj \
$(OBJS)\test_ipc.obj \
$(OBJS)\test_socket.obj \
$(OBJS)\test_regextest.obj \
@@ -599,6 +600,9 @@ $(OBJS)\test_mbconvtest.obj: .\mbconv\mbconvtest.cpp
$(OBJS)\test_misctests.obj: .\misc\misctests.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\misctests.cpp
+$(OBJS)\test_typeinfotest.obj: .\misc\typeinfotest.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\typeinfotest.cpp
+
$(OBJS)\test_ipc.obj: .\net\ipc.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\net\ipc.cpp
diff --git a/tests/makefile.wat b/tests/makefile.wat
index fa797a5560..5c5ebfd586 100644
--- a/tests/makefile.wat
+++ b/tests/makefile.wat
@@ -300,6 +300,7 @@ TEST_OBJECTS = &
$(OBJS)\test_convautotest.obj &
$(OBJS)\test_mbconvtest.obj &
$(OBJS)\test_misctests.obj &
+ $(OBJS)\test_typeinfotest.obj &
$(OBJS)\test_ipc.obj &
$(OBJS)\test_socket.obj &
$(OBJS)\test_regextest.obj &
@@ -518,6 +519,9 @@ $(OBJS)\test_mbconvtest.obj : .AUTODEPEND .\mbconv\mbconvtest.cpp
$(OBJS)\test_misctests.obj : .AUTODEPEND .\misc\misctests.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
+$(OBJS)\test_typeinfotest.obj : .AUTODEPEND .\misc\typeinfotest.cpp
+ $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
+
$(OBJS)\test_ipc.obj : .AUTODEPEND .\net\ipc.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
diff --git a/tests/misc/typeinfotest.cpp b/tests/misc/typeinfotest.cpp
new file mode 100644
index 0000000000..368d53f0b7
--- /dev/null
+++ b/tests/misc/typeinfotest.cpp
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: tests/misc/typeinfotest.cpp
+// Purpose: Test typeinfo.h
+// Author: Jaakko Salli
+// RCS-ID: $Id$
+// Copyright: (c) the wxWidgets team
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+# pragma hdrstop
+#endif
+
+#include "wx/typeinfo.h"
+
+// ----------------------------------------------------------------------------
+// test class
+// ----------------------------------------------------------------------------
+
+class TypeInfoTestCase : public CppUnit::TestCase
+{
+public:
+ TypeInfoTestCase() { }
+
+private:
+ CPPUNIT_TEST_SUITE( TypeInfoTestCase );
+ CPPUNIT_TEST( Test );
+ CPPUNIT_TEST_SUITE_END();
+
+ void Test();
+
+ DECLARE_NO_COPY_CLASS(TypeInfoTestCase)
+};
+
+// register in the unnamed registry so that these tests are run by default
+CPPUNIT_TEST_SUITE_REGISTRATION( TypeInfoTestCase );
+
+// also include in it's own registry so that these tests can be run alone
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TypeInfoTestCase, "TypeInfoTestCase" );
+
+
+namespace UserNameSpace {
+ class UserType1
+ {
+ WX_DECLARE_TYPEINFO_INLINE(UserType1)
+ public:
+ virtual ~UserType1() { }
+ };
+}
+
+class UserType1
+{
+ WX_DECLARE_TYPEINFO_INLINE(UserType1)
+public:
+ virtual ~UserType1() { }
+};
+
+class UserType2
+{
+ WX_DECLARE_TYPEINFO(UserType2)
+public:
+ virtual ~UserType2() { }
+};
+
+WX_DEFINE_TYPEINFO(UserType2)
+
+void TypeInfoTestCase::Test()
+{
+ UserNameSpace::UserType1 uns_ut1;
+ UserNameSpace::UserType1* uns_ut1_p = new UserNameSpace::UserType1();
+ UserType1 ut1;
+ UserType1* ut1_p = new UserType1();
+ UserType2 ut2;
+ UserType2* ut2_p = new UserType2();
+
+ // These type comparison should match
+ CPPUNIT_ASSERT(wxTypeId(uns_ut1) == wxTypeId(*uns_ut1_p));
+ CPPUNIT_ASSERT(wxTypeId(ut1) == wxTypeId(*ut1_p));
+ CPPUNIT_ASSERT(wxTypeId(ut2) == wxTypeId(*ut2_p));
+
+ // These type comparison should not match
+ CPPUNIT_ASSERT(wxTypeId(uns_ut1) != wxTypeId(ut1));
+ CPPUNIT_ASSERT(wxTypeId(uns_ut1) != wxTypeId(ut2));
+ CPPUNIT_ASSERT(wxTypeId(ut1) != wxTypeId(ut2));
+
+ delete uns_ut1_p;
+ delete ut1_p;
+ delete ut2_p;
+}
+
diff --git a/tests/test.bkl b/tests/test.bkl
index 7965ee7705..06ad988d77 100644
--- a/tests/test.bkl
+++ b/tests/test.bkl
@@ -57,6 +57,7 @@
mbconv/convautotest.cpp
mbconv/mbconvtest.cpp
misc/misctests.cpp
+ misc/typeinfotest.cpp
net/ipc.cpp
net/socket.cpp
regex/regextest.cpp
diff --git a/tests/test_test.dsp b/tests/test_test.dsp
index 0389ed568e..b14651819f 100644
--- a/tests/test_test.dsp
+++ b/tests/test_test.dsp
@@ -461,6 +461,10 @@ SOURCE=.\strings\tokenizer.cpp
# End Source File
# Begin Source File
+SOURCE=.\misc\typeinfotest.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\strings\unichar.cpp
# End Source File
# Begin Source File
diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj
index 9a05a8b305..7043d32d80 100644
--- a/tests/test_vc7_test.vcproj
+++ b/tests/test_vc7_test.vcproj
@@ -781,6 +781,9 @@
+
+
diff --git a/tests/test_vc8_test.vcproj b/tests/test_vc8_test.vcproj
index b006ceac98..74453d919c 100644
--- a/tests/test_vc8_test.vcproj
+++ b/tests/test_vc8_test.vcproj
@@ -1115,6 +1115,10 @@
RelativePath=".\strings\tokenizer.cpp"
>
+
+
diff --git a/tests/test_vc9_test.vcproj b/tests/test_vc9_test.vcproj
index 431bb3ad37..81786981bc 100644
--- a/tests/test_vc9_test.vcproj
+++ b/tests/test_vc9_test.vcproj
@@ -1087,6 +1087,10 @@
RelativePath=".\strings\tokenizer.cpp"
>
+
+
diff --git a/wxGTK.spec b/wxGTK.spec
index ac46a9b9b0..e180bce148 100644
--- a/wxGTK.spec
+++ b/wxGTK.spec
@@ -322,6 +322,7 @@ wx/tls.h
wx/tokenzr.h
wx/tracker.h
wx/txtstrm.h
+wx/typeinfo.h
wx/types.h
wx/unichar.h
wx/uri.h
diff --git a/wxMotif.spec b/wxMotif.spec
index 17f5818d77..32ecaadceb 100644
--- a/wxMotif.spec
+++ b/wxMotif.spec
@@ -227,6 +227,7 @@ wx/tls.h
wx/tokenzr.h
wx/tracker.h
wx/txtstrm.h
+wx/typeinfo.h
wx/types.h
wx/unichar.h
wx/uri.h
diff --git a/wxX11.spec b/wxX11.spec
index 9ee4ad19a9..bf79d96c4f 100644
--- a/wxX11.spec
+++ b/wxX11.spec
@@ -251,6 +251,7 @@ wx/tls.h
wx/tokenzr.h
wx/tracker.h
wx/txtstrm.h
+wx/typeinfo.h
wx/types.h
wx/unichar.h
wx/uri.h