From 7db064f60f2d60bcfea44a9973a18e6c2bf2161d Mon Sep 17 00:00:00 2001 From: Jaakko Salli Date: Thu, 19 Nov 2009 19:27:24 +0000 Subject: [PATCH] Added typeinfo.h which implements wxTypeId, using C++ RTTI if available. wxAny and Unbind<>() code are updated to use it. Added and updated related unit tests. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62690 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 2 + build/bakefiles/files.bkl | 1 + build/msw/wx_base.dsp | 4 ++ build/msw/wx_vc7_base.vcproj | 3 + build/msw/wx_vc8_base.vcproj | 4 ++ build/msw/wx_vc9_base.vcproj | 4 ++ include/wx/any.h | 28 +++----- include/wx/event.h | 66 +++++++++---------- include/wx/typeinfo.h | 123 +++++++++++++++++++++++++++++++++++ interface/wx/any.h | 24 ------- tests/Makefile.in | 4 ++ tests/any/anytest.cpp | 14 +++- tests/makefile.bcc | 4 ++ tests/makefile.gcc | 4 ++ tests/makefile.vc | 4 ++ tests/makefile.wat | 4 ++ tests/misc/typeinfotest.cpp | 92 ++++++++++++++++++++++++++ tests/test.bkl | 1 + tests/test_test.dsp | 4 ++ tests/test_vc7_test.vcproj | 3 + tests/test_vc8_test.vcproj | 4 ++ tests/test_vc9_test.vcproj | 4 ++ wxGTK.spec | 1 + wxMotif.spec | 1 + wxX11.spec | 1 + 25 files changed, 323 insertions(+), 81 deletions(-) create mode 100644 include/wx/typeinfo.h create mode 100644 tests/misc/typeinfotest.cpp 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 -- 2.45.2