Set svn properties correctly for the newly added files.

Set svn:keyword and, most importantly, svn:eol-style, to avoid having files
with DOS line endings in svn, for the new files added by r61971.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61973 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-09-19 15:41:08 +00:00
parent 9ae96ec2bd
commit 39601a7f74
4 changed files with 2054 additions and 2054 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,425 +1,425 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: any.h // Name: any.h
// Purpose: interface of wxAny // Purpose: interface of wxAny
// Author: wxWidgets team // Author: wxWidgets team
// RCS-ID: $Id$ // RCS-ID: $Id$
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/** /**
@class wxAny @class wxAny
The wxAny class represents a container for any type. Its value The wxAny class represents a container for any type. Its value
can be changed at run time, possibly to a different type of value. can be changed at run time, possibly to a different type of value.
wxAny is successor class for wxVariant, essentially doing the same thing wxAny is successor class for wxVariant, essentially doing the same thing
in a more modern, template-based manner and with transparent support in a more modern, template-based manner and with transparent support
for any user data type. for any user data type.
Some pseudo-code'ish example of use with arbitrary user data: Some pseudo-code'ish example of use with arbitrary user data:
@code @code
void SomeFunction() void SomeFunction()
{ {
MyClass myObject; MyClass myObject;
wxAny any = myObject; wxAny any = myObject;
// Do something // Do something
// ... // ...
// Let's do a sanity check to make sure that any still holds // Let's do a sanity check to make sure that any still holds
// data of correct type. // data of correct type.
if ( any.CheckType<MyClass>() ) if ( any.CheckType<MyClass>() )
{ {
// Thank goodness, still a correct type. // Thank goodness, still a correct type.
MyClass myObject2 = any.As<MyClass>(); MyClass myObject2 = any.As<MyClass>();
} }
else else
{ {
// Something has gone horribly wrong! // Something has gone horribly wrong!
wxFAIL(); wxFAIL();
} }
} }
@endcode @endcode
When compared to wxVariant, there are various internal implementation When compared to wxVariant, there are various internal implementation
differences as well. For instance, wxAny only allocates separate data differences as well. For instance, wxAny only allocates separate data
object in heap for large (ie. size in bytes more than object in heap for large (ie. size in bytes more than
WX_ANY_VALUE_BUFFER_SIZE) or 'non-movable' data types. Pointers, integers, 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 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': allocation. Use following code to declare your own data type as 'movable':
@code @code
#include "wx/meta/movable.h" #include "wx/meta/movable.h"
WX_DECLARE_TYPE_MOVABLE(MyClass) WX_DECLARE_TYPE_MOVABLE(MyClass)
@endcode @endcode
However, you must be aware that 'movable' means such data that can be However, you must be aware that 'movable' means such data that can be
copied with memcpy() without corrupting program integrity. For instance, copied with memcpy() without corrupting program integrity. For instance,
movable objects usually cannot contain pointers or references to other movable objects usually cannot contain pointers or references to other
data. wxRect, wxPoint, and wxSize are good examples of movable classes. data. wxRect, wxPoint, and wxSize are good examples of movable classes.
Note that pointers to any and all classes are already automatically Note that pointers to any and all classes are already automatically
declared as movable data. declared as movable data.
@library{wxbase} @library{wxbase}
@category{data} @category{data}
@see wxAnyValueType, wxVariant @see wxAnyValueType, wxVariant
*/ */
class wxAny class wxAny
{ {
public: public:
/** /**
Default constructor. It seeds the object with a null value. Default constructor. It seeds the object with a null value.
*/ */
wxAny(); wxAny();
/** /**
Constructs wxAny from data. Constructs wxAny from data.
*/ */
template<typename T> template<typename T>
wxAny(const T& value); wxAny(const T& value);
/** /**
Constructs wxAny from another wxAny. Constructs wxAny from another wxAny.
*/ */
wxAny(const wxAny& any); wxAny(const wxAny& any);
/** /**
Destructor. Destructor.
*/ */
~wxAny(); ~wxAny();
/** /**
This template function converts wxAny into given type. No dynamic This template function converts wxAny into given type. No dynamic
conversion is performed, so if the type is incorrect an assertion conversion is performed, so if the type is incorrect an assertion
failure will occur in debug builds, and a bogus value is returned failure will occur in debug builds, and a bogus value is returned
in release ones. in release ones.
@remarks This template function may not work properly with Visual C++ @remarks This template function may not work properly with Visual C++
6. For full compiler compatibility, please use 6. For full compiler compatibility, please use
wxANY_AS(any, T) macro instead. wxANY_AS(any, T) macro instead.
*/ */
template<typename T> template<typename T>
T As() const; T As() const;
/** /**
Use this template function for checking if this wxAny holds Use this template function for checking if this wxAny holds
a specific C++ data type. a specific C++ data type.
@remarks This template function may not work properly with Visual C++ @remarks This template function may not work properly with Visual C++
6. For full compiler compatibility, please use 6. For full compiler compatibility, please use
wxANY_CHECK_TYPE(any, T) macro instead. wxANY_CHECK_TYPE(any, T) macro instead.
@see wxAnyValueType::CheckType() @see wxAnyValueType::CheckType()
*/ */
template<typename T> template<typename T>
bool CheckType(); bool CheckType();
/** /**
Template function that retrieves and converts the value of this Template function that retrieves and converts the value of this
wxAny to the type that T* value is. wxAny to the type that T* value is.
@return Returns @true if conversion was succesfull. @return Returns @true if conversion was succesfull.
*/ */
template<typename T> template<typename T>
bool GetAs(T* value) const; bool GetAs(T* value) const;
/** /**
Returns the value type as wxAnyValueType instance. Returns the value type as wxAnyValueType instance.
@remarks You cannot reliably test whether two wxAnys are of @remarks You cannot reliably test whether two wxAnys are of
same value type by simply comparing return values same value type by simply comparing return values
of wxAny::GetType(). Instead use of wxAny::GetType(). Instead use
wxAnyValueType::CheckType<T>() template function. wxAnyValueType::CheckType<T>() template function.
*/ */
const wxAnyValueType* GetType() const; const wxAnyValueType* GetType() const;
/** /**
Tests if wxAny is null (that is, whether there is data). Tests if wxAny is null (that is, whether there is data).
*/ */
bool IsNull() const; bool IsNull() const;
/** /**
Makes wxAny null (that is, clears it). Makes wxAny null (that is, clears it).
*/ */
void MakeNull(); void MakeNull();
//@{ //@{
/** /**
@name Assignment operators @name Assignment operators
*/ */
template<typename T> template<typename T>
wxAny& operator=(const T &value); wxAny& operator=(const T &value);
wxAny& operator=(const wxAny &any); wxAny& operator=(const wxAny &any);
//@} //@}
//@{ //@{
/** /**
@name Equality operators @name Equality operators
@remarks Generic template-based comparison operators have not been @remarks Generic template-based comparison operators have not been
provided for various code consistency reasons, so for custom provided for various code consistency reasons, so for custom
data types you have do something like this: data types you have do something like this:
@code @code
if ( any.CheckType<MyClass*>() && if ( any.CheckType<MyClass*>() &&
any.As<MyClass*>() == myObjectPtr ) any.As<MyClass*>() == myObjectPtr )
{ {
// Do something if any stores myObjectPtr // Do something if any stores myObjectPtr
} }
@endcode @endcode
*/ */
bool operator==(signed char value) const; bool operator==(signed char value) const;
bool operator==(signed short value) const; bool operator==(signed short value) const;
bool operator==(signed int value) const; bool operator==(signed int value) const;
bool operator==(signed long value) const; bool operator==(signed long value) const;
bool operator==(wxLongLong_t value) const; bool operator==(wxLongLong_t value) const;
bool operator==(unsigned char value) const; bool operator==(unsigned char value) const;
bool operator==(unsigned short value) const; bool operator==(unsigned short value) const;
bool operator==(unsigned int value) const; bool operator==(unsigned int value) const;
bool operator==(unsigned long value) const; bool operator==(unsigned long value) const;
bool operator==(wxULongLong_t value) const; bool operator==(wxULongLong_t value) const;
bool operator==(float value) const; bool operator==(float value) const;
bool operator==(double value) const; bool operator==(double value) const;
bool operator==(bool value) const; bool operator==(bool value) const;
bool operator==(const char* value) const; bool operator==(const char* value) const;
bool operator==(const wchar_t* value) const; bool operator==(const wchar_t* value) const;
bool operator==(const wxString& value) const; bool operator==(const wxString& value) const;
//@} //@}
//@{ //@{
/** /**
@name Inequality operators @name Inequality operators
*/ */
bool operator!=(signed char value) const; bool operator!=(signed char value) const;
bool operator!=(signed short value) const; bool operator!=(signed short value) const;
bool operator!=(signed int value) const; bool operator!=(signed int value) const;
bool operator!=(signed long value) const; bool operator!=(signed long value) const;
bool operator!=(wxLongLong_t value) const; bool operator!=(wxLongLong_t value) const;
bool operator!=(unsigned char value) const; bool operator!=(unsigned char value) const;
bool operator!=(unsigned short value) const; bool operator!=(unsigned short value) const;
bool operator!=(unsigned int value) const; bool operator!=(unsigned int value) const;
bool operator!=(unsigned long value) const; bool operator!=(unsigned long value) const;
bool operator!=(wxULongLong_t value) const; bool operator!=(wxULongLong_t value) const;
bool operator!=(float value) const; bool operator!=(float value) const;
bool operator!=(double value) const; bool operator!=(double value) const;
bool operator!=(bool value) const; bool operator!=(bool value) const;
bool operator!=(const char* value) const; bool operator!=(const char* value) const;
bool operator!=(const wchar_t* value) const; bool operator!=(const wchar_t* value) const;
bool operator!=(const wxString& value) const; bool operator!=(const wxString& value) const;
//@} //@}
}; };
/** /**
This is value getter macro that is more compatible with older This is value getter macro that is more compatible with older
compilers, such as Visual C++ 6.0. compilers, such as Visual C++ 6.0.
*/ */
#define wxANY_AS(any, T) #define wxANY_AS(any, T)
/** /**
This is type checking macro that is more compatible with older This is type checking macro that is more compatible with older
compilers, such as Visual C++ 6.0. compilers, such as Visual C++ 6.0.
*/ */
#define wxANY_CHECK_TYPE(any, T) #define wxANY_CHECK_TYPE(any, T)
/** /**
Size of the wxAny value buffer. Size of the wxAny value buffer.
*/ */
enum enum
{ {
WX_ANY_VALUE_BUFFER_SIZE = 16 WX_ANY_VALUE_BUFFER_SIZE = 16
}; };
/** /**
Type for buffer within wxAny for holding data. Type for buffer within wxAny for holding data.
*/ */
union wxAnyValueBuffer union wxAnyValueBuffer
{ {
void* m_ptr; void* m_ptr;
wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE]; wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
}; };
/** /**
@class wxAnyValueType @class wxAnyValueType
wxAnyValueType is base class for value type functionality for C++ data wxAnyValueType is base class for value type functionality for C++ data
types used with wxAny. Usually the default template will create a types used with wxAny. Usually the default template will create a
satisfactory wxAnyValueType implementation for a data type, but satisfactory wxAnyValueType implementation for a data type, but
sometimes you may need to add some customization. To do this you will need sometimes you may need to add some customization. To do this you will need
to add specialized template of wxAnyValueTypeImpl<>. Often your only to add specialized template of wxAnyValueTypeImpl<>. Often your only
need may be to add dynamic type conversion which would be done like need may be to add dynamic type conversion which would be done like
this: this:
@code @code
template<> template<>
class wxAnyValueTypeImpl<MyClass> : class wxAnyValueTypeImpl<MyClass> :
public wxAnyValueTypeImplBase<MyClass> public wxAnyValueTypeImplBase<MyClass>
{ {
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>) WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
public: public:
wxAnyValueTypeImpl() : wxAnyValueTypeImpl() :
wxAnyValueTypeImplBase<MyClass>() { } wxAnyValueTypeImplBase<MyClass>() { }
virtual ~wxAnyValueTypeImpl() { } virtual ~wxAnyValueTypeImpl() { }
virtual bool ConvertValue(const wxAnyValueBuffer& src, virtual bool ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
// GetValue() is a static member function implemented // GetValue() is a static member function implemented
// in wxAnyValueTypeImplBase<>. // in wxAnyValueTypeImplBase<>.
MyClass value = GetValue(src); MyClass value = GetValue(src);
// TODO: Convert value from src buffer to destination // TODO: Convert value from src buffer to destination
// type and buffer. If cannot be done, return // type and buffer. If cannot be done, return
// false. This is a simple sample. // false. This is a simple sample.
if ( dstType->CheckType<wxString>() ) if ( dstType->CheckType<wxString>() )
{ {
wxString s = value.ToString(); wxString s = value.ToString();
wxAnyValueTypeImpl<wxString>::SetValue(s, dst); wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
} }
else else
{ {
return false; return false;
} }
} }
}; };
// //
// Following must be placed somewhere in your source code // Following must be placed somewhere in your source code
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
@endcode @endcode
wxAnyValueTypeImplBase<> template, from which we inherit in the above wxAnyValueTypeImplBase<> template, from which we inherit in the above
example, contains the bulk of the default wxAnyValueTypeImpl<> template example, contains the bulk of the default wxAnyValueTypeImpl<> template
implementation, and as such allows you to easily add some minor implementation, and as such allows you to easily add some minor
customization. customization.
If you need a have complete control over the type interpretation, you If you need a have complete control over the type interpretation, you
will need to derive a class directly from wxAnyValueType, like this: will need to derive a class directly from wxAnyValueType, like this:
@code @code
template <> template <>
class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType
{ {
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>) WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
public: public:
virtual void DeleteValue(wxAnyValueBuffer& buf) const virtual void DeleteValue(wxAnyValueBuffer& buf) const
{ {
// TODO: Free the data in buffer // TODO: Free the data in buffer
// It is important to clear the buffer like this // It is important to clear the buffer like this
// at the end of DeleteValue(). // at the end of DeleteValue().
buf.m_ptr = NULL; buf.m_ptr = NULL;
} }
virtual void CopyBuffer(const wxAnyValueBuffer& src, virtual void CopyBuffer(const wxAnyValueBuffer& src,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
// TODO: Copy value from one buffer to another. // TODO: Copy value from one buffer to another.
} }
virtual bool ConvertValue(const wxAnyValueBuffer& src, virtual bool ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
// TODO: Convert value from src buffer to destination // TODO: Convert value from src buffer to destination
// type and buffer. // type and buffer.
} }
// //
// Following static functions must be implemented // Following static functions must be implemented
// //
static void SetValue(const T& value, static void SetValue(const T& value,
wxAnyValueBuffer& buf) wxAnyValueBuffer& buf)
{ {
// TODO: Store value into buf. // TODO: Store value into buf.
} }
static const T& GetValue(const wxAnyValueBuffer& buf) static const T& GetValue(const wxAnyValueBuffer& buf)
{ {
// TODO: Return reference to value stored in buffer. // TODO: Return reference to value stored in buffer.
} }
}; };
// //
// Following must be placed somewhere in your source code // Following must be placed somewhere in your source code
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
@endcode @endcode
@library{wxbase} @library{wxbase}
@category{data} @category{data}
@see wxAny @see wxAny
*/ */
class wxAnyValueType class wxAnyValueType
{ {
public: public:
/** /**
Default constructor. Default constructor.
*/ */
wxAnyValueType(); wxAnyValueType();
/** /**
Destructor. Destructor.
*/ */
virtual ~wxAnyValueType(); virtual ~wxAnyValueType();
/** /**
Use this template function for checking if wxAnyValueType represents Use this template function for checking if wxAnyValueType represents
a specific C++ data type. a specific C++ data type.
@remarks This template function does not work on some older compilers @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 ccompatibility
please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
instead. instead.
@see wxAny::CheckType() @see wxAny::CheckType()
*/ */
template <typename T> template <typename T>
bool CheckType(); bool CheckType();
/** /**
Convert value into buffer of different type. Return false if Convert value into buffer of different type. Return false if
not possible. not possible.
*/ */
virtual bool ConvertValue(const wxAnyValueBuffer& src, virtual bool ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const = 0; wxAnyValueBuffer& dst) const = 0;
/** /**
Implement this for buffer-to-buffer copy. src.m_ptr can Implement this for buffer-to-buffer copy. src.m_ptr can
be expected to be NULL if value type of previously stored be expected to be NULL if value type of previously stored
data was different. data was different.
*/ */
virtual void CopyBuffer(const wxAnyValueBuffer& src, virtual void CopyBuffer(const wxAnyValueBuffer& src,
wxAnyValueBuffer& dst) const = 0; wxAnyValueBuffer& dst) const = 0;
/** /**
This function is called every time the data in wxAny This function is called every time the data in wxAny
buffer needs to be freed. buffer needs to be freed.
*/ */
virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0; virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
/** /**
This function is used for internal type matching. This function is used for internal type matching.
*/ */
virtual wxAnyClassInfo GetClassInfo() const = 0; virtual wxAnyClassInfo GetClassInfo() const = 0;
/** /**
This function is used for internal type matching. This function is used for internal type matching.
*/ */
virtual bool IsSameType(const wxAnyValueType* otherType) const = 0; virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
}; };
/** /**
This is type checking macro that is more compatible with older This is type checking macro that is more compatible with older
compilers, such as Visual C++ 6.0. compilers, such as Visual C++ 6.0.
*/ */
#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T)

View File

@@ -1,402 +1,402 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: src/common/any.cpp // Name: src/common/any.cpp
// Purpose: wxAny class, container for any type // Purpose: wxAny class, container for any type
// Author: Jaakko Salli // Author: Jaakko Salli
// Modified by: // Modified by:
// Created: 07/05/2009 // Created: 07/05/2009
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) wxWidgets team // Copyright: (c) wxWidgets team
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h". // For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#pragma hdrstop #pragma hdrstop
#endif #endif
#include "wx/any.h" #include "wx/any.h"
#if wxUSE_ANY #if wxUSE_ANY
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/math.h" #include "wx/math.h"
#include "wx/crt.h" #include "wx/crt.h"
#endif #endif
#include "wx/vector.h" #include "wx/vector.h"
#include "wx/module.h" #include "wx/module.h"
using namespace wxPrivate; using namespace wxPrivate;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// wxAnyValueTypeGlobals // wxAnyValueTypeGlobals
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Helper class to manage wxAnyValueType instances and other // Helper class to manage wxAnyValueType instances and other
// related global variables. // related global variables.
// //
// NB: We really need to have wxAnyValueType instances allocated // NB: We really need to have wxAnyValueType instances allocated
// in heap. They are stored as static template member variables, // in heap. They are stored as static template member variables,
// and with them we just can't be too careful (eg. not allocating // and with them we just can't be too careful (eg. not allocating
// them in heap broke the type identification in GCC). // them in heap broke the type identification in GCC).
// //
class wxAnyValueTypeGlobals class wxAnyValueTypeGlobals
{ {
public: public:
wxAnyValueTypeGlobals() wxAnyValueTypeGlobals()
{ {
} }
~wxAnyValueTypeGlobals() ~wxAnyValueTypeGlobals()
{ {
for ( size_t i=0; i<m_valueTypes.size(); i++ ) for ( size_t i=0; i<m_valueTypes.size(); i++ )
delete m_valueTypes[i]; delete m_valueTypes[i];
} }
void RegisterValueType(wxAnyValueType* valueType) void RegisterValueType(wxAnyValueType* valueType)
{ {
m_valueTypes.push_back(valueType); m_valueTypes.push_back(valueType);
} }
private: private:
wxVector<wxAnyValueType*> m_valueTypes; wxVector<wxAnyValueType*> m_valueTypes;
}; };
static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL; static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
// //
// This class is to make sure that wxAnyValueType instances // This class is to make sure that wxAnyValueType instances
// etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
// because wxModule itself is instantiated too late. // because wxModule itself is instantiated too late.
// //
class wxAnyValueTypeGlobalsManager : public wxModule class wxAnyValueTypeGlobalsManager : public wxModule
{ {
DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager) DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
public: public:
wxAnyValueTypeGlobalsManager() : wxModule() { } wxAnyValueTypeGlobalsManager() : wxModule() { }
virtual ~wxAnyValueTypeGlobalsManager() { } virtual ~wxAnyValueTypeGlobalsManager() { }
virtual bool OnInit() virtual bool OnInit()
{ {
return true; return true;
} }
virtual void OnExit() virtual void OnExit()
{ {
delete g_wxAnyValueTypeGlobals; delete g_wxAnyValueTypeGlobals;
g_wxAnyValueTypeGlobals = NULL; g_wxAnyValueTypeGlobals = NULL;
} }
private: private:
}; };
IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule) IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// wxAnyValueType // wxAnyValueType
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
wxAnyValueType::wxAnyValueType() wxAnyValueType::wxAnyValueType()
{ {
if ( !g_wxAnyValueTypeGlobals ) if ( !g_wxAnyValueTypeGlobals )
g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals(); g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
g_wxAnyValueTypeGlobals->RegisterValueType(this); g_wxAnyValueTypeGlobals->RegisterValueType(this);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// wxAny // wxAny
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
void wxAny::AssignAny(const wxAny &any) void wxAny::AssignAny(const wxAny &any)
{ {
if ( !any.m_type->IsSameType(m_type) ) if ( !any.m_type->IsSameType(m_type) )
{ {
m_type->DeleteValue(m_buffer); m_type->DeleteValue(m_buffer);
m_type = any.m_type; m_type = any.m_type;
} }
m_type->CopyBuffer(any.m_buffer, m_buffer); m_type->CopyBuffer(any.m_buffer, m_buffer);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Dynamic conversion member functions // Dynamic conversion member functions
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Define integer minimum and maximum as helpers // Define integer minimum and maximum as helpers
#ifdef wxLongLong_t #ifdef wxLongLong_t
const wxAnyBaseIntType UseIntMin = wxINT64_MIN; const wxAnyBaseIntType UseIntMin = wxINT64_MIN;
const wxAnyBaseUintType UseIntMax = wxINT64_MAX; const wxAnyBaseUintType UseIntMax = wxINT64_MAX;
const wxAnyBaseUintType UseUintMax = wxUINT64_MAX; const wxAnyBaseUintType UseUintMax = wxUINT64_MAX;
#else #else
const wxAnyBaseIntType UseIntMin = LONG_MIN; const wxAnyBaseIntType UseIntMin = LONG_MIN;
const wxAnyBaseUintType UseUintMax = ULONG_MAX; const wxAnyBaseUintType UseUintMax = ULONG_MAX;
const wxAnyBaseUintType UseIntMax = LONG_MAX; const wxAnyBaseUintType UseIntMax = LONG_MAX;
#endif #endif
const double UseIntMinF = static_cast<double>(UseIntMin); const double UseIntMinF = static_cast<double>(UseIntMin);
#ifndef __VISUALC6__ #ifndef __VISUALC6__
const double UseIntMaxF = static_cast<double>(UseIntMax); const double UseIntMaxF = static_cast<double>(UseIntMax);
const double UseUintMaxF = static_cast<double>(UseUintMax); const double UseUintMaxF = static_cast<double>(UseUintMax);
#else #else
// VC6 doesn't implement conversion from unsigned __int64 to double // VC6 doesn't implement conversion from unsigned __int64 to double
const wxAnyBaseIntType UseIntMax0 = static_cast<wxAnyBaseIntType>(UseIntMax); const wxAnyBaseIntType UseIntMax0 = static_cast<wxAnyBaseIntType>(UseIntMax);
const wxAnyBaseIntType UseUintMax0 = static_cast<wxAnyBaseIntType>(UseUintMax); const wxAnyBaseIntType UseUintMax0 = static_cast<wxAnyBaseIntType>(UseUintMax);
const double UseIntMaxF = static_cast<double>(UseIntMax0); const double UseIntMaxF = static_cast<double>(UseIntMax0);
const double UseUintMaxF = static_cast<double>(UseUintMax0); const double UseUintMaxF = static_cast<double>(UseUintMax0);
#endif #endif
bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src, bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
wxAnyBaseIntType value = GetValue(src); wxAnyBaseIntType value = GetValue(src);
if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
{ {
#ifdef wxLongLong_t #ifdef wxLongLong_t
wxLongLong ll(value); wxLongLong ll(value);
wxString s = ll.ToString(); wxString s = ll.ToString();
#else #else
wxString s = wxString::Format(wxS("%ld"), (long)value); wxString s = wxString::Format(wxS("%ld"), (long)value);
#endif #endif
wxAnyValueTypeImpl<wxString>::SetValue(s, dst); wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
{ {
if ( value < 0 ) if ( value < 0 )
return false; return false;
wxAnyBaseUintType ul = (wxAnyBaseUintType) value; wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
wxAnyValueTypeImplUint::SetValue(ul, dst); wxAnyValueTypeImplUint::SetValue(ul, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
{ {
double value2 = static_cast<double>(value); double value2 = static_cast<double>(value);
wxAnyValueTypeImplDouble::SetValue(value2, dst); wxAnyValueTypeImplDouble::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
{ {
bool value2 = value ? true : false; bool value2 = value ? true : false;
wxAnyValueTypeImpl<bool>::SetValue(value2, dst); wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
} }
else else
return false; return false;
return true; return true;
} }
bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src, bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
wxAnyBaseUintType value = GetValue(src); wxAnyBaseUintType value = GetValue(src);
if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
{ {
#ifdef wxLongLong_t #ifdef wxLongLong_t
wxULongLong ull(value); wxULongLong ull(value);
wxString s = ull.ToString(); wxString s = ull.ToString();
#else #else
wxString s = wxString::Format(wxS("%lu"), (long)value); wxString s = wxString::Format(wxS("%lu"), (long)value);
#endif #endif
wxAnyValueTypeImpl<wxString>::SetValue(s, dst); wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
{ {
if ( value > UseIntMax ) if ( value > UseIntMax )
return false; return false;
wxAnyBaseIntType l = (wxAnyBaseIntType) value; wxAnyBaseIntType l = (wxAnyBaseIntType) value;
wxAnyValueTypeImplInt::SetValue(l, dst); wxAnyValueTypeImplInt::SetValue(l, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
{ {
#ifndef __VISUALC6__ #ifndef __VISUALC6__
double value2 = static_cast<double>(value); double value2 = static_cast<double>(value);
#else #else
// VC6 doesn't implement conversion from unsigned __int64 to double // VC6 doesn't implement conversion from unsigned __int64 to double
wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value); wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);
double value2 = static_cast<double>(value0); double value2 = static_cast<double>(value0);
#endif #endif
wxAnyValueTypeImplDouble::SetValue(value2, dst); wxAnyValueTypeImplDouble::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
{ {
bool value2 = value ? true : false; bool value2 = value ? true : false;
wxAnyValueTypeImpl<bool>::SetValue(value2, dst); wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
} }
else else
return false; return false;
return true; return true;
} }
bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src, bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
wxString value = GetValue(src); wxString value = GetValue(src);
if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
{ {
wxAnyBaseIntType value2; wxAnyBaseIntType value2;
#ifdef wxLongLong_t #ifdef wxLongLong_t
if ( !value.ToLongLong(&value2) ) if ( !value.ToLongLong(&value2) )
#else #else
if ( !value.ToLong(&value2) ) if ( !value.ToLong(&value2) )
#endif #endif
return false; return false;
wxAnyValueTypeImplInt::SetValue(value2, dst); wxAnyValueTypeImplInt::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
{ {
wxAnyBaseUintType value2; wxAnyBaseUintType value2;
#ifdef wxLongLong_t #ifdef wxLongLong_t
if ( !value.ToULongLong(&value2) ) if ( !value.ToULongLong(&value2) )
#else #else
if ( !value.ToULong(&value2) ) if ( !value.ToULong(&value2) )
#endif #endif
return false; return false;
wxAnyValueTypeImplUint::SetValue(value2, dst); wxAnyValueTypeImplUint::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
{ {
double value2; double value2;
if ( !value.ToDouble(&value2) ) if ( !value.ToDouble(&value2) )
return false; return false;
wxAnyValueTypeImplDouble::SetValue(value2, dst); wxAnyValueTypeImplDouble::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
{ {
bool value2; bool value2;
value.MakeLower(); value.MakeLower();
if ( value == wxS("true") || if ( value == wxS("true") ||
value == wxS("yes") || value == wxS("yes") ||
value == wxS('1') ) value == wxS('1') )
value2 = true; value2 = true;
else if ( value == wxS("false") || else if ( value == wxS("false") ||
value == wxS("no") || value == wxS("no") ||
value == wxS('0') ) value == wxS('0') )
value2 = false; value2 = false;
else else
return false; return false;
wxAnyValueTypeImpl<bool>::SetValue(value2, dst); wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
} }
else else
return false; return false;
return true; return true;
} }
bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src, bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
bool value = GetValue(src); bool value = GetValue(src);
if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
{ {
wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value); wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
wxAnyValueTypeImplInt::SetValue(value2, dst); wxAnyValueTypeImplInt::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
{ {
wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value); wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
wxAnyValueTypeImplUint::SetValue(value2, dst); wxAnyValueTypeImplUint::SetValue(value2, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
{ {
wxString s; wxString s;
if ( value ) if ( value )
s = wxS("true"); s = wxS("true");
else else
s = wxS("false"); s = wxS("false");
wxAnyValueTypeImpl<wxString>::SetValue(s, dst); wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
} }
else else
return false; return false;
return true; return true;
} }
bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src, bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
double value = GetValue(src); double value = GetValue(src);
if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) ) if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
{ {
if ( value < UseIntMinF || value > UseIntMaxF ) if ( value < UseIntMinF || value > UseIntMaxF )
return false; return false;
wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value); wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
wxAnyValueTypeImplUint::SetValue(ul, dst); wxAnyValueTypeImplUint::SetValue(ul, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
{ {
if ( value < 0.0 || value > UseUintMaxF ) if ( value < 0.0 || value > UseUintMaxF )
return false; return false;
wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value); wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
wxAnyValueTypeImplUint::SetValue(ul, dst); wxAnyValueTypeImplUint::SetValue(ul, dst);
} }
else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
{ {
wxString s = wxString::Format(wxS("%.14g"), value); wxString s = wxString::Format(wxS("%.14g"), value);
wxAnyValueTypeImpl<wxString>::SetValue(s, dst); wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
} }
else else
return false; return false;
return true; return true;
} }
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// wxAnyNullValueType implementation // wxAnyNullValueType implementation
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
class wxAnyNullValue class wxAnyNullValue
{ {
private: private:
void* m_dummy; void* m_dummy;
}; };
template <> template <>
class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
{ {
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>) WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
public: public:
virtual void DeleteValue(wxAnyValueBuffer& buf) const virtual void DeleteValue(wxAnyValueBuffer& buf) const
{ {
buf.m_ptr = NULL; // This is important buf.m_ptr = NULL; // This is important
} }
// Dummy implementations // Dummy implementations
virtual void CopyBuffer(const wxAnyValueBuffer& src, virtual void CopyBuffer(const wxAnyValueBuffer& src,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
wxUnusedVar(src); wxUnusedVar(src);
wxUnusedVar(dst); wxUnusedVar(dst);
} }
virtual bool ConvertValue(const wxAnyValueBuffer& src, virtual bool ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
wxUnusedVar(src); wxUnusedVar(src);
wxUnusedVar(dstType); wxUnusedVar(dstType);
wxUnusedVar(dst); wxUnusedVar(dst);
return false; return false;
} }
private: private:
}; };
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
wxAnyValueType* wxAnyNullValueType = wxAnyValueType* wxAnyNullValueType =
wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance(); wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
#endif // wxUSE_ANY #endif // wxUSE_ANY

View File

@@ -1,433 +1,433 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Name: tests/any/anytest.cpp // Name: tests/any/anytest.cpp
// Purpose: Test the wxAny classes // Purpose: Test the wxAny classes
// Author: Jaakko Salli // Author: Jaakko Salli
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) the wxWidgets team // Copyright: (c) the wxWidgets team
// Licence: wxWindows licence // Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include "testprec.h" #include "testprec.h"
#ifdef __BORLANDC__ #ifdef __BORLANDC__
# pragma hdrstop # pragma hdrstop
#endif #endif
#if wxUSE_ANY #if wxUSE_ANY
#include "wx/any.h" #include "wx/any.h"
#include "wx/datetime.h" #include "wx/datetime.h"
#include <math.h> #include <math.h>
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// test class // test class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxAnyTestCase : public CppUnit::TestCase class wxAnyTestCase : public CppUnit::TestCase
{ {
public: public:
wxAnyTestCase(); wxAnyTestCase();
private: private:
CPPUNIT_TEST_SUITE( wxAnyTestCase ); CPPUNIT_TEST_SUITE( wxAnyTestCase );
CPPUNIT_TEST( Equality ); CPPUNIT_TEST( Equality );
CPPUNIT_TEST( As ); CPPUNIT_TEST( As );
CPPUNIT_TEST( GetAs ); CPPUNIT_TEST( GetAs );
CPPUNIT_TEST( Null ); CPPUNIT_TEST( Null );
CPPUNIT_TEST( CustomTemplateSpecialization ); CPPUNIT_TEST( CustomTemplateSpecialization );
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void Equality(); void Equality();
void As(); void As();
void GetAs(); void GetAs();
void Null(); void Null();
void CustomTemplateSpecialization(); void CustomTemplateSpecialization();
wxDateTime m_testDateTime; wxDateTime m_testDateTime;
wxAny m_anySignedChar1; wxAny m_anySignedChar1;
wxAny m_anySignedShort1; wxAny m_anySignedShort1;
wxAny m_anySignedInt1; wxAny m_anySignedInt1;
wxAny m_anySignedLong1; wxAny m_anySignedLong1;
wxAny m_anySignedLongLong1; wxAny m_anySignedLongLong1;
wxAny m_anyUnsignedChar1; wxAny m_anyUnsignedChar1;
wxAny m_anyUnsignedShort1; wxAny m_anyUnsignedShort1;
wxAny m_anyUnsignedInt1; wxAny m_anyUnsignedInt1;
wxAny m_anyUnsignedLong1; wxAny m_anyUnsignedLong1;
wxAny m_anyUnsignedLongLong1; wxAny m_anyUnsignedLongLong1;
wxAny m_anyStringString1; wxAny m_anyStringString1;
wxAny m_anyCharString1; wxAny m_anyCharString1;
wxAny m_anyWcharString1; wxAny m_anyWcharString1;
wxAny m_anyBool1; wxAny m_anyBool1;
wxAny m_anyFloatDouble1; wxAny m_anyFloatDouble1;
wxAny m_anyDoubleDouble1; wxAny m_anyDoubleDouble1;
wxAny m_anyWxObjectPtr1; wxAny m_anyWxObjectPtr1;
wxAny m_anyVoidPtr1; wxAny m_anyVoidPtr1;
wxAny m_anyDateTime1; wxAny m_anyDateTime1;
wxAny m_anySignedChar2; wxAny m_anySignedChar2;
wxAny m_anySignedShort2; wxAny m_anySignedShort2;
wxAny m_anySignedInt2; wxAny m_anySignedInt2;
wxAny m_anySignedLong2; wxAny m_anySignedLong2;
wxAny m_anySignedLongLong2; wxAny m_anySignedLongLong2;
wxAny m_anyUnsignedChar2; wxAny m_anyUnsignedChar2;
wxAny m_anyUnsignedShort2; wxAny m_anyUnsignedShort2;
wxAny m_anyUnsignedInt2; wxAny m_anyUnsignedInt2;
wxAny m_anyUnsignedLong2; wxAny m_anyUnsignedLong2;
wxAny m_anyUnsignedLongLong2; wxAny m_anyUnsignedLongLong2;
wxAny m_anyStringString2; wxAny m_anyStringString2;
wxAny m_anyCharString2; wxAny m_anyCharString2;
wxAny m_anyWcharString2; wxAny m_anyWcharString2;
wxAny m_anyBool2; wxAny m_anyBool2;
wxAny m_anyFloatDouble2; wxAny m_anyFloatDouble2;
wxAny m_anyDoubleDouble2; wxAny m_anyDoubleDouble2;
wxAny m_anyWxObjectPtr2; wxAny m_anyWxObjectPtr2;
wxAny m_anyVoidPtr2; wxAny m_anyVoidPtr2;
wxAny m_anyDateTime2; wxAny m_anyDateTime2;
DECLARE_NO_COPY_CLASS(wxAnyTestCase) DECLARE_NO_COPY_CLASS(wxAnyTestCase)
}; };
// register in the unnamed registry so that these tests are run by default // register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase ); CPPUNIT_TEST_SUITE_REGISTRATION( wxAnyTestCase );
// also include in it's own registry so that these tests can be run alone // also include in it's own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" ); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( wxAnyTestCase, "wxAnyTestCase" );
// Let's use a number with first digit after decimal dot less than 5, // Let's use a number with first digit after decimal dot less than 5,
// so that we don't have to worry about whether conversion from float // so that we don't have to worry about whether conversion from float
// to int truncates or rounds. // to int truncates or rounds.
const double TEST_FLOAT_CONST = 123.456; const double TEST_FLOAT_CONST = 123.456;
const double FEQ_DELTA = 0.001; const double FEQ_DELTA = 0.001;
wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234); wxObject* dummyWxObjectPointer = reinterpret_cast<wxObject*>(1234);
void* dummyVoidPointer = reinterpret_cast<void*>(1234); void* dummyVoidPointer = reinterpret_cast<void*>(1234);
// //
// Test both 'creation' methods // Test both 'creation' methods
wxAnyTestCase::wxAnyTestCase() wxAnyTestCase::wxAnyTestCase()
: m_anySignedChar1((signed char)15), : m_anySignedChar1((signed char)15),
m_anySignedShort1((signed short)15), m_anySignedShort1((signed short)15),
m_anySignedInt1((signed int)15), m_anySignedInt1((signed int)15),
m_anySignedLong1((signed long)15), m_anySignedLong1((signed long)15),
#ifdef wxLongLong_t #ifdef wxLongLong_t
m_anySignedLongLong1((wxLongLong_t)15), m_anySignedLongLong1((wxLongLong_t)15),
#endif #endif
m_anyUnsignedChar1((unsigned char)15), m_anyUnsignedChar1((unsigned char)15),
m_anyUnsignedShort1((unsigned short)15), m_anyUnsignedShort1((unsigned short)15),
m_anyUnsignedInt1((unsigned int)15), m_anyUnsignedInt1((unsigned int)15),
m_anyUnsignedLong1((unsigned long)15), m_anyUnsignedLong1((unsigned long)15),
#ifdef wxLongLong_t #ifdef wxLongLong_t
m_anyUnsignedLongLong1((wxULongLong_t)15), m_anyUnsignedLongLong1((wxULongLong_t)15),
#endif #endif
m_anyStringString1(wxString("abc")), m_anyStringString1(wxString("abc")),
m_anyCharString1("abc"), m_anyCharString1("abc"),
m_anyWcharString1(L"abc"), m_anyWcharString1(L"abc"),
m_anyBool1(true), m_anyBool1(true),
m_anyFloatDouble1((float)TEST_FLOAT_CONST), m_anyFloatDouble1((float)TEST_FLOAT_CONST),
m_anyDoubleDouble1((double)TEST_FLOAT_CONST), m_anyDoubleDouble1((double)TEST_FLOAT_CONST),
m_anyWxObjectPtr1(dummyWxObjectPointer), m_anyWxObjectPtr1(dummyWxObjectPointer),
m_anyVoidPtr1(dummyVoidPointer), m_anyVoidPtr1(dummyVoidPointer),
m_anyDateTime1(wxDateTime::Now()) m_anyDateTime1(wxDateTime::Now())
{ {
m_testDateTime = wxDateTime::Now(); m_testDateTime = wxDateTime::Now();
m_anySignedChar2 = (signed char)15; m_anySignedChar2 = (signed char)15;
m_anySignedShort2 = (signed short)15; m_anySignedShort2 = (signed short)15;
m_anySignedInt2 = (signed int)15; m_anySignedInt2 = (signed int)15;
m_anySignedLong2 = (signed long)15; m_anySignedLong2 = (signed long)15;
#ifdef wxLongLong_t #ifdef wxLongLong_t
m_anySignedLongLong2 = (wxLongLong_t)15; m_anySignedLongLong2 = (wxLongLong_t)15;
#endif #endif
m_anyUnsignedChar2 = (unsigned char)15; m_anyUnsignedChar2 = (unsigned char)15;
m_anyUnsignedShort2 = (unsigned short)15; m_anyUnsignedShort2 = (unsigned short)15;
m_anyUnsignedInt2 = (unsigned int)15; m_anyUnsignedInt2 = (unsigned int)15;
m_anyUnsignedLong2 = (unsigned long)15; m_anyUnsignedLong2 = (unsigned long)15;
#ifdef wxLongLong_t #ifdef wxLongLong_t
m_anyUnsignedLongLong2 = (wxULongLong_t)15; m_anyUnsignedLongLong2 = (wxULongLong_t)15;
#endif #endif
m_anyStringString2 = wxString("abc"); m_anyStringString2 = wxString("abc");
m_anyCharString2 = "abc"; m_anyCharString2 = "abc";
m_anyWcharString2 = L"abc"; m_anyWcharString2 = L"abc";
m_anyBool2 = true; m_anyBool2 = true;
m_anyFloatDouble2 = (float)TEST_FLOAT_CONST; m_anyFloatDouble2 = (float)TEST_FLOAT_CONST;
m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST; m_anyDoubleDouble2 = (double)TEST_FLOAT_CONST;
m_anyDateTime2 = m_testDateTime; m_anyDateTime2 = m_testDateTime;
m_anyWxObjectPtr2 = dummyWxObjectPointer; m_anyWxObjectPtr2 = dummyWxObjectPointer;
m_anyVoidPtr2 = dummyVoidPointer; m_anyVoidPtr2 = dummyVoidPointer;
} }
void wxAnyTestCase::Equality() void wxAnyTestCase::Equality()
{ {
// //
// Currently this should work // Currently this should work
CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L); CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15L);
CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L); CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30L);
CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL); CPPUNIT_ASSERT(m_anyUnsignedLong1 == 15UL);
CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL); CPPUNIT_ASSERT(m_anyUnsignedLong1 != 30UL);
CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc")); CPPUNIT_ASSERT(m_anyStringString1 == wxString("abc"));
CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC")); CPPUNIT_ASSERT(m_anyStringString1 != wxString("ABC"));
CPPUNIT_ASSERT(m_anyStringString1 == "abc"); CPPUNIT_ASSERT(m_anyStringString1 == "abc");
CPPUNIT_ASSERT(m_anyStringString1 != "ABC"); CPPUNIT_ASSERT(m_anyStringString1 != "ABC");
CPPUNIT_ASSERT(m_anyStringString1 == L"abc"); CPPUNIT_ASSERT(m_anyStringString1 == L"abc");
CPPUNIT_ASSERT(m_anyStringString1 != L"ABC"); CPPUNIT_ASSERT(m_anyStringString1 != L"ABC");
CPPUNIT_ASSERT(m_anyBool1 == true); CPPUNIT_ASSERT(m_anyBool1 == true);
CPPUNIT_ASSERT(m_anyBool1 != false); CPPUNIT_ASSERT(m_anyBool1 != false);
CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double), CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
wxANY_AS(m_anyDoubleDouble1, double), wxANY_AS(m_anyDoubleDouble1, double),
FEQ_DELTA); FEQ_DELTA);
CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double), CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble1, double),
TEST_FLOAT_CONST, TEST_FLOAT_CONST,
FEQ_DELTA); FEQ_DELTA);
CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*) CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr1, wxObject*)
== dummyWxObjectPointer); == dummyWxObjectPointer);
CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer); CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr1, void*) == dummyVoidPointer);
CPPUNIT_ASSERT(m_anySignedLong2 == 15); CPPUNIT_ASSERT(m_anySignedLong2 == 15);
CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc")); CPPUNIT_ASSERT(m_anyStringString2 == wxString("abc"));
CPPUNIT_ASSERT(m_anyStringString2 == "abc"); CPPUNIT_ASSERT(m_anyStringString2 == "abc");
CPPUNIT_ASSERT(m_anyStringString2 == L"abc"); CPPUNIT_ASSERT(m_anyStringString2 == L"abc");
CPPUNIT_ASSERT(m_anyBool2 == true); CPPUNIT_ASSERT(m_anyBool2 == true);
CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double), CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
wxANY_AS(m_anyDoubleDouble2, double), wxANY_AS(m_anyDoubleDouble2, double),
FEQ_DELTA); FEQ_DELTA);
CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double), CPPUNIT_ASSERT_DOUBLES_EQUAL(wxANY_AS(m_anyFloatDouble2, double),
TEST_FLOAT_CONST, TEST_FLOAT_CONST,
FEQ_DELTA); FEQ_DELTA);
CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*) CPPUNIT_ASSERT(wxANY_AS(m_anyWxObjectPtr2, wxObject*)
== dummyWxObjectPointer); == dummyWxObjectPointer);
CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer); CPPUNIT_ASSERT(wxANY_AS(m_anyVoidPtr2, void*) == dummyVoidPointer);
} }
void wxAnyTestCase::As() void wxAnyTestCase::As()
{ {
// //
// Test getting C++ data from wxAny without dynamic conversion // Test getting C++ data from wxAny without dynamic conversion
signed char a = wxANY_AS(m_anySignedChar1, signed char); signed char a = wxANY_AS(m_anySignedChar1, signed char);
CPPUNIT_ASSERT(a == (signed int)15); CPPUNIT_ASSERT(a == (signed int)15);
signed short b = wxANY_AS(m_anySignedShort1, signed short); signed short b = wxANY_AS(m_anySignedShort1, signed short);
CPPUNIT_ASSERT(b == (signed int)15); CPPUNIT_ASSERT(b == (signed int)15);
signed int c = wxANY_AS(m_anySignedInt1, signed int); signed int c = wxANY_AS(m_anySignedInt1, signed int);
CPPUNIT_ASSERT(c == (signed int)15); CPPUNIT_ASSERT(c == (signed int)15);
signed long d = wxANY_AS(m_anySignedLong1, signed long); signed long d = wxANY_AS(m_anySignedLong1, signed long);
CPPUNIT_ASSERT(d == (signed int)15); CPPUNIT_ASSERT(d == (signed int)15);
#ifdef wxLongLong_t #ifdef wxLongLong_t
wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t); wxLongLong_t e = wxANY_AS(m_anySignedLongLong1, wxLongLong_t);
CPPUNIT_ASSERT(e == (signed int)15); CPPUNIT_ASSERT(e == (signed int)15);
#endif #endif
unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char); unsigned char f = wxANY_AS(m_anyUnsignedChar1, unsigned char);
CPPUNIT_ASSERT(f == (unsigned int)15); CPPUNIT_ASSERT(f == (unsigned int)15);
unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short); unsigned short g = wxANY_AS(m_anyUnsignedShort1, unsigned short);
CPPUNIT_ASSERT(g == (unsigned int)15); CPPUNIT_ASSERT(g == (unsigned int)15);
unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int); unsigned int h = wxANY_AS(m_anyUnsignedInt1, unsigned int);
CPPUNIT_ASSERT(h == (unsigned int)15); CPPUNIT_ASSERT(h == (unsigned int)15);
unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long); unsigned long i = wxANY_AS(m_anyUnsignedLong1, unsigned long);
CPPUNIT_ASSERT(i == (unsigned int)15); CPPUNIT_ASSERT(i == (unsigned int)15);
#ifdef wxLongLong_t #ifdef wxLongLong_t
wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t); wxULongLong_t j = wxANY_AS(m_anyUnsignedLongLong1, wxULongLong_t);
CPPUNIT_ASSERT(j == (unsigned int)15); CPPUNIT_ASSERT(j == (unsigned int)15);
#endif #endif
wxString k = wxANY_AS(m_anyStringString1, wxString); wxString k = wxANY_AS(m_anyStringString1, wxString);
CPPUNIT_ASSERT(k == "abc"); CPPUNIT_ASSERT(k == "abc");
wxString l = wxANY_AS(m_anyCharString1, wxString); wxString l = wxANY_AS(m_anyCharString1, wxString);
CPPUNIT_ASSERT(l == "abc"); CPPUNIT_ASSERT(l == "abc");
wxString m = wxANY_AS(m_anyWcharString1, wxString); wxString m = wxANY_AS(m_anyWcharString1, wxString);
CPPUNIT_ASSERT(m == "abc"); CPPUNIT_ASSERT(m == "abc");
bool n = wxANY_AS(m_anyBool1, bool); bool n = wxANY_AS(m_anyBool1, bool);
CPPUNIT_ASSERT(n); CPPUNIT_ASSERT(n);
float o = wxANY_AS(m_anyFloatDouble1, float); float o = wxANY_AS(m_anyFloatDouble1, float);
CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA); CPPUNIT_ASSERT_DOUBLES_EQUAL(o, TEST_FLOAT_CONST, FEQ_DELTA);
double p = wxANY_AS(m_anyDoubleDouble1, double); double p = wxANY_AS(m_anyDoubleDouble1, double);
CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA); CPPUNIT_ASSERT_DOUBLES_EQUAL(p, TEST_FLOAT_CONST, FEQ_DELTA);
wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime); wxDateTime q = wxANY_AS(m_anyDateTime1, wxDateTime);
CPPUNIT_ASSERT(q == m_testDateTime); CPPUNIT_ASSERT(q == m_testDateTime);
wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*); wxObject* r = wxANY_AS(m_anyWxObjectPtr1, wxObject*);
CPPUNIT_ASSERT(r == dummyWxObjectPointer); CPPUNIT_ASSERT(r == dummyWxObjectPointer);
void* s = wxANY_AS(m_anyVoidPtr1, void*); void* s = wxANY_AS(m_anyVoidPtr1, void*);
CPPUNIT_ASSERT(s == dummyVoidPointer); CPPUNIT_ASSERT(s == dummyVoidPointer);
} }
void wxAnyTestCase::Null() void wxAnyTestCase::Null()
{ {
wxAny a; wxAny a;
CPPUNIT_ASSERT(a.IsNull()); CPPUNIT_ASSERT(a.IsNull());
a = -127; a = -127;
CPPUNIT_ASSERT(a == -127); CPPUNIT_ASSERT(a == -127);
a.MakeNull(); a.MakeNull();
CPPUNIT_ASSERT(a.IsNull()); CPPUNIT_ASSERT(a.IsNull());
} }
void wxAnyTestCase::GetAs() void wxAnyTestCase::GetAs()
{ {
// //
// Test dynamic conversion // Test dynamic conversion
bool res; bool res;
long l = 0; long l = 0;
unsigned long ul = 0; unsigned long ul = 0;
wxString s; wxString s;
// Let's test against float instead of double, since the former // Let's test against float instead of double, since the former
// is not the native underlying type the code converts to, but // is not the native underlying type the code converts to, but
// should still work, all the same. // should still work, all the same.
float f = 0.0; float f = 0.0;
bool b = false; bool b = false;
// Conversions from signed long type // Conversions from signed long type
res = m_anySignedLong1.GetAs(&ul); res = m_anySignedLong1.GetAs(&ul);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15)); CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
res = m_anySignedLong1.GetAs(&s); res = m_anySignedLong1.GetAs(&s);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(s == "15"); CPPUNIT_ASSERT(s == "15");
res = m_anySignedLong1.GetAs(&f); res = m_anySignedLong1.GetAs(&f);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA); CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
res = m_anySignedLong1.GetAs(&b); res = m_anySignedLong1.GetAs(&b);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(b == true); CPPUNIT_ASSERT(b == true);
// Conversions from unsigned long type // Conversions from unsigned long type
res = m_anyUnsignedLong1.GetAs(&l); res = m_anyUnsignedLong1.GetAs(&l);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(l == static_cast<signed long>(15)); CPPUNIT_ASSERT(l == static_cast<signed long>(15));
res = m_anyUnsignedLong1.GetAs(&s); res = m_anyUnsignedLong1.GetAs(&s);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(s == "15"); CPPUNIT_ASSERT(s == "15");
res = m_anyUnsignedLong1.GetAs(&f); res = m_anyUnsignedLong1.GetAs(&f);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA); CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
res = m_anyUnsignedLong1.GetAs(&b); res = m_anyUnsignedLong1.GetAs(&b);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(b == true); CPPUNIT_ASSERT(b == true);
// Conversions from default "abc" string to other types // Conversions from default "abc" string to other types
// should not work. // should not work.
CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l)); CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&l));
CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul)); CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&ul));
CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f)); CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&f));
CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b)); CPPUNIT_ASSERT(!m_anyStringString1.GetAs(&b));
// Let's test some other conversions from string that should work. // Let's test some other conversions from string that should work.
wxAny anyString; wxAny anyString;
anyString = "15"; anyString = "15";
res = anyString.GetAs(&l); res = anyString.GetAs(&l);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(l == static_cast<signed long>(15)); CPPUNIT_ASSERT(l == static_cast<signed long>(15));
res = anyString.GetAs(&ul); res = anyString.GetAs(&ul);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15)); CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(15));
res = anyString.GetAs(&f); res = anyString.GetAs(&f);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA); CPPUNIT_ASSERT_DOUBLES_EQUAL(f, 15.0, FEQ_DELTA);
anyString = "TRUE"; anyString = "TRUE";
res = anyString.GetAs(&b); res = anyString.GetAs(&b);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(b == true); CPPUNIT_ASSERT(b == true);
anyString = "0"; anyString = "0";
res = anyString.GetAs(&b); res = anyString.GetAs(&b);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(b == false); CPPUNIT_ASSERT(b == false);
// Conversions from bool type // Conversions from bool type
res = m_anyBool1.GetAs(&l); res = m_anyBool1.GetAs(&l);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(l == static_cast<signed long>(1)); CPPUNIT_ASSERT(l == static_cast<signed long>(1));
res = m_anyBool1.GetAs(&ul); res = m_anyBool1.GetAs(&ul);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1)); CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(1));
res = m_anyBool1.GetAs(&s); res = m_anyBool1.GetAs(&s);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(s == "true"); CPPUNIT_ASSERT(s == "true");
CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f)); CPPUNIT_ASSERT(!m_anyBool1.GetAs(&f));
// Conversions from floating point type // Conversions from floating point type
res = m_anyDoubleDouble1.GetAs(&l); res = m_anyDoubleDouble1.GetAs(&l);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT(l == static_cast<signed long>(123)); CPPUNIT_ASSERT(l == static_cast<signed long>(123));
res = m_anyDoubleDouble1.GetAs(&ul); res = m_anyDoubleDouble1.GetAs(&ul);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123)); CPPUNIT_ASSERT_EQUAL(ul, static_cast<unsigned long>(123));
res = m_anyDoubleDouble1.GetAs(&s); res = m_anyDoubleDouble1.GetAs(&s);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
double d2; double d2;
res = s.ToDouble(&d2); res = s.ToDouble(&d2);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA); CPPUNIT_ASSERT_DOUBLES_EQUAL(d2, TEST_FLOAT_CONST, FEQ_DELTA);
} }
// //
// Test user data type specialization of wxAnyValueTypeImpl // Test user data type specialization of wxAnyValueTypeImpl
// //
class MyClass class MyClass
{ {
public: public:
MyClass( int someValue = 32768 ) MyClass( int someValue = 32768 )
{ {
m_someValue = someValue; m_someValue = someValue;
} }
wxString ToString() wxString ToString()
{ {
return wxString::Format("%i", m_someValue); return wxString::Format("%i", m_someValue);
} }
private: private:
int m_someValue; int m_someValue;
}; };
template<> template<>
class wxAnyValueTypeImpl<MyClass> : class wxAnyValueTypeImpl<MyClass> :
public wxAnyValueTypeImplBase<MyClass> public wxAnyValueTypeImplBase<MyClass>
{ {
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>) WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
public: public:
wxAnyValueTypeImpl() : wxAnyValueTypeImpl() :
wxAnyValueTypeImplBase<MyClass>() { } wxAnyValueTypeImplBase<MyClass>() { }
virtual ~wxAnyValueTypeImpl() { } virtual ~wxAnyValueTypeImpl() { }
virtual bool ConvertValue(const wxAnyValueBuffer& src, virtual bool ConvertValue(const wxAnyValueBuffer& src,
wxAnyValueType* dstType, wxAnyValueType* dstType,
wxAnyValueBuffer& dst) const wxAnyValueBuffer& dst) const
{ {
MyClass value = GetValue(src); MyClass value = GetValue(src);
if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) ) if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
{ {
wxString s = value.ToString(); wxString s = value.ToString();
wxAnyValueTypeImpl<wxString>::SetValue(s, dst); wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
} }
else else
return false; return false;
return true; return true;
} }
}; };
// //
// Following must be placed somewhere in your source code // Following must be placed somewhere in your source code
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>) WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
void wxAnyTestCase::CustomTemplateSpecialization() void wxAnyTestCase::CustomTemplateSpecialization()
{ {
// Do only a minimal CheckType() test, as dynamic type conversion already // Do only a minimal CheckType() test, as dynamic type conversion already
// uses it a lot. // uses it a lot.
bool res; bool res;
MyClass myObject; MyClass myObject;
wxAny any = myObject; wxAny any = myObject;
CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) ); CPPUNIT_ASSERT( wxANY_CHECK_TYPE(any, MyClass) );
MyClass myObject2 = wxANY_AS(any, MyClass); MyClass myObject2 = wxANY_AS(any, MyClass);
wxUnusedVar(myObject2); wxUnusedVar(myObject2);
wxString str; wxString str;
res = any.GetAs(&str); res = any.GetAs(&str);
CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(res);
CPPUNIT_ASSERT_EQUAL(str, myObject.ToString()); CPPUNIT_ASSERT_EQUAL(str, myObject.ToString());
} }
#endif // wxUSE_ANY #endif // wxUSE_ANY