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) \
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 \
wx/meta/if.h
wx/meta/int2type.h
wx/meta/movable.h
+ wx/meta/pod.h
wx/fswatcher.h
wx/generic/fswatcher.h
</set>
# End Source File\r
# Begin Source File\r
\r
+SOURCE=..\..\include\wx\meta\pod.h\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=..\..\include\wx\power.h\r
# End Source File\r
# Begin Source File\r
<File\r
RelativePath="..\..\include\wx\platinfo.h">\r
</File>\r
+ <File\r
+ RelativePath="..\..\include\wx\meta\pod.h">\r
+ </File>\r
<File\r
RelativePath="..\..\include\wx\power.h">\r
</File>\r
RelativePath="..\..\include\wx\platinfo.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\include\wx\meta\pod.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\include\wx\power.h"\r
>\r
RelativePath="..\..\include\wx\platinfo.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\include\wx\meta\pod.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\include\wx\power.h"\r
>\r
#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"
{
template<typename T>
-class wxAnyValueTypeOpsMovable
+class wxAnyValueTypeOpsPOD
{
public:
static void DeleteValue(wxAnyValueBuffer& buf)
template<typename T>
class wxAnyValueTypeImplBase : public wxAnyValueType
{
- typedef typename wxIf< wxIsMovable<T>::value &&
+ typedef typename wxIf< wxIsPod<T>::value &&
sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
- wxPrivate::wxAnyValueTypeOpsMovable<T>,
+ wxPrivate::wxAnyValueTypeOpsPOD<T>,
wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
Ops;
#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<wxString> 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
template<typename T>
struct wxIsMovable
{
- wxDEFINE_TEMPLATE_BOOL_VALUE(false);
+ wxDEFINE_TEMPLATE_BOOL_VALUE(wxIsPod<T>::value);
};
// Macro to add wxIsMovable<T> specialization for given type that marks it
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<typename T>
-struct wxIsMovable<T*>
-{
- static const bool value = true;
-};
-
-template<typename T>
-struct wxIsMovable<const T*>
-{
- 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.
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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
+// <tr1/type_traits>, while GCC 4.3 and later have it in <type_traits>.
+//
+
+// 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<typename T>
+struct wxIsPod
+{
+ wxDEFINE_TEMPLATE_BOOL_VALUE(false);
+};
+
+// Macro to add wxIsPod<T> specialization for given type that marks it
+// as Plain Old Data:
+#define WX_DECLARE_TYPE_POD(type) \
+ template<> struct wxIsPod<type> \
+ { \
+ 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<typename T>
+struct wxIsPod<T*>
+{
+ static const bool value = true;
+};
+
+template<typename T>
+struct wxIsPod<const T*>
+{
+ static const bool value = true;
+};
+
+#endif // !VC++ < 7
+
+#endif // _WX_META_POD_H_
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}
test_mbconvtest.o \
test_dynamiclib.o \
test_environ.o \
+ test_metatest.o \
test_misctests.o \
test_module.o \
test_pathlist.o \
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
$(OBJS)\test_mbconvtest.obj \\r
$(OBJS)\test_dynamiclib.obj \\r
$(OBJS)\test_environ.obj \\r
+ $(OBJS)\test_metatest.obj \\r
$(OBJS)\test_misctests.obj \\r
$(OBJS)\test_module.obj \\r
$(OBJS)\test_pathlist.obj \\r
$(OBJS)\test_environ.obj: .\misc\environ.cpp\r
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\environ.cpp\r
\r
+$(OBJS)\test_metatest.obj: .\misc\metatest.cpp\r
+ $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\metatest.cpp\r
+\r
$(OBJS)\test_misctests.obj: .\misc\misctests.cpp\r
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\misc\misctests.cpp\r
\r
$(OBJS)\test_mbconvtest.o \\r
$(OBJS)\test_dynamiclib.o \\r
$(OBJS)\test_environ.o \\r
+ $(OBJS)\test_metatest.o \\r
$(OBJS)\test_misctests.o \\r
$(OBJS)\test_module.o \\r
$(OBJS)\test_pathlist.o \\r
$(OBJS)\test_environ.o: ./misc/environ.cpp\r
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<\r
\r
+$(OBJS)\test_metatest.o: ./misc/metatest.cpp\r
+ $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<\r
+\r
$(OBJS)\test_misctests.o: ./misc/misctests.cpp\r
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<\r
\r
$(OBJS)\test_mbconvtest.obj \\r
$(OBJS)\test_dynamiclib.obj \\r
$(OBJS)\test_environ.obj \\r
+ $(OBJS)\test_metatest.obj \\r
$(OBJS)\test_misctests.obj \\r
$(OBJS)\test_module.obj \\r
$(OBJS)\test_pathlist.obj \\r
$(OBJS)\test_environ.obj: .\misc\environ.cpp\r
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\environ.cpp\r
\r
+$(OBJS)\test_metatest.obj: .\misc\metatest.cpp\r
+ $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\metatest.cpp\r
+\r
$(OBJS)\test_misctests.obj: .\misc\misctests.cpp\r
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\misc\misctests.cpp\r
\r
$(OBJS)\test_mbconvtest.obj &\r
$(OBJS)\test_dynamiclib.obj &\r
$(OBJS)\test_environ.obj &\r
+ $(OBJS)\test_metatest.obj &\r
$(OBJS)\test_misctests.obj &\r
$(OBJS)\test_module.obj &\r
$(OBJS)\test_pathlist.obj &\r
$(OBJS)\test_environ.obj : .AUTODEPEND .\misc\environ.cpp\r
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<\r
\r
+$(OBJS)\test_metatest.obj : .AUTODEPEND .\misc\metatest.cpp\r
+ $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<\r
+\r
$(OBJS)\test_misctests.obj : .AUTODEPEND .\misc\misctests.cpp\r
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<\r
\r
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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<bool>::value);
+ CPPUNIT_ASSERT(wxIsPod<signed int>::value);
+ CPPUNIT_ASSERT(wxIsPod<double>::value);
+#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
+ CPPUNIT_ASSERT(wxIsPod<wxObject*>::value);
+#endif
+ CPPUNIT_ASSERT(!wxIsPod<wxObject>::value);
+}
+
+void MetaProgrammingTestCase::IsMovable()
+{
+ CPPUNIT_ASSERT(wxIsMovable<bool>::value);
+ CPPUNIT_ASSERT(wxIsMovable<signed int>::value);
+ CPPUNIT_ASSERT(wxIsMovable<double>::value);
+#if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
+ CPPUNIT_ASSERT(wxIsMovable<wxObject*>::value);
+#endif
+ CPPUNIT_ASSERT(!wxIsMovable<wxObject>::value);
+}
mbconv/mbconvtest.cpp
misc/dynamiclib.cpp
misc/environ.cpp
+ misc/metatest.cpp
misc/misctests.cpp
misc/module.cpp
misc/pathlist.cpp
# End Source File\r
# Begin Source File\r
\r
+SOURCE=.\misc\metatest.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\thread\misc.cpp\r
# End Source File\r
# Begin Source File\r
<File\r
RelativePath=".\streams\memstream.cpp">\r
</File>\r
+ <File\r
+ RelativePath=".\misc\metatest.cpp">\r
+ </File>\r
<File\r
RelativePath=".\thread\misc.cpp">\r
</File>\r
RelativePath=".\streams\memstream.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\misc\metatest.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath=".\thread\misc.cpp"\r
>\r
RelativePath=".\streams\memstream.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\misc\metatest.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath=".\thread\misc.cpp"\r
>\r
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
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
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