Use placement new when storing value in wxAnyValueBuffer. This should allow using any data type, regardless whether it is Plain Old Data or copyable or not.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64623 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -16,8 +16,8 @@
|
||||
|
||||
#if wxUSE_ANY
|
||||
|
||||
#include <new> // for placement new
|
||||
#include "wx/string.h"
|
||||
#include "wx/meta/pod.h"
|
||||
#include "wx/meta/if.h"
|
||||
#include "wx/typeinfo.h"
|
||||
|
||||
@@ -193,18 +193,24 @@ namespace wxPrivate
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
class wxAnyValueTypeOpsPOD
|
||||
class wxAnyValueTypeOpsInplace
|
||||
{
|
||||
public:
|
||||
static void DeleteValue(wxAnyValueBuffer& buf)
|
||||
{
|
||||
wxUnusedVar(buf);
|
||||
T* value = reinterpret_cast<T*>(&buf.m_buffer[0]);
|
||||
value->~T();
|
||||
|
||||
// Some compiler may given 'unused variable' warnings without this
|
||||
wxUnusedVar(value);
|
||||
}
|
||||
|
||||
static void SetValue(const T& value,
|
||||
wxAnyValueBuffer& buf)
|
||||
{
|
||||
memcpy(buf.m_buffer, &value, sizeof(T));
|
||||
// Use placement new
|
||||
void* const place = buf.m_buffer;
|
||||
::new(place) T(value);
|
||||
}
|
||||
|
||||
static const T& GetValue(const wxAnyValueBuffer& buf)
|
||||
@@ -270,9 +276,8 @@ public:
|
||||
template<typename T>
|
||||
class wxAnyValueTypeImplBase : public wxAnyValueType
|
||||
{
|
||||
typedef typename wxIf< wxIsPod<T>::value &&
|
||||
sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
|
||||
wxPrivate::wxAnyValueTypeOpsPOD<T>,
|
||||
typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
|
||||
wxPrivate::wxAnyValueTypeOpsInplace<T>,
|
||||
wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
|
||||
Ops;
|
||||
|
||||
|
@@ -45,27 +45,8 @@
|
||||
|
||||
When compared to wxVariant, there are various internal implementation
|
||||
differences as well. For instance, wxAny only allocates separate data
|
||||
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/pod.h"
|
||||
WX_DECLARE_TYPE_POD(MyPodStruct)
|
||||
@endcode
|
||||
|
||||
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 types are already automatically
|
||||
declared as Plain Old Data.
|
||||
object in heap for large objects (i.e. ones with size more than
|
||||
WX_ANY_VALUE_BUFFER_SIZE, which at the time of writing is 16 bytes).
|
||||
|
||||
@library{wxbase}
|
||||
@category{data}
|
||||
|
Reference in New Issue
Block a user