union wxAnyValueBuffer
{
+ union Alignment
+ {
+ #if wxHAS_INT64
+ wxInt64 m_int64;
+ #endif
+ long double m_longDouble;
+ void ( *m_funcPtr )(void);
+ void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
+ } m_alignment;
+
void* m_ptr;
wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
};
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.
+ Implement this for buffer-to-buffer copy.
+
+ @param src
+ This is the source data buffer.
+
+ @param dst
+ This is the destination data buffer that is in either
+ uninitialized or freed state.
*/
virtual void CopyBuffer(const wxAnyValueBuffer& src,
wxAnyValueBuffer& dst) const = 0;
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);
}
WX_ANY_DEFINE_SUB_TYPE(double, Double)
+//
+// Defines a dummy wxAnyValueTypeImpl<> with given export
+// declaration. This is needed if a class is used with
+// wxAny in both user shared library and application.
+//
+#define wxDECLARE_ANY_TYPE(CLS, DECL) \
+template<> \
+class DECL wxAnyValueTypeImpl<CLS> : \
+ public wxAnyValueTypeImplBase<CLS> \
+{ \
+ WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
+public: \
+ wxAnyValueTypeImpl() : \
+ wxAnyValueTypeImplBase<CLS>() { } \
+ virtual ~wxAnyValueTypeImpl() { } \
+ \
+ virtual bool ConvertValue(const wxAnyValueBuffer& src, \
+ wxAnyValueType* dstType, \
+ wxAnyValueBuffer& dst) const \
+ { \
+ wxUnusedVar(src); \
+ wxUnusedVar(dstType); \
+ wxUnusedVar(dst); \
+ return false; \
+ } \
+};
+
+
+// Make sure some of wx's own types get the right wxAnyValueType export
+// (this is needed only for types that are referred to from wxBase.
+// currently we may not use any of these types from there, but let's
+// use the macro on at least one to make sure it compiles since we can't
+// really test it properly in unittests since a separate DLL would
+// be needed).
+#if wxUSE_DATETIME
+ #include "wx/datetime.h"
+ wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
+#endif
+
+//#include "wx/object.h"
+//wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
+
+//#include "wx/arrstr.h"
+//wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
+
+
+
#ifdef __VISUALC6__
// Re-enable useless VC6 warnings
#pragma warning (pop)
// As standard, wxAny can store value of almost any type, in a fairly
// optimal manner even.
//
-class WXDLLIMPEXP_BASE wxAny
+class wxAny
{
public:
/**
T As(T* = NULL) const
{
if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
+ {
wxFAIL_MSG("Incorrect or non-convertible data type");
+ }
+
return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
}
private:
// Assignment functions
- void AssignAny(const wxAny &any);
+ void AssignAny(const wxAny& any)
+ {
+ // Must delete value - CopyBuffer() never does that
+ m_type->DeleteValue(m_buffer);
+
+ wxAnyValueType* newType = any.m_type;
+
+ if ( !newType->IsSameType(m_type) )
+ m_type = newType;
+
+ newType->CopyBuffer(any.m_buffer, m_buffer);
+ }
template<typename T>
void Assign(const T &value)
}
// Data
- wxAnyValueType* m_type;
wxAnyValueBuffer m_buffer;
+ wxAnyValueType* m_type;
};