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

View File

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

View File

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