#include "wx/string.h"
#include "wx/meta/movable.h"
#include "wx/meta/if.h"
+#include "wx/typeinfo.h"
// Size of the wxAny value buffer.
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<>)
//
class WXDLLIMPEXP_BASE wxAnyValueType
{
+ WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
public:
/**
Default constructor.
{
}
- /**
- This function is used for internal type matching.
- */
- virtual wxAnyClassInfo GetClassInfo() const = 0;
-
/**
This function is used for internal type matching.
*/
#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
- //valueTypePtr->CheckType(static_cast<T*>(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).
+ Even though C++ RTTI would be fully available to use, we'd have to to
+ facilitate sub-type system which allows, for instance, wxAny with
+ signed short '15' to be treated equal to wxAny with signed long long '15'.
+ Having sm_instance is important here.
*/
#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
friend class wxAny; \
+ WX_DECLARE_TYPEINFO_INLINE(CLS) \
public: \
- static void sm_classInfo() {} \
- \
- virtual wxAnyClassInfo GetClassInfo() const \
- { \
- return sm_classInfo; \
- } \
static bool IsSameClass(const wxAnyValueType* otherType) \
{ \
- return sm_instance->GetClassInfo() == otherType->GetClassInfo(); \
+ return wxTypeId(*sm_instance) == wxTypeId(*otherType); \
} \
virtual bool IsSameType(const wxAnyValueType* otherType) const \
{ \
static const T& GetValue(const wxAnyValueBuffer& buf)
{
- return *(reinterpret_cast<const T*>(&buf.m_buffer[0]));
+ // Breaking this code into two lines should supress
+ // GCC's 'type-punned pointer will break strict-aliasing rules'
+ // warning.
+ const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
+ return *value;
}
};
virtual ~wxAnyValueTypeImpl() { } \
static void SetValue(const T& value, wxAnyValueBuffer& buf) \
{ \
- *(reinterpret_cast<UseDataType*>(&buf.m_buffer[0])) = \
- static_cast<UseDataType>(value); \
+ void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
+ UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
+ *dptr = static_cast<UseDataType>(value); \
} \
static T GetValue(const wxAnyValueBuffer& buf) \
{ \
- return static_cast<T>( \
- *(reinterpret_cast<const UseDataType*>(&buf.m_buffer[0]))); \
+ const void* voidPtr = \
+ reinterpret_cast<const void*>(&buf.m_buffer[0]); \
+ const UseDataType* sptr = \
+ reinterpret_cast<const UseDataType*>(voidPtr); \
+ return static_cast<T>(*sptr); \
} \
};
*/
wxAny& operator=(const wxAny &any)
{
- AssignAny(any);
+ if (this != &any)
+ AssignAny(any);
return *this;
}
in release ones.
@remarks This template function does not work on some older compilers
- (such as Visual C++ 6.0). For full compiler ccompatibility
+ (such as Visual C++ 6.0). For full compiler compatibility
please use wxANY_AS(any, T) macro instead.
*/
// FIXME-VC6: remove this hack when VC6 is no longer supported