// Author: Jaakko Salli
// Modified by:
// Created: 07/05/2009
-// RCS-ID: $Id$
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if wxUSE_ANY
+#include <new> // for placement new
#include "wx/string.h"
-#include "wx/meta/movable.h"
#include "wx/meta/if.h"
#include "wx/typeinfo.h"
-
+#include "wx/list.h"
// Size of the wxAny value buffer.
enum
a specific C++ data type.
@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_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
instead.
// FIXME-VC6: remove this hack when VC6 is no longer supported
template <typename T>
bool CheckType(T* reserved = NULL) const;
+
+#if wxUSE_EXTENDED_RTTI
+ virtual const wxTypeInfo* GetTypeInfo() const = 0;
+#endif
private:
};
{
template<typename T>
-class wxAnyValueTypeOpsMovable
+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)
{
- // Breaking this code into two lines should supress
+ // Breaking this code into two lines should suppress
// GCC's 'type-punned pointer will break strict-aliasing rules'
// warning.
const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
template<typename T>
class wxAnyValueTypeImplBase : public wxAnyValueType
{
- typedef typename wxIf< wxIsMovable<T>::value &&
- sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
- wxPrivate::wxAnyValueTypeOpsMovable<T>,
+ typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
+ wxPrivate::wxAnyValueTypeOpsInplace<T>,
wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
Ops;
{
return Ops::GetValue(buf);
}
+#if wxUSE_EXTENDED_RTTI
+ virtual const wxTypeInfo* GetTypeInfo() const
+ {
+ return wxGetTypeInfo((T*)NULL);
+ }
+#endif
};
// Helper macro for using same base value type implementation for multiple
// actual C++ data types.
//
-#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
+#define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
template<> \
class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
{ \
const UseDataType* sptr = \
reinterpret_cast<const UseDataType*>(voidPtr); \
return static_cast<T>(*sptr); \
+ }
+
+#if wxUSE_EXTENDED_RTTI
+#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
+_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
+ virtual const wxTypeInfo* GetTypeInfo() const \
+ { \
+ return wxGetTypeInfo((T*)NULL); \
} \
};
-
+#else
+#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
+_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
+};
+#endif
//
// Integer value types
// (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
+// really test it properly in unit tests since a separate DLL would
// be needed).
#if wxUSE_DATETIME
#include "wx/datetime.h"
@remarks You cannot reliably test whether two wxAnys are of
same value type by simply comparing return values
- of wxAny::GetType(). Instead use
- wxAnyValueType::CheckType<T>() template function.
+ of wxAny::GetType(). Instead, use wxAny::HasSameType().
+
+ @see HasSameType()
*/
const wxAnyValueType* GetType() const
{
}
/**
- Tests if wxAny is null (that is, whether there is data).
+ Returns @true if this and another wxAny have the same
+ value type.
+ */
+ bool HasSameType(const wxAny& other) const
+ {
+ return GetType()->IsSameType(other.GetType());
+ }
+
+ /**
+ Tests if wxAny is null (that is, whether there is no data).
*/
bool IsNull() const
{
WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
#endif
+ wxGCC_WARNING_SUPPRESS(float-equal)
+
bool operator==(float value) const
{
if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
(wxAnyValueTypeImpl<double>::GetValue(m_buffer));
}
+ wxGCC_WARNING_RESTORE(float-equal)
+
bool operator==(bool value) const
{
if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
no type conversion is performed, so if the type is incorrect an
assertion failure will occur.
- @remarks For conveniency, conversion is done when T is wxString. This
+ @remarks For convenience, conversion is done when T is wxString. This
is useful when a string literal (which are treated as
const char* and const wchar_t*) has been assigned to wxAny.
return value;
}
+#if wxUSE_EXTENDED_RTTI
+ const wxTypeInfo* GetTypeInfo() const
+ {
+ return m_type->GetTypeInfo();
+ }
+#endif
/**
- Template function that etrieves and converts the value of this
+ Template function that retrieves and converts the value of this
variant to the type that T* value is.
- @return Returns @true if conversion was succesfull.
+ @return Returns @true if conversion was successful.
*/
template<typename T>
bool GetAs(T* value) const
return wxAnyValueTypeImpl<T>::IsSameClass(this);
}
-
+WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
#endif // wxUSE_ANY