wxAny initial commit (closes #10932)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61971 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Jaakko Salli
2009-09-19 08:51:11 +00:00
parent 11c2b0413a
commit 178c77606f
44 changed files with 2343 additions and 3 deletions

402
src/common/any.cpp Normal file
View File

@@ -0,0 +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