From 178c77606f3186250b42685ca752d0bc34cd02e9 Mon Sep 17 00:00:00 2001 From: Jaakko Salli Date: Sat, 19 Sep 2009 08:51:11 +0000 Subject: [PATCH] wxAny initial commit (closes #10932) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61971 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 19 + build/bakefiles/files.bkl | 2 + build/msw/makefile.bcc | 16 + build/msw/makefile.gcc | 16 + build/msw/makefile.vc | 16 + build/msw/makefile.wat | 16 + build/msw/wx_base.dsp | 8 + build/msw/wx_vc7_base.vcproj | 6 + build/msw/wx_vc8_base.vcproj | 8 + build/msw/wx_vc9_base.vcproj | 8 + configure | 54 +- configure.in | 5 + docs/changes.txt | 4 +- docs/doxygen/mainpages/cat_classes.h | 1 + docs/doxygen/mainpages/const_wxusedef.h | 1 + docs/doxygen/scripts/common.py | 2 + include/wx/any.h | 794 ++++++++++++++++++++++++ include/wx/chkconf.h | 8 + include/wx/msw/setup0.h | 8 + include/wx/msw/wince/setup.h | 8 + include/wx/os2/setup0.h | 8 + include/wx/osx/setup0.h | 8 + include/wx/palmos/setup0.h | 8 + include/wx/setup_inc.h | 8 + include/wx/univ/setup0.h | 8 + interface/wx/any.h | 425 +++++++++++++ setup.h.in | 2 + setup.h_vms | 2 + src/common/any.cpp | 402 ++++++++++++ src/common/descrip.mms | 5 +- tests/Makefile.in | 4 + tests/any/anytest.cpp | 431 +++++++++++++ tests/makefile.bcc | 4 + tests/makefile.gcc | 4 + tests/makefile.vc | 4 + tests/makefile.wat | 4 + 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 + 44 files changed, 2343 insertions(+), 3 deletions(-) create mode 100644 include/wx/any.h create mode 100644 interface/wx/any.h create mode 100644 src/common/any.cpp create mode 100644 tests/any/anytest.cpp diff --git a/Makefile.in b/Makefile.in index a15c0958dc..9c4dcdf98e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -310,6 +310,7 @@ WXSCINTILLA_OBJECTS = \ PLUGINS_INST_DIR = $(libdir)/wx/$(PLUGIN_VERSION0) ALL_BASE_HEADERS = \ wx/afterstd.h \ + wx/any.h \ wx/anystr.h \ wx/app.h \ wx/apptrait.h \ @@ -470,6 +471,7 @@ ALL_HEADERS = \ $(ALL_GUI_HEADERS) ALL_PORTS_BASE_HEADERS = \ wx/afterstd.h \ + wx/any.h \ wx/anystr.h \ wx/app.h \ wx/apptrait.h \ @@ -665,6 +667,7 @@ ALL_PORTS_BASE_HEADERS = \ wx/xml/xml.h \ wx/xtixml.h ALL_BASE_SOURCES = \ + src/common/any.cpp \ src/common/appbase.cpp \ src/common/arcall.cpp \ src/common/arcfind.cpp \ @@ -855,6 +858,7 @@ MONODLL_OBJCXXFLAGS = $(__monodll_PCH_INC) -D__WX$(TOOLKIT)__ \ -I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DLINK_LEXERS \ $(PIC_FLAG) $(CPPFLAGS) $(OBJCXXFLAGS) MONODLL_OBJECTS = \ + monodll_any.o \ monodll_appbase.o \ monodll_arcall.o \ monodll_arcfind.o \ @@ -982,6 +986,7 @@ MONOLIB_OBJCXXFLAGS = $(__monolib_PCH_INC) -D__WX$(TOOLKIT)__ \ -I$(top_srcdir)/src/stc/scintilla/src -D__WX__ -DSCI_LEXER -DLINK_LEXERS \ $(CPPFLAGS) $(OBJCXXFLAGS) MONOLIB_OBJECTS = \ + monolib_any.o \ monolib_appbase.o \ monolib_arcall.o \ monolib_arcfind.o \ @@ -1104,6 +1109,7 @@ BASEDLL_OBJCXXFLAGS = $(__basedll_PCH_INC) -D__WX$(TOOLKIT)__ \ -DwxUSE_BASE=1 $(PIC_FLAG) $(CPPFLAGS) $(OBJCXXFLAGS) BASEDLL_OBJECTS = \ $(__basedll___win32rc) \ + basedll_any.o \ basedll_appbase.o \ basedll_arcall.o \ basedll_arcfind.o \ @@ -1209,6 +1215,7 @@ BASELIB_OBJCXXFLAGS = $(__baselib_PCH_INC) -D__WX$(TOOLKIT)__ \ $(__INC_REGEX_p) $(__INC_EXPAT_p) -DwxUSE_GUI=0 -DwxUSE_BASE=1 $(CPPFLAGS) \ $(OBJCXXFLAGS) BASELIB_OBJECTS = \ + baselib_any.o \ baselib_appbase.o \ baselib_arcall.o \ baselib_arcfind.o \ @@ -14203,6 +14210,9 @@ wxscintilla_WindowAccessor.o: $(srcdir)/src/stc/scintilla/src/WindowAccessor.cxx wxscintilla_XPM.o: $(srcdir)/src/stc/scintilla/src/XPM.cxx $(CXXC) -c -o $@ $(WXSCINTILLA_CXXFLAGS) $(srcdir)/src/stc/scintilla/src/XPM.cxx +monodll_any.o: $(srcdir)/src/common/any.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/any.cpp + monodll_appbase.o: $(srcdir)/src/common/appbase.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/appbase.cpp @@ -18940,6 +18950,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) monodll_version_rc.o: $(srcdir)/src/msw/version.rc $(MONODLL_ODEP) $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_62) $(__DEBUG_DEFINE_p_61) $(__EXCEPTIONS_DEFINE_p_61) $(__RTTI_DEFINE_p_61) $(__THREAD_DEFINE_p_61) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include $(__INC_TIFF_BUILD_p_62) $(__INC_TIFF_p_62) $(__INC_JPEG_p_62) $(__INC_PNG_p_61) $(__INC_ZLIB_p_63) $(__INC_REGEX_p_61) $(__INC_EXPAT_p_61) --define wxUSE_BASE=1 --define WXMAKINGDLL --include-dir $(top_srcdir)/src/stc/scintilla/include --include-dir $(top_srcdir)/src/stc/scintilla/src --define __WX__ --define SCI_LEXER --define LINK_LEXERS +monolib_any.o: $(srcdir)/src/common/any.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/any.cpp + monolib_appbase.o: $(srcdir)/src/common/appbase.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/appbase.cpp @@ -23677,6 +23690,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) basedll_version_rc.o: $(srcdir)/src/msw/version.rc $(BASEDLL_ODEP) $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_62) $(__DEBUG_DEFINE_p_61) $(__EXCEPTIONS_DEFINE_p_61) $(__RTTI_DEFINE_p_61) $(__THREAD_DEFINE_p_61) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIX)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include $(__INC_TIFF_BUILD_p_62) $(__INC_TIFF_p_62) $(__INC_JPEG_p_62) $(__INC_PNG_p_61) $(__INC_ZLIB_p_63) $(__INC_REGEX_p_61) $(__INC_EXPAT_p_61) --define wxUSE_GUI=0 --define WXMAKINGDLL_BASE --define wxUSE_BASE=1 +basedll_any.o: $(srcdir)/src/common/any.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/any.cpp + basedll_appbase.o: $(srcdir)/src/common/appbase.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/appbase.cpp @@ -24148,6 +24164,9 @@ basedll_cocoa_utils.o: $(srcdir)/src/osx/cocoa/utils.mm $(BASEDLL_ODEP) @COND_PLATFORM_MACOSX_1@basedll_utilsunx.o: $(srcdir)/src/unix/utilsunx.cpp $(BASEDLL_ODEP) @COND_PLATFORM_MACOSX_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/utilsunx.cpp +baselib_any.o: $(srcdir)/src/common/any.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/any.cpp + baselib_appbase.o: $(srcdir)/src/common/appbase.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/appbase.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 6849e3fee6..5b045f8b8d 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -304,6 +304,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! + src/common/any.cpp src/common/appbase.cpp src/common/arcall.cpp src/common/arcfind.cpp @@ -392,6 +393,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/afterstd.h + wx/any.h wx/anystr.h wx/app.h wx/apptrait.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index a60282ccba..1a65bf39e5 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -308,6 +308,7 @@ MONODLL_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ $(CXXFLAGS) MONODLL_OBJECTS = \ $(OBJS)\monodll_dummy.obj \ + $(OBJS)\monodll_any.obj \ $(OBJS)\monodll_appbase.obj \ $(OBJS)\monodll_arcall.obj \ $(OBJS)\monodll_arcfind.obj \ @@ -448,6 +449,7 @@ MONOLIB_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ $(CXXFLAGS) MONOLIB_OBJECTS = \ $(OBJS)\monolib_dummy.obj \ + $(OBJS)\monolib_any.obj \ $(OBJS)\monolib_appbase.obj \ $(OBJS)\monolib_arcall.obj \ $(OBJS)\monolib_arcfind.obj \ @@ -585,6 +587,7 @@ BASEDLL_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ -DwxUSE_BASE=1 -Hu -H=$(OBJS)\wxprec_basedll.csm $(CPPFLAGS) $(CXXFLAGS) BASEDLL_OBJECTS = \ $(OBJS)\basedll_dummy.obj \ + $(OBJS)\basedll_any.obj \ $(OBJS)\basedll_appbase.obj \ $(OBJS)\basedll_arcall.obj \ $(OBJS)\basedll_arcfind.obj \ @@ -707,6 +710,7 @@ BASELIB_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ -H=$(OBJS)\wxprec_baselib.csm $(CPPFLAGS) $(CXXFLAGS) BASELIB_OBJECTS = \ $(OBJS)\baselib_dummy.obj \ + $(OBJS)\baselib_any.obj \ $(OBJS)\baselib_appbase.obj \ $(OBJS)\baselib_arcall.obj \ $(OBJS)\baselib_arcfind.obj \ @@ -5495,6 +5499,9 @@ $(OBJS)\wxscintilla_XPM.obj: ..\..\src\stc\scintilla\src\XPM.cxx $(OBJS)\monodll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) -H ..\..\src\common\dummy.cpp +$(OBJS)\monodll_any.obj: ..\..\src\common\any.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\monodll_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\appbase.cpp @@ -7732,6 +7739,9 @@ $(OBJS)\monodll_version.res: ..\..\src\msw\version.rc $(OBJS)\monolib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) -H ..\..\src\common\dummy.cpp +$(OBJS)\monolib_any.obj: ..\..\src\common\any.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\monolib_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\appbase.cpp @@ -9969,6 +9979,9 @@ $(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp $(OBJS)\basedll_version.res: ..\..\src\msw\version.rc brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_62) $(__DEBUG_DEFINE_p_61) $(__EXCEPTIONS_DEFINE_p_61) $(__RTTI_DEFINE_p_61) $(__THREAD_DEFINE_p_61) $(__UNICODE_DEFINE_p_62) $(__MSLU_DEFINE_p_61) $(__GFXCTX_DEFINE_p_61) -i$(SETUPHDIR) -i..\..\include -dWXBUILDING -dWXDLLNAME=wxbase$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_bcc$(VENDORTAG) -i..\..\src\tiff\libtiff -i..\..\src\jpeg -i..\..\src\png -i..\..\src\zlib -i..\..\src\regex -i..\..\src\expat\lib -dwxUSE_GUI=0 -dWXMAKINGDLL_BASE -dwxUSE_BASE=1 ..\..\src\msw\version.rc +$(OBJS)\basedll_any.obj: ..\..\src\common\any.cpp + $(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\basedll_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\appbase.cpp @@ -10284,6 +10297,9 @@ $(OBJS)\basedll_volume.obj: ..\..\src\msw\volume.cpp $(OBJS)\baselib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) -q -c -P -o$@ $(BASELIB_CXXFLAGS) -H ..\..\src\common\dummy.cpp +$(OBJS)\baselib_any.obj: ..\..\src\common\any.cpp + $(CXX) -q -c -P -o$@ $(BASELIB_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\baselib_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) -q -c -P -o$@ $(BASELIB_CXXFLAGS) ..\..\src\common\appbase.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 0159901c1e..ae9165a644 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -295,6 +295,7 @@ MONODLL_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) MONODLL_OBJECTS = \ $(OBJS)\monodll_dummy.o \ + $(OBJS)\monodll_any.o \ $(OBJS)\monodll_appbase.o \ $(OBJS)\monodll_arcall.o \ $(OBJS)\monodll_arcfind.o \ @@ -436,6 +437,7 @@ MONOLIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) MONOLIB_OBJECTS = \ $(OBJS)\monolib_dummy.o \ + $(OBJS)\monolib_any.o \ $(OBJS)\monolib_appbase.o \ $(OBJS)\monolib_arcall.o \ $(OBJS)\monolib_arcfind.o \ @@ -575,6 +577,7 @@ BASEDLL_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ BASEDLL_OBJECTS = \ $(OBJS)\basedll_dummy.o \ $(OBJS)\basedll_version_rc.o \ + $(OBJS)\basedll_any.o \ $(OBJS)\basedll_appbase.o \ $(OBJS)\basedll_arcall.o \ $(OBJS)\basedll_arcfind.o \ @@ -697,6 +700,7 @@ BASELIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ $(CXXFLAGS) BASELIB_OBJECTS = \ $(OBJS)\baselib_dummy.o \ + $(OBJS)\baselib_any.o \ $(OBJS)\baselib_appbase.o \ $(OBJS)\baselib_arcall.o \ $(OBJS)\baselib_arcfind.o \ @@ -5653,6 +5657,9 @@ $(OBJS)\wxscintilla_XPM.o: ../../src/stc/scintilla/src/XPM.cxx $(OBJS)\monodll_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_any.o: ../../src/common/any.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_appbase.o: ../../src/common/appbase.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -8002,6 +8009,9 @@ $(OBJS)\monodll_version_rc.o: ../../src/msw/version.rc $(OBJS)\monolib_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_any.o: ../../src/common/any.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_appbase.o: ../../src/common/appbase.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -10351,6 +10361,9 @@ $(OBJS)\basedll_dummy.o: ../../src/common/dummy.cpp $(OBJS)\basedll_version_rc.o: ../../src/msw/version.rc windres --use-temp-file -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_62) $(__DEBUG_DEFINE_p_61) $(__EXCEPTIONS_DEFINE_p_61) $(__RTTI_DEFINE_p_61) $(__THREAD_DEFINE_p_61) $(__UNICODE_DEFINE_p_62) $(__MSLU_DEFINE_p_61) $(__GFXCTX_DEFINE_p_61) --include-dir $(SETUPHDIR) --include-dir ../../include --define WXBUILDING --define WXDLLNAME=wxbase$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gcc$(VENDORTAG) --include-dir ../../src/tiff/libtiff --include-dir ../../src/jpeg --include-dir ../../src/png --include-dir ../../src/zlib --include-dir ../../src/regex --include-dir ../../src/expat/lib --define wxUSE_GUI=0 --define WXMAKINGDLL_BASE --define wxUSE_BASE=1 +$(OBJS)\basedll_any.o: ../../src/common/any.cpp + $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\basedll_appbase.o: ../../src/common/appbase.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -10666,6 +10679,9 @@ $(OBJS)\basedll_volume.o: ../../src/msw/volume.cpp $(OBJS)\baselib_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\baselib_any.o: ../../src/common/any.cpp + $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\baselib_appbase.o: ../../src/common/appbase.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 5d14da8cba..71f5912442 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -311,6 +311,7 @@ MONODLL_CXXFLAGS = /M$(__RUNTIME_LIBS_100)$(__DEBUGRUNTIME) /DWIN32 \ /Fp"$(OBJS)\wxprec_monodll.pch" $(CPPFLAGS) $(CXXFLAGS) MONODLL_OBJECTS = \ $(OBJS)\monodll_dummy.obj \ + $(OBJS)\monodll_any.obj \ $(OBJS)\monodll_appbase.obj \ $(OBJS)\monodll_arcall.obj \ $(OBJS)\monodll_arcfind.obj \ @@ -456,6 +457,7 @@ MONOLIB_CXXFLAGS = /M$(__RUNTIME_LIBS_113)$(__DEBUGRUNTIME) /DWIN32 \ /Fp"$(OBJS)\wxprec_monolib.pch" $(CPPFLAGS) $(CXXFLAGS) MONOLIB_OBJECTS = \ $(OBJS)\monolib_dummy.obj \ + $(OBJS)\monolib_any.obj \ $(OBJS)\monolib_appbase.obj \ $(OBJS)\monolib_arcall.obj \ $(OBJS)\monolib_arcfind.obj \ @@ -599,6 +601,7 @@ BASEDLL_CXXFLAGS = /M$(__RUNTIME_LIBS_127)$(__DEBUGRUNTIME) /DWIN32 \ BASEDLL_OBJECTS = \ $(OBJS)\basedll_dummy.obj \ $(OBJS)\basedll_version.res \ + $(OBJS)\basedll_any.obj \ $(OBJS)\basedll_appbase.obj \ $(OBJS)\basedll_arcall.obj \ $(OBJS)\basedll_arcfind.obj \ @@ -726,6 +729,7 @@ BASELIB_CXXFLAGS = /M$(__RUNTIME_LIBS_140)$(__DEBUGRUNTIME) /DWIN32 \ /Fp"$(OBJS)\wxprec_baselib.pch" $(CPPFLAGS) $(CXXFLAGS) BASELIB_OBJECTS = \ $(OBJS)\baselib_dummy.obj \ + $(OBJS)\baselib_any.obj \ $(OBJS)\baselib_appbase.obj \ $(OBJS)\baselib_arcall.obj \ $(OBJS)\baselib_arcfind.obj \ @@ -5861,6 +5865,9 @@ $(OBJS)\wxscintilla_XPM.obj: ..\..\src\stc\scintilla\src\XPM.cxx $(OBJS)\monodll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp +$(OBJS)\monodll_any.obj: ..\..\src\common\any.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\monodll_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\appbase.cpp @@ -8098,6 +8105,9 @@ $(OBJS)\monodll_version.res: ..\..\src\msw\version.rc $(OBJS)\monolib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp +$(OBJS)\monolib_any.obj: ..\..\src\common\any.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\monolib_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\appbase.cpp @@ -10335,6 +10345,9 @@ $(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp $(OBJS)\basedll_version.res: ..\..\src\msw\version.rc rc /fo$@ /d WIN32 $(____DEBUGRUNTIME_4) $(__NO_VC_CRTDBG_p_68) /d __WXMSW__ $(__WXUNIV_DEFINE_p_62) $(__DEBUG_DEFINE_p_61) $(__EXCEPTIONS_DEFINE_p_61) $(__RTTI_DEFINE_p_61) $(__THREAD_DEFINE_p_61) $(__UNICODE_DEFINE_p_62) $(__MSLU_DEFINE_p_61) $(__GFXCTX_DEFINE_p_61) /i $(SETUPHDIR) /i ..\..\include /d WXBUILDING /d WXDLLNAME=wxbase$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_vc$(VENDORTAG) /i ..\..\src\tiff\libtiff /i ..\..\src\jpeg /i ..\..\src\png /i ..\..\src\zlib /i ..\..\src\regex /i ..\..\src\expat\lib /d wxUSE_GUI=0 /d WXMAKINGDLL_BASE /d wxUSE_BASE=1 ..\..\src\msw\version.rc +$(OBJS)\basedll_any.obj: ..\..\src\common\any.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\basedll_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\appbase.cpp @@ -10650,6 +10663,9 @@ $(OBJS)\basedll_volume.obj: ..\..\src\msw\volume.cpp $(OBJS)\baselib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp +$(OBJS)\baselib_any.obj: ..\..\src\common\any.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\any.cpp + $(OBJS)\baselib_appbase.obj: ..\..\src\common\appbase.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\appbase.cpp diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index 18cb56ed3e..d02c4c6208 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -3439,6 +3439,7 @@ MONODLL_CXXFLAGS = -bd $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & $(__EXCEPTIONSFLAG) $(CPPFLAGS) $(CXXFLAGS) MONODLL_OBJECTS = & $(OBJS)\monodll_dummy.obj & + $(OBJS)\monodll_any.obj & $(OBJS)\monodll_appbase.obj & $(OBJS)\monodll_arcall.obj & $(OBJS)\monodll_arcfind.obj & @@ -3579,6 +3580,7 @@ MONOLIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & $(CPPFLAGS) $(CXXFLAGS) MONOLIB_OBJECTS = & $(OBJS)\monolib_dummy.obj & + $(OBJS)\monolib_any.obj & $(OBJS)\monolib_appbase.obj & $(OBJS)\monolib_arcall.obj & $(OBJS)\monolib_arcfind.obj & @@ -3717,6 +3719,7 @@ BASEDLL_CXXFLAGS = -bd $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & $(CPPFLAGS) $(CXXFLAGS) BASEDLL_OBJECTS = & $(OBJS)\basedll_dummy.obj & + $(OBJS)\basedll_any.obj & $(OBJS)\basedll_appbase.obj & $(OBJS)\basedll_arcall.obj & $(OBJS)\basedll_arcfind.obj & @@ -3839,6 +3842,7 @@ BASELIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & $(CPPFLAGS) $(CXXFLAGS) BASELIB_OBJECTS = & $(OBJS)\baselib_dummy.obj & + $(OBJS)\baselib_any.obj & $(OBJS)\baselib_appbase.obj & $(OBJS)\baselib_arcall.obj & $(OBJS)\baselib_arcfind.obj & @@ -5920,6 +5924,9 @@ $(OBJS)\wxscintilla_XPM.obj : .AUTODEPEND ..\..\src\stc\scintilla\src\XPM.cxx $(OBJS)\monodll_dummy.obj : .AUTODEPEND ..\..\src\common\dummy.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +$(OBJS)\monodll_any.obj : .AUTODEPEND ..\..\src\common\any.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< + $(OBJS)\monodll_appbase.obj : .AUTODEPEND ..\..\src\common\appbase.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -8269,6 +8276,9 @@ $(OBJS)\monodll_version.res : .AUTODEPEND ..\..\src\msw\version.rc $(OBJS)\monolib_dummy.obj : .AUTODEPEND ..\..\src\common\dummy.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +$(OBJS)\monolib_any.obj : .AUTODEPEND ..\..\src\common\any.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< + $(OBJS)\monolib_appbase.obj : .AUTODEPEND ..\..\src\common\appbase.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -10618,6 +10628,9 @@ $(OBJS)\basedll_dummy.obj : .AUTODEPEND ..\..\src\common\dummy.cpp $(OBJS)\basedll_version.res : .AUTODEPEND ..\..\src\msw\version.rc wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) $(__GFXCTX_DEFINE_p) -i=$(SETUPHDIR) -i=..\..\include -dWXBUILDING -dWXDLLNAME=wxbase$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_wat$(VENDORTAG) -i=..\..\src\tiff\libtiff -i=..\..\src\jpeg -i=..\..\src\png -i=..\..\src\zlib -i=..\..\src\regex -i=..\..\src\expat\lib -dwxUSE_GUI=0 -dWXMAKINGDLL_BASE -dwxUSE_BASE=1 $< +$(OBJS)\basedll_any.obj : .AUTODEPEND ..\..\src\common\any.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(BASEDLL_CXXFLAGS) $< + $(OBJS)\basedll_appbase.obj : .AUTODEPEND ..\..\src\common\appbase.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASEDLL_CXXFLAGS) $< @@ -10933,6 +10946,9 @@ $(OBJS)\basedll_volume.obj : .AUTODEPEND ..\..\src\msw\volume.cpp $(OBJS)\baselib_dummy.obj : .AUTODEPEND ..\..\src\common\dummy.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASELIB_CXXFLAGS) $< +$(OBJS)\baselib_any.obj : .AUTODEPEND ..\..\src\common\any.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(BASELIB_CXXFLAGS) $< + $(OBJS)\baselib_appbase.obj : .AUTODEPEND ..\..\src\common\appbase.cpp $(CXX) -bt=nt -zq -fo=$^@ $(BASELIB_CXXFLAGS) $< diff --git a/build/msw/wx_base.dsp b/build/msw/wx_base.dsp index 4bc1022d75..5230122619 100644 --- a/build/msw/wx_base.dsp +++ b/build/msw/wx_base.dsp @@ -244,6 +244,10 @@ LIB32=link.exe -lib # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\src\common\any.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\common\appbase.cpp # End Source File # Begin Source File @@ -1039,6 +1043,10 @@ SOURCE=..\..\include\wx\afterstd.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\any.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\anystr.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_base.vcproj b/build/msw/wx_vc7_base.vcproj index a032ba90a4..3c2a33a32c 100644 --- a/build/msw/wx_vc7_base.vcproj +++ b/build/msw/wx_vc7_base.vcproj @@ -524,6 +524,9 @@ + + @@ -1205,6 +1208,9 @@ + + diff --git a/build/msw/wx_vc8_base.vcproj b/build/msw/wx_vc8_base.vcproj index dcbfff119d..4aa08b9f1e 100644 --- a/build/msw/wx_vc8_base.vcproj +++ b/build/msw/wx_vc8_base.vcproj @@ -734,6 +734,10 @@ Name="Common Sources" UniqueIdentifier="{A6A5C30D-BDB6-5050-906D-10A96065136C}" > + + @@ -1627,6 +1631,10 @@ RelativePath="..\..\include\wx\afterstd.h" > + + diff --git a/build/msw/wx_vc9_base.vcproj b/build/msw/wx_vc9_base.vcproj index 89ca7503c2..c5af22ed92 100644 --- a/build/msw/wx_vc9_base.vcproj +++ b/build/msw/wx_vc9_base.vcproj @@ -730,6 +730,10 @@ Name="Common Sources" UniqueIdentifier="{A6A5C30D-BDB6-5050-906D-10A96065136C}" > + + @@ -1623,6 +1627,10 @@ RelativePath="..\..\include\wx\afterstd.h" > + + diff --git a/configure b/configure index 8273903a77..535c97c026 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Id. +# From configure.in Id: configure.in 61944 2009-09-16 12:06:02Z PJC . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for wxWidgets 2.9.1. # @@ -1711,6 +1711,7 @@ Optional Features: --enable-baseevtloop use event loop in console programs too --enable-epollloop use wxEpollDispatcher class (Linux only) --enable-selectloop use wxSelectDispatcher class + --enable-any use wxAny class --enable-apple_ieee use the Apple IEEE codec --enable-arcstream use wxArchive streams --enable-base64 use base64 encoding/decoding functions @@ -6274,6 +6275,50 @@ echo "${ECHO_T}$result" >&6; } + enablestring= + defaultval=$wxUSE_ALL_FEATURES + if test -z "$defaultval"; then + if test x"$enablestring" = xdisable; then + defaultval=yes + else + defaultval=no + fi + fi + + { echo "$as_me:$LINENO: checking for --${enablestring:-enable}-any" >&5 +echo $ECHO_N "checking for --${enablestring:-enable}-any... $ECHO_C" >&6; } + # Check whether --enable-any was given. +if test "${enable_any+set}" = set; then + enableval=$enable_any; + if test "$enableval" = yes; then + wx_cv_use_any='wxUSE_ANY=yes' + else + wx_cv_use_any='wxUSE_ANY=no' + fi + +else + + wx_cv_use_any='wxUSE_ANY=${'DEFAULT_wxUSE_ANY":-$defaultval}" + +fi + + + eval "$wx_cv_use_any" + + if test x"$enablestring" = xdisable; then + if test $wxUSE_ANY = no; then + result=yes + else + result=no + fi + else + result=$wxUSE_ANY + fi + + { echo "$as_me:$LINENO: result: $result" >&5 +echo "${ECHO_T}$result" >&6; } + + enablestring= defaultval=$wxUSE_ALL_FEATURES if test -z "$defaultval"; then @@ -42260,6 +42305,13 @@ _ACEOF fi +if test "$wxUSE_ANY" = "yes"; then + cat >>confdefs.h <<\_ACEOF +#define wxUSE_ANY 1 +_ACEOF + +fi + if test "$wxUSE_APPLE_IEEE" = "yes"; then cat >>confdefs.h <<\_ACEOF #define wxUSE_APPLE_IEEE 1 diff --git a/configure.in b/configure.in index f5e9343db1..aff441405d 100644 --- a/configure.in +++ b/configure.in @@ -728,6 +728,7 @@ WX_ARG_FEATURE(epollloop, [ --enable-epollloop use wxEpollDispatcher c WX_ARG_FEATURE(selectloop, [ --enable-selectloop use wxSelectDispatcher class], wxUSE_SELECT_DISPATCHER) dnl please keep the settings below in alphabetical order +WX_ARG_FEATURE(any, [ --enable-any use wxAny class], wxUSE_ANY) WX_ARG_FEATURE(apple_ieee, [ --enable-apple_ieee use the Apple IEEE codec], wxUSE_APPLE_IEEE) WX_ARG_FEATURE(arcstream, [ --enable-arcstream use wxArchive streams], wxUSE_ARCHIVE_STREAMS) WX_ARG_FEATURE(base64, [ --enable-base64 use base64 encoding/decoding functions], wxUSE_BASE64) @@ -5473,6 +5474,10 @@ if test "$wxUSE_EXTENDED_RTTI" = "yes"; then AC_DEFINE(wxUSE_EXTENDED_RTTI) fi +if test "$wxUSE_ANY" = "yes"; then + AC_DEFINE(wxUSE_ANY) +fi + if test "$wxUSE_APPLE_IEEE" = "yes"; then AC_DEFINE(wxUSE_APPLE_IEEE) fi diff --git a/docs/changes.txt b/docs/changes.txt index 8bcebd9415..f9055f7267 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -1,4 +1,4 @@ -------------------------------------------------------------------------------- +------------------------------------------------------------------------------- wxWidgets Change Log ------------------------------------------------------------------------------- @@ -391,6 +391,8 @@ All: - Fix bug with position argument in wxImage::Size() (Byron Sorgdrager). - Fix bug with parsing concatenated switches in wxCmdLineParser (Mike Funduc). - Added wxMBConv::cMB2WC(wxCharBuffer) and cWC2MB(wxWCharBuffer) overloads. +- Added wxAny class; a modern, backwards-incompatible replacement for + wxVariant. All (GUI): diff --git a/docs/doxygen/mainpages/cat_classes.h b/docs/doxygen/mainpages/cat_classes.h index b287c33871..97820dfb6a 100644 --- a/docs/doxygen/mainpages/cat_classes.h +++ b/docs/doxygen/mainpages/cat_classes.h @@ -624,6 +624,7 @@ Related overview: @ref overview_log These are the data structure classes supported by wxWidgets. +@li wxAny: A class for storing arbitrary types that may change at run-time @li wxCmdLineParser: Command line parser class @li wxDateSpan: A logical time interval. @li wxDateTime: A class for date/time manipulations diff --git a/docs/doxygen/mainpages/const_wxusedef.h b/docs/doxygen/mainpages/const_wxusedef.h index 78fb4b3509..2f04505ab4 100644 --- a/docs/doxygen/mainpages/const_wxusedef.h +++ b/docs/doxygen/mainpages/const_wxusedef.h @@ -67,6 +67,7 @@ library: @itemdef{wxUSE_ACCEL, Use wxAcceleratorTable/Entry classes and support for them in wxMenu, wxMenuBar.} @itemdef{wxUSE_AFM_FOR_POSTSCRIPT, In wxPostScriptDC class use AFM (adobe font metrics) file for character widths.} @itemdef{wxUSE_ANIMATIONCTRL, Use wxAnimationCtrl class.} +@itemdef{wxUSE_ANY, Use wxAny class.} @itemdef{wxUSE_APPLE_IEEE, IEEE Extended to/from double routines; see src/common/extended.c file.} @itemdef{wxUSE_ARCHIVE_STREAMS, Enable streams for archive formats.} @itemdef{wxUSE_AUI, Use AUI (dockable windows) library.} diff --git a/docs/doxygen/scripts/common.py b/docs/doxygen/scripts/common.py index 41e80d7201..5285e0e3c5 100644 --- a/docs/doxygen/scripts/common.py +++ b/docs/doxygen/scripts/common.py @@ -7,6 +7,8 @@ ignored_methods = { # these classes are either replaced by different data types in bindings, or have equivalent / better # functionality provided by the target language. excluded_classes = [ + "wxAny", + "wxAnyValueType", "wxArchiveClassFactory", "wxArchiveEntry", "wxArchiveInputStream", diff --git a/include/wx/any.h b/include/wx/any.h new file mode 100644 index 0000000000..9acda4ef55 --- /dev/null +++ b/include/wx/any.h @@ -0,0 +1,794 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/any.h +// Purpose: wxAny class +// Author: Jaakko Salli +// Modified by: +// Created: 07/05/2009 +// RCS-ID: $Id$ +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_ANY_H_ +#define _WX_ANY_H_ + +#include "wx/defs.h" + +#if wxUSE_ANY + +#include "wx/string.h" +#include "wx/meta/movable.h" +#include "wx/meta/if.h" + + +// Size of the wxAny value buffer. +enum +{ + WX_ANY_VALUE_BUFFER_SIZE = 16 +}; + +union wxAnyValueBuffer +{ + void* m_ptr; + 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<>) +// will create a satisfactory wxAnyValueType implementation for a data type. +// +class WXDLLIMPEXP_BASE wxAnyValueType +{ +public: + /** + Default constructor. + */ + wxAnyValueType(); + + /** + Destructor. + */ + virtual ~wxAnyValueType() + { + } + + /** + This function is used for internal type matching. + */ + virtual wxAnyClassInfo GetClassInfo() const = 0; + + /** + This function is used for internal type matching. + */ + virtual bool IsSameType(const wxAnyValueType* otherType) const = 0; + + /** + This function is called every time the data in wxAny + buffer needs to be freed. + */ + virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0; + + /** + Implement this for buffer-to-buffer copy. src.m_ptr can + be expected to be NULL if value type of previously stored + data was different. + */ + virtual void CopyBuffer(const wxAnyValueBuffer& src, + wxAnyValueBuffer& dst) const = 0; + + /** + Convert value into buffer of different type. Return false if + not possible. + */ + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const = 0; + + /** + Use this template function for checking if wxAnyValueType represents + a specific C++ data type. + + @remarks This template function does not work on some older compilers + (such as Visual C++ 6.0). For full compiler ccompatibility + please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro + instead. + + @see wxAny::CheckType() + */ + // FIXME-VC6: remove this hack when VC6 is no longer supported + template + bool CheckType(T* reserved = NULL); +private: +}; + +// +// This method of checking the type is compatible with VC6 +#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). +*/ +#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \ + friend class wxAny; \ +public: \ + static void sm_classInfo() {} \ + \ + virtual wxAnyClassInfo GetClassInfo() const \ + { \ + return sm_classInfo; \ + } \ + static bool IsSameClass(const wxAnyValueType* otherType) \ + { \ + return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \ + } \ + virtual bool IsSameType(const wxAnyValueType* otherType) const \ + { \ + return IsSameClass(otherType); \ + } \ +private: \ + static CLS* sm_instance; \ +public: \ + static wxAnyValueType* GetInstance() \ + { \ + return sm_instance; \ + } + + +#define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \ + CLS* CLS::sm_instance = new CLS(); + + +#ifdef __VISUALC6__ + // "non dll-interface class 'xxx' used as base interface + #pragma warning (push) + #pragma warning (disable:4275) +#endif + +/** + Following are helper classes for the wxAnyValueTypeImplBase. +*/ +namespace wxPrivate +{ + +template +class wxAnyValueTypeOpsMovable +{ +public: + static void DeleteValue(wxAnyValueBuffer& buf) + { + wxUnusedVar(buf); + } + + static void SetValue(const T& value, + wxAnyValueBuffer& buf) + { + memcpy(buf.m_buffer, &value, sizeof(T)); + } + + static const T& GetValue(const wxAnyValueBuffer& buf) + { + return *(reinterpret_cast(&buf.m_buffer[0])); + } +}; + + +template +class wxAnyValueTypeOpsGeneric +{ +public: + template + class DataHolder + { + public: + DataHolder(const T2& value) + { + m_value = value; + } + virtual ~DataHolder() { } + + T2 m_value; + private: + wxDECLARE_NO_COPY_CLASS(DataHolder); + }; + + static void DeleteValue(wxAnyValueBuffer& buf) + { + DataHolder* holder = static_cast*>(buf.m_ptr); + delete holder; + } + + static void SetValue(const T& value, + wxAnyValueBuffer& buf) + { + DataHolder* holder = new DataHolder(value); + buf.m_ptr = holder; + } + + static const T& GetValue(const wxAnyValueBuffer& buf) + { + DataHolder* holder = static_cast*>(buf.m_ptr); + return holder->m_value; + } +}; + +} // namespace wxPrivate + + +/** + Intermediate template for the generic value type implementation. + We can derive from this same value type for multiple actual types + (for instance, we can have wxAnyValueTypeImplInt for all signed + integer types), and also easily implement specialized templates + with specific dynamic type conversion. +*/ +template +class wxAnyValueTypeImplBase : public wxAnyValueType +{ + typedef typename wxIf< wxIsMovable::value && + sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE, + wxPrivate::wxAnyValueTypeOpsMovable, + wxPrivate::wxAnyValueTypeOpsGeneric >::value + Ops; + +public: + wxAnyValueTypeImplBase() : wxAnyValueType() { } + virtual ~wxAnyValueTypeImplBase() { } + + virtual void DeleteValue(wxAnyValueBuffer& buf) const + { + Ops::DeleteValue(buf); + buf.m_ptr = NULL; // This is important + } + + virtual void CopyBuffer(const wxAnyValueBuffer& src, + wxAnyValueBuffer& dst) const + { + Ops::DeleteValue(dst); + Ops::SetValue(Ops::GetValue(src), dst); + } + + /** + It is important to reimplement this in any specialized template + classes that inherit from wxAnyValueTypeImplBase. + */ + static void SetValue(const T& value, + wxAnyValueBuffer& buf) + { + Ops::SetValue(value, buf); + } + + /** + It is important to reimplement this in any specialized template + classes that inherit from wxAnyValueTypeImplBase. + */ + static const T& GetValue(const wxAnyValueBuffer& buf) + { + return Ops::GetValue(buf); + } +}; + + +/* + Generic value type template. Note that bulk of the implementation + resides in wxAnyValueTypeImplBase. +*/ +template +class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +public: + wxAnyValueTypeImpl() : wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImpl() { } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const + { + wxUnusedVar(src); + wxUnusedVar(dstType); + wxUnusedVar(dst); + return false; + } +}; + +template +wxAnyValueTypeImpl* wxAnyValueTypeImpl::sm_instance = + new wxAnyValueTypeImpl(); + + +// +// Helper macro for using same base value type implementation for multiple +// actual C++ data types. +// +#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \ +template<> \ +class wxAnyValueTypeImpl : public wxAnyValueTypeImpl##CLSTYPE \ +{ \ + typedef wxAnyBase##CLSTYPE##Type UseDataType; \ +public: \ + wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \ + virtual ~wxAnyValueTypeImpl() { } \ + static void SetValue(const T& value, wxAnyValueBuffer& buf) \ + { \ + *(reinterpret_cast(&buf.m_buffer[0])) = \ + static_cast(value); \ + } \ + static T GetValue(const wxAnyValueBuffer& buf) \ + { \ + return static_cast( \ + *(reinterpret_cast(&buf.m_buffer[0]))); \ + } \ +}; + + +// +// Integer value types +// + +#ifdef wxLongLong_t + typedef wxLongLong_t wxAnyBaseIntType; + typedef wxULongLong_t wxAnyBaseUintType; +#else + typedef long wxAnyBaseIntType; + typedef unsigned long wxAnyBaseUintType; +#endif + + +class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt : + public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt) +public: + wxAnyValueTypeImplInt() : + wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImplInt() { } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const; +}; + + +class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint : + public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint) +public: + wxAnyValueTypeImplUint() : + wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImplUint() { } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const; +}; + + +WX_ANY_DEFINE_SUB_TYPE(signed long, Int) +WX_ANY_DEFINE_SUB_TYPE(signed int, Int) +WX_ANY_DEFINE_SUB_TYPE(signed short, Int) +WX_ANY_DEFINE_SUB_TYPE(signed char, Int) +#ifdef wxLongLong_t +WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int) +#endif + +WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint) +WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint) +WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint) +WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint) +#ifdef wxLongLong_t +WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint) +#endif + + +// +// String value type +// +class WXDLLIMPEXP_BASE wxAnyValueTypeImplString : + public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString) +public: + wxAnyValueTypeImplString() : + wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImplString() { } + + /** + Convert value into buffer of different type. Return false if + not possible. + */ + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const; + +}; + +template<> +class wxAnyValueTypeImpl : public wxAnyValueTypeImplString +{ +public: + wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { } + virtual ~wxAnyValueTypeImpl() { } +}; + + +// +// Bool value type +// +template<> +class WXDLLIMPEXP_BASE wxAnyValueTypeImpl : + public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +public: + wxAnyValueTypeImpl() : + wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImpl() { } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const; +}; + +// +// Floating point value type +// +class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble : + public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble) +public: + wxAnyValueTypeImplDouble() : + wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImplDouble() { } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const; +}; + +// WX_ANY_DEFINE_SUB_TYPE requires this +typedef double wxAnyBaseDoubleType; + +WX_ANY_DEFINE_SUB_TYPE(float, Double) +WX_ANY_DEFINE_SUB_TYPE(double, Double) + + +#ifdef __VISUALC6__ + // Re-enable useless VC6 warnings + #pragma warning (pop) +#endif + + +/* + Let's define a discrete Null value so we don't have to really + ever check if wxAny.m_type pointer is NULL or not. This is an + optimization, mostly. Implementation of this value type is + "hidden" in the source file. +*/ +extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType; + + +// +// We need to implement custom signed/unsigned int equals operators +// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work. +#define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \ +bool operator==(TS value) const \ +{ \ + if ( wxAnyValueTypeImpl::IsSameClass(m_type) ) \ + return (value == static_cast \ + (wxAnyValueTypeImpl::GetValue(m_buffer))); \ + if ( wxAnyValueTypeImpl::IsSameClass(m_type) ) \ + return (value == static_cast \ + (wxAnyValueTypeImpl::GetValue(m_buffer))); \ + return false; \ +} \ +bool operator==(TUS value) const \ +{ \ + if ( wxAnyValueTypeImpl::IsSameClass(m_type) ) \ + return (value == static_cast \ + (wxAnyValueTypeImpl::GetValue(m_buffer))); \ + if ( wxAnyValueTypeImpl::IsSameClass(m_type) ) \ + return (value == static_cast \ + (wxAnyValueTypeImpl::GetValue(m_buffer))); \ + return false; \ +} + + +// +// The wxAny class represents a container for any type. A variant's value +// can be changed at run time, possibly to a different type of value. +// +// As standard, wxAny can store value of almost any type, in a fairly +// optimal manner even. +// +class WXDLLIMPEXP_BASE wxAny +{ +public: + /** + Default constructor. + */ + wxAny() + { + m_type = wxAnyNullValueType; + } + + /** + Destructor. + */ + ~wxAny() + { + m_type->DeleteValue(m_buffer); + } + + //@{ + /** + Various constructors. + */ + wxAny(const char* value) + { + m_type = wxAnyNullValueType; + Assign(wxString(value)); + } + wxAny(const wchar_t* value) + { + m_type = wxAnyNullValueType; + Assign(wxString(value)); + } + + wxAny(const wxAny& any) + { + m_type = wxAnyNullValueType; + AssignAny(any); + } + + template + wxAny(const T& value) + { + m_type = wxAnyValueTypeImpl::sm_instance; + wxAnyValueTypeImpl::SetValue(value, m_buffer); + } + //@} + + /** + Use this template function for checking if this wxAny holds + a specific C++ data type. + + @remarks This template function does not work on some older compilers + (such as Visual C++ 6.0). For full compiler ccompatibility + please use wxANY_CHECK_TYPE(any, T) macro instead. + + @see wxAnyValueType::CheckType() + */ + // FIXME-VC6: remove this hack when VC6 is no longer supported + template + bool CheckType(T* = NULL) + { + return m_type->CheckType(); + } + + /** + Returns the value type as wxAnyValueType instance. + + @remarks You cannot reliably test whether two wxAnys are of + same value type by simply comparing return values + of wxAny::GetType(). Instead use + wxAnyValueType::CheckType() template function. + */ + const wxAnyValueType* GetType() const + { + return m_type; + } + + /** + Tests if wxAny is null (that is, whether there is data). + */ + bool IsNull() const + { + return (m_type == wxAnyNullValueType); + } + + /** + Makes wxAny null (that is, clears it). + */ + void MakeNull() + { + m_type->DeleteValue(m_buffer); + m_type = wxAnyNullValueType; + } + + //@{ + /** + Assignment operators. + */ + wxAny& operator=(const wxAny &any) + { + AssignAny(any); + return *this; + } + + template + wxAny& operator=(const T &value) + { + m_type->DeleteValue(m_buffer); + m_type = wxAnyValueTypeImpl::sm_instance; + wxAnyValueTypeImpl::SetValue(value, m_buffer); + return *this; + } + + wxAny& operator=(const char* value) + { Assign(wxString(value)); return *this; } + wxAny& operator=(const wchar_t* value) + { Assign(wxString(value)); return *this; } + //@} + + //@{ + /** + Equality operators. + */ + bool operator==(const wxString& value) const + { + if ( !wxAnyValueTypeImpl::IsSameClass(m_type) ) + return false; + + return value == + static_cast + (wxAnyValueTypeImpl::GetValue(m_buffer)); + } + + bool operator==(const char* value) const + { return (*this) == wxString(value); } + bool operator==(const wchar_t* value) const + { return (*this) == wxString(value); } + + // + // We need to implement custom signed/unsigned int equals operators + // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work. + WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char) + WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short) + WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int) + WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long) +#ifdef wxLongLong_t + WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t) +#endif + + bool operator==(float value) const + { + if ( !wxAnyValueTypeImpl::IsSameClass(m_type) ) + return false; + + return value == + static_cast + (wxAnyValueTypeImpl::GetValue(m_buffer)); + } + + bool operator==(double value) const + { + if ( !wxAnyValueTypeImpl::IsSameClass(m_type) ) + return false; + + return value == + static_cast + (wxAnyValueTypeImpl::GetValue(m_buffer)); + } + + bool operator==(bool value) const + { + if ( !wxAnyValueTypeImpl::IsSameClass(m_type) ) + return false; + + return value == (wxAnyValueTypeImpl::GetValue(m_buffer)); + } + + //@} + + //@{ + /** + Inequality operators (implement as template). + */ + template + bool operator!=(const T& value) const + { return !((*this) == value); } + //@} + + /** + This template function converts wxAny into given type. No dynamic + conversion is performed, so if the type is incorrect an assertion + failure will occur in debug builds, and a bogus value is returned + in release ones. + + @remarks This template function does not work on some older compilers + (such as Visual C++ 6.0). For full compiler ccompatibility + please use wxANY_AS(any, T) macro instead. + */ + // FIXME-VC6: remove this hack when VC6 is no longer supported + template + T As(T* = NULL) const + { + if ( !wxAnyValueTypeImpl::IsSameClass(m_type) ) + wxFAIL_MSG("Incorrect or non-convertible data type"); + return static_cast(wxAnyValueTypeImpl::GetValue(m_buffer)); + } + + /** + Template function that etrieves and converts the value of this + variant to the type that T* value is. + + @return Returns @true if conversion was succesfull. + */ + template + bool GetAs(T* value) const + { + if ( !wxAnyValueTypeImpl::IsSameClass(m_type) ) + { + wxAnyValueType* otherType = + wxAnyValueTypeImpl::sm_instance; + wxAnyValueBuffer temp_buf; + + if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) ) + return false; + + *value = + static_cast(wxAnyValueTypeImpl::GetValue(temp_buf)); + otherType->DeleteValue(temp_buf); + + return true; + } + *value = static_cast(wxAnyValueTypeImpl::GetValue(m_buffer)); + return true; + } + +private: + // Assignment functions + void AssignAny(const wxAny &any); + + template + void Assign(const T &value) + { + m_type->DeleteValue(m_buffer); + m_type = wxAnyValueTypeImpl::sm_instance; + wxAnyValueTypeImpl::SetValue(value, m_buffer); + } + + // Data + wxAnyValueType* m_type; + wxAnyValueBuffer m_buffer; +}; + + +// +// This method of checking the type is compatible with VC6 +#define wxANY_CHECK_TYPE(any, T) \ + wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T) + + +// +// This method of getting the value is compatible with VC6 +#define wxANY_AS(any, T) \ + any.As(static_cast(NULL)) + + +template +inline bool wxAnyValueType::CheckType(T* reserved) +{ + wxUnusedVar(reserved); + return wxAnyValueTypeImpl::IsSameClass(this); +} + + + +#endif // wxUSE_ANY + +#endif // _WX_ANY_H_ diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index 95bba3811a..0d4f0b008c 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -68,6 +68,14 @@ please keep the options in alphabetical order! */ +#ifndef wxUSE_ANY +# ifdef wxABORT_ON_CONFIG_ERROR +# error "wxUSE_ANY must be defined." +# else +# define wxUSE_ANY 0 +# endif +#endif /* wxUSE_ANY */ + #ifndef wxUSE_CONSOLE_EVENTLOOP # ifdef wxABORT_ON_CONFIG_ERROR # error "wxUSE_CONSOLE_EVENTLOOP must be defined." diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 60f67f7312..9deacf6e96 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -570,6 +570,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/include/wx/msw/wince/setup.h b/include/wx/msw/wince/setup.h index f13813b574..e9d70cee44 100644 --- a/include/wx/msw/wince/setup.h +++ b/include/wx/msw/wince/setup.h @@ -570,6 +570,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/include/wx/os2/setup0.h b/include/wx/os2/setup0.h index 48ccfd6c52..5403761a21 100644 --- a/include/wx/os2/setup0.h +++ b/include/wx/os2/setup0.h @@ -570,6 +570,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/include/wx/osx/setup0.h b/include/wx/osx/setup0.h index 1783604b04..2af5514a2f 100644 --- a/include/wx/osx/setup0.h +++ b/include/wx/osx/setup0.h @@ -571,6 +571,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/include/wx/palmos/setup0.h b/include/wx/palmos/setup0.h index 18ca37e61c..33b7c3fa88 100644 --- a/include/wx/palmos/setup0.h +++ b/include/wx/palmos/setup0.h @@ -570,6 +570,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index cc24179174..b014a90b88 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -566,6 +566,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/include/wx/univ/setup0.h b/include/wx/univ/setup0.h index 7a270163cb..7f9cb99638 100644 --- a/include/wx/univ/setup0.h +++ b/include/wx/univ/setup0.h @@ -569,6 +569,14 @@ // possible in which case setting this to 0 can gain up to 100KB. #define wxUSE_VARIANT 1 +// Support for wxAny class, the successor for wxVariant. +// +// Default is 1. +// +// Recommended setting: 1 unless you want to reduce the library size by a small amount, +// or your compiler cannot for some reason cope with complexity of templates used. +#define wxUSE_ANY 1 + // Support for regular expression matching via wxRegEx class: enable this to // use POSIX regular expressions in your code. You need to compile regex // library from src/regex to use it under Windows. diff --git a/interface/wx/any.h b/interface/wx/any.h new file mode 100644 index 0000000000..9dc3442018 --- /dev/null +++ b/interface/wx/any.h @@ -0,0 +1,425 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: any.h +// Purpose: interface of wxAny +// Author: wxWidgets team +// RCS-ID: $Id$ +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + + +/** + @class wxAny + + The wxAny class represents a container for any type. Its value + can be changed at run time, possibly to a different type of value. + + wxAny is successor class for wxVariant, essentially doing the same thing + in a more modern, template-based manner and with transparent support + for any user data type. + + Some pseudo-code'ish example of use with arbitrary user data: + + @code + void SomeFunction() + { + MyClass myObject; + wxAny any = myObject; + + // Do something + // ... + + // Let's do a sanity check to make sure that any still holds + // data of correct type. + if ( any.CheckType() ) + { + // Thank goodness, still a correct type. + MyClass myObject2 = any.As(); + } + else + { + // Something has gone horribly wrong! + wxFAIL(); + } + } + @endcode + + When compared to wxVariant, there are various internal implementation + differences as well. For instance, wxAny only allocates separate data + object in heap for large (ie. size in bytes more than + WX_ANY_VALUE_BUFFER_SIZE) or 'non-movable' data types. Pointers, integers, + bools etc. are fitted in the wxAny's own buffer without need for any extra + allocation. Use following code to declare your own data type as 'movable': + + @code + #include "wx/meta/movable.h" + WX_DECLARE_TYPE_MOVABLE(MyClass) + @endcode + + However, you must be aware that 'movable' means such data that can be + copied with memcpy() without corrupting program integrity. For instance, + movable objects usually cannot contain pointers or references to other + data. wxRect, wxPoint, and wxSize are good examples of movable classes. + + Note that pointers to any and all classes are already automatically + declared as movable data. + + @library{wxbase} + @category{data} + + @see wxAnyValueType, wxVariant +*/ +class wxAny +{ +public: + /** + Default constructor. It seeds the object with a null value. + */ + wxAny(); + + /** + Constructs wxAny from data. + */ + template + wxAny(const T& value); + + /** + Constructs wxAny from another wxAny. + */ + wxAny(const wxAny& any); + + /** + Destructor. + */ + ~wxAny(); + + /** + This template function converts wxAny into given type. No dynamic + conversion is performed, so if the type is incorrect an assertion + failure will occur in debug builds, and a bogus value is returned + in release ones. + + @remarks This template function may not work properly with Visual C++ + 6. For full compiler compatibility, please use + wxANY_AS(any, T) macro instead. + */ + template + T As() const; + + /** + Use this template function for checking if this wxAny holds + a specific C++ data type. + + @remarks This template function may not work properly with Visual C++ + 6. For full compiler compatibility, please use + wxANY_CHECK_TYPE(any, T) macro instead. + + @see wxAnyValueType::CheckType() + */ + template + bool CheckType(); + + /** + Template function that retrieves and converts the value of this + wxAny to the type that T* value is. + + @return Returns @true if conversion was succesfull. + */ + template + bool GetAs(T* value) const; + + /** + Returns the value type as wxAnyValueType instance. + + @remarks You cannot reliably test whether two wxAnys are of + same value type by simply comparing return values + of wxAny::GetType(). Instead use + wxAnyValueType::CheckType() template function. + */ + const wxAnyValueType* GetType() const; + + /** + Tests if wxAny is null (that is, whether there is data). + */ + bool IsNull() const; + + /** + Makes wxAny null (that is, clears it). + */ + void MakeNull(); + + //@{ + /** + @name Assignment operators + */ + template + wxAny& operator=(const T &value); + wxAny& operator=(const wxAny &any); + //@} + + //@{ + /** + @name Equality operators + + @remarks Generic template-based comparison operators have not been + provided for various code consistency reasons, so for custom + data types you have do something like this: + + @code + if ( any.CheckType() && + any.As() == myObjectPtr ) + { + // Do something if any stores myObjectPtr + } + @endcode + */ + bool operator==(signed char value) const; + bool operator==(signed short value) const; + bool operator==(signed int value) const; + bool operator==(signed long value) const; + bool operator==(wxLongLong_t value) const; + bool operator==(unsigned char value) const; + bool operator==(unsigned short value) const; + bool operator==(unsigned int value) const; + bool operator==(unsigned long value) const; + bool operator==(wxULongLong_t value) const; + bool operator==(float value) const; + bool operator==(double value) const; + bool operator==(bool value) const; + bool operator==(const char* value) const; + bool operator==(const wchar_t* value) const; + bool operator==(const wxString& value) const; + //@} + + //@{ + /** + @name Inequality operators + */ + bool operator!=(signed char value) const; + bool operator!=(signed short value) const; + bool operator!=(signed int value) const; + bool operator!=(signed long value) const; + bool operator!=(wxLongLong_t value) const; + bool operator!=(unsigned char value) const; + bool operator!=(unsigned short value) const; + bool operator!=(unsigned int value) const; + bool operator!=(unsigned long value) const; + bool operator!=(wxULongLong_t value) const; + bool operator!=(float value) const; + bool operator!=(double value) const; + bool operator!=(bool value) const; + bool operator!=(const char* value) const; + bool operator!=(const wchar_t* value) const; + bool operator!=(const wxString& value) const; + //@} +}; + +/** + This is value getter macro that is more compatible with older + compilers, such as Visual C++ 6.0. +*/ +#define wxANY_AS(any, T) + + +/** + This is type checking macro that is more compatible with older + compilers, such as Visual C++ 6.0. +*/ +#define wxANY_CHECK_TYPE(any, T) + + +/** + Size of the wxAny value buffer. +*/ +enum +{ + WX_ANY_VALUE_BUFFER_SIZE = 16 +}; + +/** + Type for buffer within wxAny for holding data. +*/ +union wxAnyValueBuffer +{ + void* m_ptr; + wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE]; +}; + + +/** + @class wxAnyValueType + + wxAnyValueType is base class for value type functionality for C++ data + types used with wxAny. Usually the default template will create a + satisfactory wxAnyValueType implementation for a data type, but + sometimes you may need to add some customization. To do this you will need + to add specialized template of wxAnyValueTypeImpl<>. Often your only + need may be to add dynamic type conversion which would be done like + this: + + @code + template<> + class wxAnyValueTypeImpl : + public wxAnyValueTypeImplBase + { + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + public: + wxAnyValueTypeImpl() : + wxAnyValueTypeImplBase() { } + virtual ~wxAnyValueTypeImpl() { } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const + { + // GetValue() is a static member function implemented + // in wxAnyValueTypeImplBase<>. + MyClass value = GetValue(src); + + // TODO: Convert value from src buffer to destination + // type and buffer. If cannot be done, return + // false. This is a simple sample. + if ( dstType->CheckType() ) + { + wxString s = value.ToString(); + wxAnyValueTypeImpl::SetValue(s, dst); + } + else + { + return false; + } + } + }; + + // + // Following must be placed somewhere in your source code + WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + @endcode + + wxAnyValueTypeImplBase<> template, from which we inherit in the above + example, contains the bulk of the default wxAnyValueTypeImpl<> template + implementation, and as such allows you to easily add some minor + customization. + + If you need a have complete control over the type interpretation, you + will need to derive a class directly from wxAnyValueType, like this: + + @code + template <> + class wxAnyValueTypeImpl : public wxAnyValueType + { + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + public: + virtual void DeleteValue(wxAnyValueBuffer& buf) const + { + // TODO: Free the data in buffer + // It is important to clear the buffer like this + // at the end of DeleteValue(). + buf.m_ptr = NULL; + } + + virtual void CopyBuffer(const wxAnyValueBuffer& src, + wxAnyValueBuffer& dst) const + { + // TODO: Copy value from one buffer to another. + } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const + { + // TODO: Convert value from src buffer to destination + // type and buffer. + } + + // + // Following static functions must be implemented + // + + static void SetValue(const T& value, + wxAnyValueBuffer& buf) + { + // TODO: Store value into buf. + } + + static const T& GetValue(const wxAnyValueBuffer& buf) + { + // TODO: Return reference to value stored in buffer. + } + }; + + // + // Following must be placed somewhere in your source code + WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + + @endcode + + @library{wxbase} + @category{data} + + @see wxAny +*/ +class wxAnyValueType +{ +public: + /** + Default constructor. + */ + wxAnyValueType(); + + /** + Destructor. + */ + virtual ~wxAnyValueType(); + + /** + Use this template function for checking if wxAnyValueType represents + a specific C++ data type. + + @remarks This template function does not work on some older compilers + (such as Visual C++ 6.0). For full compiler ccompatibility + please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro + instead. + + @see wxAny::CheckType() + */ + template + bool CheckType(); + + /** + Convert value into buffer of different type. Return false if + not possible. + */ + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const = 0; + + /** + Implement this for buffer-to-buffer copy. src.m_ptr can + be expected to be NULL if value type of previously stored + data was different. + */ + virtual void CopyBuffer(const wxAnyValueBuffer& src, + wxAnyValueBuffer& dst) const = 0; + + /** + This function is called every time the data in wxAny + buffer needs to be freed. + */ + 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. + */ + virtual bool IsSameType(const wxAnyValueType* otherType) const = 0; +}; + +/** + This is type checking macro that is more compatible with older + compilers, such as Visual C++ 6.0. +*/ +#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) diff --git a/setup.h.in b/setup.h.in index 117d7b5542..2ec082aec9 100644 --- a/setup.h.in +++ b/setup.h.in @@ -294,6 +294,8 @@ #define wxUSE_VARIANT 0 +#define wxUSE_ANY 0 + #define wxUSE_REGEX 0 #define wxUSE_SYSTEM_OPTIONS 0 diff --git a/setup.h_vms b/setup.h_vms index 08f7070753..670bef3763 100644 --- a/setup.h_vms +++ b/setup.h_vms @@ -315,6 +315,8 @@ typedef pid_t GPid; #define wxUSE_VARIANT 1 +#define wxUSE_ANY 1 + #define wxUSE_REGEX 0 #define wxUSE_SYSTEM_OPTIONS 1 diff --git a/src/common/any.cpp b/src/common/any.cpp new file mode 100644 index 0000000000..62f6b45d08 --- /dev/null +++ b/src/common/any.cpp @@ -0,0 +1,402 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/common/any.cpp +// Purpose: wxAny class, container for any type +// Author: Jaakko Salli +// Modified by: +// Created: 07/05/2009 +// RCS-ID: $Id$ +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/any.h" + +#if wxUSE_ANY + +#ifndef WX_PRECOMP + #include "wx/math.h" + #include "wx/crt.h" +#endif + +#include "wx/vector.h" +#include "wx/module.h" + +using namespace wxPrivate; + +//------------------------------------------------------------------------- +// wxAnyValueTypeGlobals +//------------------------------------------------------------------------- + +// +// Helper class to manage wxAnyValueType instances and other +// related global variables. +// +// NB: We really need to have wxAnyValueType instances allocated +// in heap. They are stored as static template member variables, +// and with them we just can't be too careful (eg. not allocating +// them in heap broke the type identification in GCC). +// +class wxAnyValueTypeGlobals +{ +public: + wxAnyValueTypeGlobals() + { + } + ~wxAnyValueTypeGlobals() + { + for ( size_t i=0; i m_valueTypes; +}; + +static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL; + +// +// This class is to make sure that wxAnyValueType instances +// etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals +// because wxModule itself is instantiated too late. +// +class wxAnyValueTypeGlobalsManager : public wxModule +{ + DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager) +public: + wxAnyValueTypeGlobalsManager() : wxModule() { } + virtual ~wxAnyValueTypeGlobalsManager() { } + + virtual bool OnInit() + { + return true; + } + virtual void OnExit() + { + delete g_wxAnyValueTypeGlobals; + g_wxAnyValueTypeGlobals = NULL; + } +private: +}; + +IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule) + + +//------------------------------------------------------------------------- +// wxAnyValueType +//------------------------------------------------------------------------- + +wxAnyValueType::wxAnyValueType() +{ + if ( !g_wxAnyValueTypeGlobals ) + g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals(); + + g_wxAnyValueTypeGlobals->RegisterValueType(this); +} + +//------------------------------------------------------------------------- +// wxAny +//------------------------------------------------------------------------- + +void wxAny::AssignAny(const wxAny &any) +{ + if ( !any.m_type->IsSameType(m_type) ) + { + m_type->DeleteValue(m_buffer); + m_type = any.m_type; + } + m_type->CopyBuffer(any.m_buffer, m_buffer); +} + +//------------------------------------------------------------------------- +// Dynamic conversion member functions +//------------------------------------------------------------------------- + +// +// Define integer minimum and maximum as helpers +#ifdef wxLongLong_t +const wxAnyBaseIntType UseIntMin = wxINT64_MIN; +const wxAnyBaseUintType UseIntMax = wxINT64_MAX; +const wxAnyBaseUintType UseUintMax = wxUINT64_MAX; +#else +const wxAnyBaseIntType UseIntMin = LONG_MIN; +const wxAnyBaseUintType UseUintMax = ULONG_MAX; +const wxAnyBaseUintType UseIntMax = LONG_MAX; +#endif + +const double UseIntMinF = static_cast(UseIntMin); +#ifndef __VISUALC6__ +const double UseIntMaxF = static_cast(UseIntMax); +const double UseUintMaxF = static_cast(UseUintMax); +#else +// VC6 doesn't implement conversion from unsigned __int64 to double +const wxAnyBaseIntType UseIntMax0 = static_cast(UseIntMax); +const wxAnyBaseIntType UseUintMax0 = static_cast(UseUintMax); +const double UseIntMaxF = static_cast(UseIntMax0); +const double UseUintMaxF = static_cast(UseUintMax0); +#endif + + +bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const +{ + wxAnyBaseIntType value = GetValue(src); + if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) + { +#ifdef wxLongLong_t + wxLongLong ll(value); + wxString s = ll.ToString(); +#else + wxString s = wxString::Format(wxS("%ld"), (long)value); +#endif + wxAnyValueTypeImpl::SetValue(s, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) + { + if ( value < 0 ) + return false; + wxAnyBaseUintType ul = (wxAnyBaseUintType) value; + wxAnyValueTypeImplUint::SetValue(ul, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) ) + { + double value2 = static_cast(value); + wxAnyValueTypeImplDouble::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) + { + bool value2 = value ? true : false; + wxAnyValueTypeImpl::SetValue(value2, dst); + } + else + return false; + + return true; +} + +bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const +{ + wxAnyBaseUintType value = GetValue(src); + if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) + { +#ifdef wxLongLong_t + wxULongLong ull(value); + wxString s = ull.ToString(); +#else + wxString s = wxString::Format(wxS("%lu"), (long)value); +#endif + wxAnyValueTypeImpl::SetValue(s, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) + { + if ( value > UseIntMax ) + return false; + wxAnyBaseIntType l = (wxAnyBaseIntType) value; + wxAnyValueTypeImplInt::SetValue(l, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) ) + { +#ifndef __VISUALC6__ + double value2 = static_cast(value); +#else + // VC6 doesn't implement conversion from unsigned __int64 to double + wxAnyBaseIntType value0 = static_cast(value); + double value2 = static_cast(value0); +#endif + wxAnyValueTypeImplDouble::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) + { + bool value2 = value ? true : false; + wxAnyValueTypeImpl::SetValue(value2, dst); + } + else + return false; + + return true; +} + +bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const +{ + wxString value = GetValue(src); + if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) + { + wxAnyBaseIntType value2; +#ifdef wxLongLong_t + if ( !value.ToLongLong(&value2) ) +#else + if ( !value.ToLong(&value2) ) +#endif + return false; + wxAnyValueTypeImplInt::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) + { + wxAnyBaseUintType value2; +#ifdef wxLongLong_t + if ( !value.ToULongLong(&value2) ) +#else + if ( !value.ToULong(&value2) ) +#endif + return false; + wxAnyValueTypeImplUint::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) ) + { + double value2; + if ( !value.ToDouble(&value2) ) + return false; + wxAnyValueTypeImplDouble::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) + { + bool value2; + value.MakeLower(); + if ( value == wxS("true") || + value == wxS("yes") || + value == wxS('1') ) + value2 = true; + else if ( value == wxS("false") || + value == wxS("no") || + value == wxS('0') ) + value2 = false; + else + return false; + + wxAnyValueTypeImpl::SetValue(value2, dst); + } + else + return false; + + return true; +} + +bool wxAnyValueTypeImpl::ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const +{ + bool value = GetValue(src); + if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) + { + wxAnyBaseIntType value2 = static_cast(value); + wxAnyValueTypeImplInt::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) + { + wxAnyBaseIntType value2 = static_cast(value); + wxAnyValueTypeImplUint::SetValue(value2, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) + { + wxString s; + if ( value ) + s = wxS("true"); + else + s = wxS("false"); + wxAnyValueTypeImpl::SetValue(s, dst); + } + else + return false; + + return true; +} + +bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const +{ + double value = GetValue(src); + if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) + { + if ( value < UseIntMinF || value > UseIntMaxF ) + return false; + wxAnyBaseUintType ul = static_cast(value); + wxAnyValueTypeImplUint::SetValue(ul, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) + { + if ( value < 0.0 || value > UseUintMaxF ) + return false; + wxAnyBaseUintType ul = static_cast(value); + wxAnyValueTypeImplUint::SetValue(ul, dst); + } + else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) + { + wxString s = wxString::Format(wxS("%.14g"), value); + wxAnyValueTypeImpl::SetValue(s, dst); + } + else + return false; + + return true; +} + +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt) +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint) +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString) +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble) + +//------------------------------------------------------------------------- +// wxAnyNullValueType implementation +//------------------------------------------------------------------------- + +class wxAnyNullValue +{ +private: + void* m_dummy; +}; + +template <> +class wxAnyValueTypeImpl : public wxAnyValueType +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +public: + virtual void DeleteValue(wxAnyValueBuffer& buf) const + { + buf.m_ptr = NULL; // This is important + } + + // Dummy implementations + virtual void CopyBuffer(const wxAnyValueBuffer& src, + wxAnyValueBuffer& dst) const + { + wxUnusedVar(src); + wxUnusedVar(dst); + } + + virtual bool ConvertValue(const wxAnyValueBuffer& src, + wxAnyValueType* dstType, + wxAnyValueBuffer& dst) const + { + wxUnusedVar(src); + wxUnusedVar(dstType); + wxUnusedVar(dst); + return false; + } + +private: +}; + +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + +wxAnyValueType* wxAnyNullValueType = + wxAnyValueTypeImpl::GetInstance(); + +#endif // wxUSE_ANY diff --git a/src/common/descrip.mms b/src/common/descrip.mms index 6e302a5319..c47371405d 100644 --- a/src/common/descrip.mms +++ b/src/common/descrip.mms @@ -212,7 +212,8 @@ OBJECTS2=tbarbase.obj,srchcmn.obj,\ listctrlcmn.obj,socketiohandler.obj,fdiodispatcher.obj,\ selectdispatcher.obj,overlaycmn.obj,windowid.obj,sstream.obj,\ wrapsizer.obj,headerctrlcmn.obj,headercolcmn.obj,\ - rearrangectrl.obj,spinctrlcmn.obj,datetimefmt.obj,xlocale.obj + rearrangectrl.obj,spinctrlcmn.obj,datetimefmt.obj,xlocale.obj,\ + any.obj OBJECTS_MOTIF=radiocmn.obj,combocmn.obj @@ -229,6 +230,7 @@ SOURCES = \ accelcmn.cpp,\ anidecod.cpp,\ animatecmn.cpp,\ + any.cpp,\ appbase.cpp,\ appcmn.cpp,\ arrstr.cpp,\ @@ -459,6 +461,7 @@ $(OBJECTS_MOTIF) : [--.include.wx]setup.h accelcmn.obj : accelcmn.cpp anidecod.obj : anidecod.cpp animatecmn.obj : animatecmn.cpp +any.obj : any.cpp appbase.obj : appbase.cpp appcmn.obj : appcmn.cpp arrstr.obj : arrstr.cpp diff --git a/tests/Makefile.in b/tests/Makefile.in index fcc3680ff7..7291842378 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -54,6 +54,7 @@ TEST_CXXFLAGS = $(__test_PCH_INC) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \ $(CPPUNIT_CFLAGS) $(CXXWARNINGS) $(CPPFLAGS) $(CXXFLAGS) TEST_OBJECTS = \ test_test.o \ + test_anytest.o \ test_archivetest.o \ test_ziptest.o \ test_tartest.o \ @@ -346,6 +347,9 @@ fr: test_test.o: $(srcdir)/test.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/test.cpp +test_anytest.o: $(srcdir)/any/anytest.cpp $(TEST_ODEP) + $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/any/anytest.cpp + test_archivetest.o: $(srcdir)/archive/archivetest.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/archive/archivetest.cpp diff --git a/tests/any/anytest.cpp b/tests/any/anytest.cpp new file mode 100644 index 0000000000..4b05691644 --- /dev/null +++ b/tests/any/anytest.cpp @@ -0,0 +1,431 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class wxAnyTestCase : public CppUnit::TestCase +{ +public: + wxAnyTestCase(); + +private: + CPPUNIT_TEST_SUITE( wxAnyTestCase ); + CPPUNIT_TEST( Equality ); + CPPUNIT_TEST( As ); + CPPUNIT_TEST( GetAs ); + CPPUNIT_TEST( Null ); + CPPUNIT_TEST( CustomTemplateSpecialization ); + CPPUNIT_TEST_SUITE_END(); + + void Equality(); + void As(); + void GetAs(); + void Null(); + void CustomTemplateSpecialization(); + + 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_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 it's 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 double TEST_FLOAT_CONST = 123.456; + +const double FEQ_DELTA = 0.001; + +wxObject* dummyWxObjectPointer = reinterpret_cast(1234); +void* dummyVoidPointer = reinterpret_cast(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((float)TEST_FLOAT_CONST), + m_anyDoubleDouble1((double)TEST_FLOAT_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 = (float)TEST_FLOAT_CONST; + m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST; + m_anyDateTime2 = m_testDateTime; + m_anyWxObjectPtr2 = dummyWxObjectPointer; + m_anyVoidPtr2 = dummyVoidPointer; +} + +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(m_anyWxObjectPtr1.As() == dummyWxObjectPointer); + CPPUNIT_ASSERT(m_anyVoidPtr1.As() == 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(m_anyWxObjectPtr2.As() == dummyWxObjectPointer); + CPPUNIT_ASSERT(m_anyVoidPtr2.As() == dummyVoidPointer); +} + +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); + CPPUNIT_ASSERT(l == "abc"); + wxString m = wxANY_AS(m_anyWcharString1, wxString); + CPPUNIT_ASSERT(m == "abc"); + bool n = wxANY_AS(m_anyBool1, bool); + CPPUNIT_ASSERT(n); + float o = wxANY_AS(m_anyFloatDouble1, float); + CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA); + double p = wxANY_AS(m_anyDoubleDouble1, double); + CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA); + 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; + 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 + res = m_anySignedLong1.GetAs(&ul); + CPPUNIT_ASSERT(res); + CPPUNIT_ASSERT_EQUAL(ul, static_cast(15)); + 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(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(15)); + res = anyString.GetAs(&ul); + CPPUNIT_ASSERT(res); + CPPUNIT_ASSERT_EQUAL(ul, static_cast(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(1)); + res = m_anyBool1.GetAs(&ul); + CPPUNIT_ASSERT(res); + CPPUNIT_ASSERT_EQUAL(ul, static_cast(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(123)); + res = m_anyDoubleDouble1.GetAs(&ul); + CPPUNIT_ASSERT(res); + CPPUNIT_ASSERT_EQUAL(ul, static_cast(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 specialization of wxAnyValueTypeImpl +// + +class MyClass +{ +public: + MyClass( int someValue = 32768 ) + { + m_someValue = someValue; + } + + wxString ToString() + { + return wxString::Format("%i", m_someValue); + } + +private: + int m_someValue; +}; + + +template<> +class wxAnyValueTypeImpl : + public wxAnyValueTypeImplBase +{ + WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl) +public: + wxAnyValueTypeImpl() : + wxAnyValueTypeImplBase() { } + 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::SetValue(s, dst); + } + else + return false; + + return true; + } +}; + +// +// Following must be placed somewhere in your source code +WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl) + +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()); +} + +#endif // wxUSE_ANY + diff --git a/tests/makefile.bcc b/tests/makefile.bcc index 77e128c2ba..eb3cc79ecd 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -38,6 +38,7 @@ TEST_CXXFLAGS = $(__RUNTIME_LIBS) -I$(BCCDIR)\include $(__DEBUGINFO) \ TEST_OBJECTS = \ $(OBJS)\test_dummy.obj \ $(OBJS)\test_test.obj \ + $(OBJS)\test_anytest.obj \ $(OBJS)\test_archivetest.obj \ $(OBJS)\test_ziptest.obj \ $(OBJS)\test_tartest.obj \ @@ -378,6 +379,9 @@ $(OBJS)\test_dummy.obj: .\dummy.cpp $(OBJS)\test_test.obj: .\test.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\test.cpp +$(OBJS)\test_anytest.obj: .\any\anytest.cpp + $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\any\anytest.cpp + $(OBJS)\test_archivetest.obj: .\archive\archivetest.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\archive\archivetest.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index 08f2802a74..bdfd9ecd1f 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -30,6 +30,7 @@ TEST_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) $(GCCFLAGS) \ TEST_OBJECTS = \ $(OBJS)\test_dummy.o \ $(OBJS)\test_test.o \ + $(OBJS)\test_anytest.o \ $(OBJS)\test_archivetest.o \ $(OBJS)\test_ziptest.o \ $(OBJS)\test_tartest.o \ @@ -359,6 +360,9 @@ $(OBJS)\test_dummy.o: ./dummy.cpp $(OBJS)\test_test.o: ./test.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_anytest.o: ./any/anytest.cpp + $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_archivetest.o: ./archive/archivetest.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index 92c2b269a2..6dc5ddc78c 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -31,6 +31,7 @@ TEST_CXXFLAGS = /M$(__RUNTIME_LIBS_8)$(__DEBUGRUNTIME) /DWIN32 $(__DEBUGINFO) \ TEST_OBJECTS = \ $(OBJS)\test_dummy.obj \ $(OBJS)\test_test.obj \ + $(OBJS)\test_anytest.obj \ $(OBJS)\test_archivetest.obj \ $(OBJS)\test_ziptest.obj \ $(OBJS)\test_tartest.obj \ @@ -461,6 +462,9 @@ $(OBJS)\test_dummy.obj: .\dummy.cpp $(OBJS)\test_test.obj: .\test.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\test.cpp +$(OBJS)\test_anytest.obj: .\any\anytest.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\any\anytest.cpp + $(OBJS)\test_archivetest.obj: .\archive\archivetest.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\archive\archivetest.cpp diff --git a/tests/makefile.wat b/tests/makefile.wat index bdaba4b6d0..b5164a0f18 100644 --- a/tests/makefile.wat +++ b/tests/makefile.wat @@ -259,6 +259,7 @@ TEST_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) & TEST_OBJECTS = & $(OBJS)\test_dummy.obj & $(OBJS)\test_test.obj & + $(OBJS)\test_anytest.obj & $(OBJS)\test_archivetest.obj & $(OBJS)\test_ziptest.obj & $(OBJS)\test_tartest.obj & @@ -416,6 +417,9 @@ $(OBJS)\test_dummy.obj : .AUTODEPEND .\dummy.cpp $(OBJS)\test_test.obj : .AUTODEPEND .\test.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< +$(OBJS)\test_anytest.obj : .AUTODEPEND .\any\anytest.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< + $(OBJS)\test_archivetest.obj : .AUTODEPEND .\archive\archivetest.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< diff --git a/tests/test.bkl b/tests/test.bkl index 80c71cce9b..d692755fa3 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -29,6 +29,7 @@ template_append="wx_append_base"> test.cpp + any/anytest.cpp archive/archivetest.cpp archive/ziptest.cpp archive/tartest.cpp diff --git a/tests/test_test.dsp b/tests/test_test.dsp index 031f525889..2ccdd77129 100644 --- a/tests/test_test.dsp +++ b/tests/test_test.dsp @@ -235,6 +235,10 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File +SOURCE=.\any\anytest.cpp +# End Source File +# Begin Source File + SOURCE=.\archive\archivetest.cpp # End Source File # Begin Source File diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj index cc848ea3bf..75e9df0f90 100644 --- a/tests/test_vc7_test.vcproj +++ b/tests/test_vc7_test.vcproj @@ -557,6 +557,9 @@ Name="Source Files" Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + + diff --git a/tests/test_vc8_test.vcproj b/tests/test_vc8_test.vcproj index e8fccf8fbf..8e9f601b2b 100644 --- a/tests/test_vc8_test.vcproj +++ b/tests/test_vc8_test.vcproj @@ -819,6 +819,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + diff --git a/tests/test_vc9_test.vcproj b/tests/test_vc9_test.vcproj index 55021dba01..160f9e9f97 100644 --- a/tests/test_vc9_test.vcproj +++ b/tests/test_vc9_test.vcproj @@ -791,6 +791,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + diff --git a/wxGTK.spec b/wxGTK.spec index 3201cb8f96..360a94825e 100644 --- a/wxGTK.spec +++ b/wxGTK.spec @@ -206,6 +206,7 @@ rm -rf $RPM_BUILD_ROOT # --- wxBase headers list begins here --- cat <wxbase-headers.files wx/afterstd.h +wx/any.h wx/anystr.h wx/app.h wx/apptrait.h diff --git a/wxMotif.spec b/wxMotif.spec index d40578bfdf..dd9c15d14d 100644 --- a/wxMotif.spec +++ b/wxMotif.spec @@ -111,6 +111,7 @@ rm -rf $RPM_BUILD_ROOT # --- wxBase headers list begins here --- cat <wxbase-headers.files wx/afterstd.h +wx/any.h wx/anystr.h wx/app.h wx/apptrait.h diff --git a/wxX11.spec b/wxX11.spec index e28c0d4b17..2e604a33a0 100644 --- a/wxX11.spec +++ b/wxX11.spec @@ -135,6 +135,7 @@ rm -rf $RPM_BUILD_ROOT # --- wxBase headers list begins here --- cat <wxbase-headers.files wx/afterstd.h +wx/any.h wx/anystr.h wx/app.h wx/apptrait.h -- 2.45.2