diff --git a/Makefile.in b/Makefile.in index 8f0abc7312..8f5e004d6c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -471,6 +471,7 @@ ALL_BASE_HEADERS = \ wx/meta/if.h \ wx/meta/int2type.h \ wx/meta/movable.h \ + wx/meta/pod.h \ wx/fswatcher.h \ wx/generic/fswatcher.h \ $(BASE_PLATFORM_HDR) \ @@ -639,6 +640,7 @@ ALL_PORTS_BASE_HEADERS = \ wx/meta/if.h \ wx/meta/int2type.h \ wx/meta/movable.h \ + wx/meta/pod.h \ wx/fswatcher.h \ wx/generic/fswatcher.h \ wx/unix/app.h \ diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index e13803eb0d..b118663962 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -556,6 +556,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/meta/if.h wx/meta/int2type.h wx/meta/movable.h + wx/meta/pod.h wx/fswatcher.h wx/generic/fswatcher.h diff --git a/build/msw/wx_base.dsp b/build/msw/wx_base.dsp index fcb0246ac4..3880a5314c 100644 --- a/build/msw/wx_base.dsp +++ b/build/msw/wx_base.dsp @@ -1423,6 +1423,10 @@ SOURCE=..\..\include\wx\platinfo.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\meta\pod.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\power.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_base.vcproj b/build/msw/wx_vc7_base.vcproj index 14b0613c64..44bd7cc4e0 100644 --- a/build/msw/wx_vc7_base.vcproj +++ b/build/msw/wx_vc7_base.vcproj @@ -1499,6 +1499,9 @@ + + diff --git a/build/msw/wx_vc8_base.vcproj b/build/msw/wx_vc8_base.vcproj index a54045eda0..23726bbf50 100644 --- a/build/msw/wx_vc8_base.vcproj +++ b/build/msw/wx_vc8_base.vcproj @@ -2017,6 +2017,10 @@ RelativePath="..\..\include\wx\platinfo.h" > + + diff --git a/build/msw/wx_vc9_base.vcproj b/build/msw/wx_vc9_base.vcproj index 4a8a4dc9c9..3656c710db 100644 --- a/build/msw/wx_vc9_base.vcproj +++ b/build/msw/wx_vc9_base.vcproj @@ -2013,6 +2013,10 @@ RelativePath="..\..\include\wx\platinfo.h" > + + diff --git a/include/wx/any.h b/include/wx/any.h index 0e3e4a9bea..366f4bc5e3 100644 --- a/include/wx/any.h +++ b/include/wx/any.h @@ -17,7 +17,7 @@ #if wxUSE_ANY #include "wx/string.h" -#include "wx/meta/movable.h" +#include "wx/meta/pod.h" #include "wx/meta/if.h" #include "wx/typeinfo.h" @@ -193,7 +193,7 @@ namespace wxPrivate { template -class wxAnyValueTypeOpsMovable +class wxAnyValueTypeOpsPOD { public: static void DeleteValue(wxAnyValueBuffer& buf) @@ -270,9 +270,9 @@ public: template class wxAnyValueTypeImplBase : public wxAnyValueType { - typedef typename wxIf< wxIsMovable::value && + typedef typename wxIf< wxIsPod::value && sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE, - wxPrivate::wxAnyValueTypeOpsMovable, + wxPrivate::wxAnyValueTypeOpsPOD, wxPrivate::wxAnyValueTypeOpsGeneric >::value Ops; diff --git a/include/wx/meta/movable.h b/include/wx/meta/movable.h index f8624d1fb9..8c93487472 100644 --- a/include/wx/meta/movable.h +++ b/include/wx/meta/movable.h @@ -11,20 +11,9 @@ #ifndef _WX_META_MOVABLE_H_ #define _WX_META_MOVABLE_H_ -#include "wx/defs.h" +#include "wx/meta/pod.h" #include "wx/string.h" // for wxIsMovable specialization -// This macro declares something called "value" inside a class declaration. -// -// It has to be used because VC6 doesn't handle initialization of the static -// variables in the class declaration itself while BCC5.82 doesn't understand -// enums (it compiles the template fine but can't use it later) -#if defined(__VISUALC__) && !wxCHECK_VISUALC_VERSION(7) - #define wxDEFINE_TEMPLATE_BOOL_VALUE(val) enum { value = val } -#else - #define wxDEFINE_TEMPLATE_BOOL_VALUE(val) static const bool value = val -#endif - // Helper to decide if an object of type T is "movable", i.e. if it can be // copied to another memory location using memmove() or realloc() C functions. // C++ only gurantees that POD types (including primitive types) are @@ -32,7 +21,7 @@ template struct wxIsMovable { - wxDEFINE_TEMPLATE_BOOL_VALUE(false); + wxDEFINE_TEMPLATE_BOOL_VALUE(wxIsPod::value); }; // Macro to add wxIsMovable specialization for given type that marks it @@ -43,46 +32,6 @@ struct wxIsMovable wxDEFINE_TEMPLATE_BOOL_VALUE(true); \ }; -WX_DECLARE_TYPE_MOVABLE(bool) -WX_DECLARE_TYPE_MOVABLE(unsigned char) -WX_DECLARE_TYPE_MOVABLE(signed char) -WX_DECLARE_TYPE_MOVABLE(unsigned int) -WX_DECLARE_TYPE_MOVABLE(signed int) -WX_DECLARE_TYPE_MOVABLE(unsigned short int) -WX_DECLARE_TYPE_MOVABLE(signed short int) -WX_DECLARE_TYPE_MOVABLE(signed long int) -WX_DECLARE_TYPE_MOVABLE(unsigned long int) -WX_DECLARE_TYPE_MOVABLE(float) -WX_DECLARE_TYPE_MOVABLE(double) -WX_DECLARE_TYPE_MOVABLE(long double) -#if wxWCHAR_T_IS_REAL_TYPE -WX_DECLARE_TYPE_MOVABLE(wchar_t) -#endif -#ifdef wxLongLong_t -WX_DECLARE_TYPE_MOVABLE(wxLongLong_t) -WX_DECLARE_TYPE_MOVABLE(wxULongLong_t) -#endif - -// Visual C++ 6.0 can't compile partial template specializations and as this is -// only an optimization, we can live with pointers not being recognized as -// movable types under VC6 -#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7) - -// pointers are movable: -template -struct wxIsMovable -{ - static const bool value = true; -}; - -template -struct wxIsMovable -{ - static const bool value = true; -}; - -#endif // !VC++ < 7 - // Our implementation of wxString is written in such way that it's safe to move // it around (unless position cache is used which unfortunately breaks this). // OTOH, we don't know anything about std::string. diff --git a/include/wx/meta/pod.h b/include/wx/meta/pod.h new file mode 100644 index 0000000000..c3426cc6fe --- /dev/null +++ b/include/wx/meta/pod.h @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/meta/pod.h +// Purpose: Test if a type is POD +// Author: Vaclav Slavik, Jaakko Salli +// Created: 2010-06-14 +// RCS-ID: $Id$ +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_META_POD_H_ +#define _WX_META_POD_H_ + +#include "wx/defs.h" + +// +// TODO: Use TR1 is_pod<> implementation where available. VC9 SP1 has it +// in tr1 namespace, VC10 has it in std namespace. GCC 4.2 has it in +// , while GCC 4.3 and later have it in . +// + +// This macro declares something called "value" inside a class declaration. +// +// It has to be used because VC6 doesn't handle initialization of the static +// variables in the class declaration itself while BCC5.82 doesn't understand +// enums (it compiles the template fine but can't use it later) +#if defined(__VISUALC__) && !wxCHECK_VISUALC_VERSION(7) + #define wxDEFINE_TEMPLATE_BOOL_VALUE(val) enum { value = val } +#else + #define wxDEFINE_TEMPLATE_BOOL_VALUE(val) static const bool value = val +#endif + +// Helper to decide if an object of type T is POD (Plain Old Data) +template +struct wxIsPod +{ + wxDEFINE_TEMPLATE_BOOL_VALUE(false); +}; + +// Macro to add wxIsPod specialization for given type that marks it +// as Plain Old Data: +#define WX_DECLARE_TYPE_POD(type) \ + template<> struct wxIsPod \ + { \ + wxDEFINE_TEMPLATE_BOOL_VALUE(true); \ + }; + +WX_DECLARE_TYPE_POD(bool) +WX_DECLARE_TYPE_POD(unsigned char) +WX_DECLARE_TYPE_POD(signed char) +WX_DECLARE_TYPE_POD(unsigned int) +WX_DECLARE_TYPE_POD(signed int) +WX_DECLARE_TYPE_POD(unsigned short int) +WX_DECLARE_TYPE_POD(signed short int) +WX_DECLARE_TYPE_POD(signed long int) +WX_DECLARE_TYPE_POD(unsigned long int) +WX_DECLARE_TYPE_POD(float) +WX_DECLARE_TYPE_POD(double) +WX_DECLARE_TYPE_POD(long double) +#if wxWCHAR_T_IS_REAL_TYPE +WX_DECLARE_TYPE_POD(wchar_t) +#endif +#ifdef wxLongLong_t +WX_DECLARE_TYPE_POD(wxLongLong_t) +WX_DECLARE_TYPE_POD(wxULongLong_t) +#endif + +// Visual C++ 6.0 can't compile partial template specializations and as this is +// only an optimization, we can live with pointers not being recognized as +// POD types under VC6 +#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7) + +// pointers are Plain Old Data: +template +struct wxIsPod +{ + static const bool value = true; +}; + +template +struct wxIsPod +{ + static const bool value = true; +}; + +#endif // !VC++ < 7 + +#endif // _WX_META_POD_H_ diff --git a/interface/wx/any.h b/interface/wx/any.h index 0ecefb86d0..b7e1fe0725 100644 --- a/interface/wx/any.h +++ b/interface/wx/any.h @@ -45,23 +45,27 @@ 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': + object in heap for large (i.e. size in bytes more than + WX_ANY_VALUE_BUFFER_SIZE) or non-POD (Plain Old Data) data types. + Pointers, integers, bools etc. are fitted in the wxAny's internal buffer + without need for any extra allocation. It is possible that wxAny cannot + automatically determine if your own data structure is considered a + POD or not, so you may need to declare it as such explicitly, using + code like this: @code - #include "wx/meta/movable.h" - WX_DECLARE_TYPE_MOVABLE(MyClass) + #include "wx/meta/pod.h" + WX_DECLARE_TYPE_POD(MyPodStruct) @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. + Be extra careful what you declare as Plain Old Data. It must be such data + that can be copied with memcpy() without corrupting program integrity. For + instance, POD structures usually cannot contain pointers or references to + other data. wxRect, wxPoint, and wxSize are good examples of POD + classes. - Note that pointers to any and all classes are already automatically - declared as movable data. + Note that pointers to any and all types are already automatically + declared as Plain Old Data. @library{wxbase} @category{data} diff --git a/tests/Makefile.in b/tests/Makefile.in index 90b2855e4a..445d2ccb4d 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -86,6 +86,7 @@ TEST_OBJECTS = \ test_mbconvtest.o \ test_dynamiclib.o \ test_environ.o \ + test_metatest.o \ test_misctests.o \ test_module.o \ test_pathlist.o \ @@ -460,6 +461,9 @@ test_dynamiclib.o: $(srcdir)/misc/dynamiclib.cpp $(TEST_ODEP) test_environ.o: $(srcdir)/misc/environ.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/misc/environ.cpp +test_metatest.o: $(srcdir)/misc/metatest.cpp $(TEST_ODEP) + $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/misc/metatest.cpp + test_misctests.o: $(srcdir)/misc/misctests.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/misc/misctests.cpp diff --git a/tests/makefile.bcc b/tests/makefile.bcc index e104f20bf9..32e3bb97ea 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -70,6 +70,7 @@ TEST_OBJECTS = \ $(OBJS)\test_mbconvtest.obj \ $(OBJS)\test_dynamiclib.obj \ $(OBJS)\test_environ.obj \ + $(OBJS)\test_metatest.obj \ $(OBJS)\test_misctests.obj \ $(OBJS)\test_module.obj \ $(OBJS)\test_pathlist.obj \ @@ -502,6 +503,9 @@ $(OBJS)\test_dynamiclib.obj: .\misc\dynamiclib.cpp $(OBJS)\test_environ.obj: .\misc\environ.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\environ.cpp +$(OBJS)\test_metatest.obj: .\misc\metatest.cpp + $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\metatest.cpp + $(OBJS)\test_misctests.obj: .\misc\misctests.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\misctests.cpp diff --git a/tests/makefile.gcc b/tests/makefile.gcc index fccd347e5c..69c87613f0 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -62,6 +62,7 @@ TEST_OBJECTS = \ $(OBJS)\test_mbconvtest.o \ $(OBJS)\test_dynamiclib.o \ $(OBJS)\test_environ.o \ + $(OBJS)\test_metatest.o \ $(OBJS)\test_misctests.o \ $(OBJS)\test_module.o \ $(OBJS)\test_pathlist.o \ @@ -483,6 +484,9 @@ $(OBJS)\test_dynamiclib.o: ./misc/dynamiclib.cpp $(OBJS)\test_environ.o: ./misc/environ.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_metatest.o: ./misc/metatest.cpp + $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_misctests.o: ./misc/misctests.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index 4d1592bf04..fa535a3885 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -64,6 +64,7 @@ TEST_OBJECTS = \ $(OBJS)\test_mbconvtest.obj \ $(OBJS)\test_dynamiclib.obj \ $(OBJS)\test_environ.obj \ + $(OBJS)\test_metatest.obj \ $(OBJS)\test_misctests.obj \ $(OBJS)\test_module.obj \ $(OBJS)\test_pathlist.obj \ @@ -628,6 +629,9 @@ $(OBJS)\test_dynamiclib.obj: .\misc\dynamiclib.cpp $(OBJS)\test_environ.obj: .\misc\environ.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\environ.cpp +$(OBJS)\test_metatest.obj: .\misc\metatest.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\metatest.cpp + $(OBJS)\test_misctests.obj: .\misc\misctests.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\misctests.cpp diff --git a/tests/makefile.wat b/tests/makefile.wat index a758537668..aac28188fa 100644 --- a/tests/makefile.wat +++ b/tests/makefile.wat @@ -300,6 +300,7 @@ TEST_OBJECTS = & $(OBJS)\test_mbconvtest.obj & $(OBJS)\test_dynamiclib.obj & $(OBJS)\test_environ.obj & + $(OBJS)\test_metatest.obj & $(OBJS)\test_misctests.obj & $(OBJS)\test_module.obj & $(OBJS)\test_pathlist.obj & @@ -540,6 +541,9 @@ $(OBJS)\test_dynamiclib.obj : .AUTODEPEND .\misc\dynamiclib.cpp $(OBJS)\test_environ.obj : .AUTODEPEND .\misc\environ.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< +$(OBJS)\test_metatest.obj : .AUTODEPEND .\misc\metatest.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< + $(OBJS)\test_misctests.obj : .AUTODEPEND .\misc\misctests.cpp $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< diff --git a/tests/misc/metatest.cpp b/tests/misc/metatest.cpp new file mode 100644 index 0000000000..1fcefd245c --- /dev/null +++ b/tests/misc/metatest.cpp @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/misc/metatest.cpp +// Purpose: Test template meta-programming constructs +// Author: Jaakko Salli +// RCS-ID: $Id$ +// Copyright: (c) the wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#include "testprec.h" + +#ifdef __BORLANDC__ +# pragma hdrstop +#endif + +#include "wx/object.h" +#include "wx/meta/pod.h" +#include "wx/meta/movable.h" + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class MetaProgrammingTestCase : public CppUnit::TestCase +{ +public: + MetaProgrammingTestCase() { } + +private: + CPPUNIT_TEST_SUITE( MetaProgrammingTestCase ); + CPPUNIT_TEST( IsPod ); + CPPUNIT_TEST( IsMovable ); + CPPUNIT_TEST_SUITE_END(); + + void IsPod(); + void IsMovable(); + + DECLARE_NO_COPY_CLASS(MetaProgrammingTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( MetaProgrammingTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MetaProgrammingTestCase, + "MetaProgrammingTestCase" ); + + +void MetaProgrammingTestCase::IsPod() +{ + CPPUNIT_ASSERT(wxIsPod::value); + CPPUNIT_ASSERT(wxIsPod::value); + CPPUNIT_ASSERT(wxIsPod::value); +#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7) + CPPUNIT_ASSERT(wxIsPod::value); +#endif + CPPUNIT_ASSERT(!wxIsPod::value); +} + +void MetaProgrammingTestCase::IsMovable() +{ + CPPUNIT_ASSERT(wxIsMovable::value); + CPPUNIT_ASSERT(wxIsMovable::value); + CPPUNIT_ASSERT(wxIsMovable::value); +#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7) + CPPUNIT_ASSERT(wxIsMovable::value); +#endif + CPPUNIT_ASSERT(!wxIsMovable::value); +} diff --git a/tests/test.bkl b/tests/test.bkl index 3a0a5af5f3..bb1d82192c 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -61,6 +61,7 @@ mbconv/mbconvtest.cpp misc/dynamiclib.cpp misc/environ.cpp + misc/metatest.cpp misc/misctests.cpp misc/module.cpp misc/pathlist.cpp diff --git a/tests/test_test.dsp b/tests/test_test.dsp index 976585634a..83fef0ef6f 100644 --- a/tests/test_test.dsp +++ b/tests/test_test.dsp @@ -405,6 +405,10 @@ SOURCE=.\streams\memstream.cpp # End Source File # Begin Source File +SOURCE=.\misc\metatest.cpp +# End Source File +# Begin Source File + SOURCE=.\thread\misc.cpp # End Source File # Begin Source File diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj index 48f402dfe5..b593bc6545 100644 --- a/tests/test_vc7_test.vcproj +++ b/tests/test_vc7_test.vcproj @@ -739,6 +739,9 @@ + + diff --git a/tests/test_vc8_test.vcproj b/tests/test_vc8_test.vcproj index ee86d82baa..d6881f816d 100644 --- a/tests/test_vc8_test.vcproj +++ b/tests/test_vc8_test.vcproj @@ -1059,6 +1059,10 @@ RelativePath=".\streams\memstream.cpp" > + + diff --git a/tests/test_vc9_test.vcproj b/tests/test_vc9_test.vcproj index 74ea5490fc..4f13922453 100644 --- a/tests/test_vc9_test.vcproj +++ b/tests/test_vc9_test.vcproj @@ -1031,6 +1031,10 @@ RelativePath=".\streams\memstream.cpp" > + + diff --git a/wxGTK.spec b/wxGTK.spec index 724fee3a4f..477b0150ee 100644 --- a/wxGTK.spec +++ b/wxGTK.spec @@ -353,6 +353,7 @@ wx/meta/convertible.h wx/meta/if.h wx/meta/int2type.h wx/meta/movable.h +wx/meta/pod.h wx/fswatcher.h wx/generic/fswatcher.h wx/unix/app.h diff --git a/wxMotif.spec b/wxMotif.spec index bb516bbf43..6b03b7b872 100644 --- a/wxMotif.spec +++ b/wxMotif.spec @@ -258,6 +258,7 @@ wx/meta/convertible.h wx/meta/if.h wx/meta/int2type.h wx/meta/movable.h +wx/meta/pod.h wx/fswatcher.h wx/generic/fswatcher.h wx/unix/app.h diff --git a/wxX11.spec b/wxX11.spec index 46ee82ce44..6f73f7d3b4 100644 --- a/wxX11.spec +++ b/wxX11.spec @@ -282,6 +282,7 @@ wx/meta/convertible.h wx/meta/if.h wx/meta/int2type.h wx/meta/movable.h +wx/meta/pod.h wx/fswatcher.h wx/generic/fswatcher.h wx/unix/app.h