X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9a0a58f5afb88fc72f04333e32208e3b3bf2ccc5..c5d4360fc99a0b9bd512e9dc19087c96dc669345:/include/wx/variant.h diff --git a/include/wx/variant.h b/include/wx/variant.h index dffe0a0190..39adc729b9 100644 --- a/include/wx/variant.h +++ b/include/wx/variant.h @@ -4,7 +4,6 @@ // Author: Julian Smart // Modified by: // Created: 10/09/98 -// RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -21,26 +20,21 @@ #include "wx/arrstr.h" #include "wx/list.h" #include "wx/cpp.h" +#include "wx/longlong.h" #if wxUSE_DATETIME #include "wx/datetime.h" #endif // wxUSE_DATETIME -#if wxUSE_ODBC - #include "wx/db.h" // will #include sqltypes.h -#endif //ODBC - #include "wx/iosfwrap.h" +class wxAny; + /* * wxVariantData stores the actual data in a wxVariant object, * to allow it to store any type of data. * Derive from this to provide custom data handling. * - * NB: To prevent addition of extra vtbl pointer to wxVariantData, - * we don't multiple-inherit from wxObjectRefData. Instead, - * we simply replicate the wxObject ref-counting scheme. - * * NB: When you construct a wxVariantData, it will have refcount * of one. Refcount will not be further increased when * it is passed to wxVariant. This simulates old common @@ -59,11 +53,11 @@ * overloading wxVariant with unnecessary functionality. */ -class WXDLLIMPEXP_BASE wxVariantData +class WXDLLIMPEXP_BASE wxVariantData : public wxObjectRefData { friend class wxVariant; public: - wxVariantData() : m_count(1) { } + wxVariantData() { } // Override these to provide common functionality virtual bool Eq(wxVariantData& data) const = 0; @@ -81,30 +75,27 @@ public: // If it based on wxObject return the ClassInfo. virtual wxClassInfo* GetValueClassInfo() { return NULL; } - void IncRef() { m_count++; } - void DecRef() - { - if ( --m_count == 0 ) - delete this; - } + // Implement this to make wxVariant::UnShare work. Returns + // a copy of the data. + virtual wxVariantData* Clone() const { return NULL; } - int GetRefCount() const { return m_count; } +#if wxUSE_ANY + // Converts value to wxAny, if possible. Return true if successful. + virtual bool GetAsAny(wxAny* WXUNUSED(any)) const { return false; } +#endif protected: // Protected dtor should make some incompatible code // break more louder. That is, they should do data->DecRef() // instead of delete data. virtual ~wxVariantData() { } - -private: - int m_count; }; /* * wxVariant can store any kind of data, but has some basic types * built in. */ - + class WXDLLIMPEXP_FWD_BASE wxVariant; WX_DECLARE_LIST_WITH_DECL(wxVariant, wxVariantList, class WXDLLIMPEXP_BASE); @@ -116,6 +107,9 @@ public: wxVariant(const wxVariant& variant); wxVariant(wxVariantData* data, const wxString& name = wxEmptyString); +#if wxUSE_ANY + wxVariant(const wxAny& any); +#endif virtual ~wxVariant(); // generic assignment @@ -137,14 +131,17 @@ public: // For compatibility with wxWidgets <= 2.6, this doesn't increase // reference count. - wxVariantData* GetData() const { return m_data; } + wxVariantData* GetData() const + { + return (wxVariantData*) m_refData; + } void SetData(wxVariantData* data) ; // make a 'clone' of the object - void Ref(const wxVariant& clone); + void Ref(const wxVariant& clone) { wxObject::Ref(clone); } - // destroy a reference - void UnRef(); + // ensure that the data is exclusive to this variant, and not shared + bool Unshare(); // Make NULL (i.e. delete the data) void MakeNull(); @@ -162,6 +159,10 @@ public: // write contents to a string (e.g. for debugging) wxString MakeString() const; +#if wxUSE_ANY + wxAny GetAny() const; +#endif + // double wxVariant(double val, const wxString& name = wxEmptyString); bool operator== (double value) const; @@ -183,31 +184,19 @@ public: long GetLong() const; // bool -#ifdef HAVE_BOOL wxVariant(bool val, const wxString& name = wxEmptyString); bool operator== (bool value) const; bool operator!= (bool value) const; void operator= (bool value) ; inline operator bool () const { return GetBool(); } bool GetBool() const ; -#endif // wxDateTime #if wxUSE_DATETIME wxVariant(const wxDateTime& val, const wxString& name = wxEmptyString); -#if wxUSE_ODBC - wxVariant(const DATE_STRUCT* valptr, const wxString& name = wxEmptyString); - wxVariant(const TIME_STRUCT* valptr, const wxString& name = wxEmptyString); - wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name = wxEmptyString); -#endif bool operator== (const wxDateTime& value) const; bool operator!= (const wxDateTime& value) const; void operator= (const wxDateTime& value) ; -#if wxUSE_ODBC - void operator= (const DATE_STRUCT* value) ; - void operator= (const TIME_STRUCT* value) ; - void operator= (const TIMESTAMP_STRUCT* value) ; -#endif inline operator wxDateTime () const { return GetDateTime(); } wxDateTime GetDateTime() const; #endif @@ -219,8 +208,8 @@ public: wxVariant(const char* val, const wxString& name = wxEmptyString); wxVariant(const wchar_t* val, const wxString& name = wxEmptyString); wxVariant(const wxCStrData& val, const wxString& name = wxEmptyString); - wxVariant(const wxCharBuffer& val, const wxString& name = wxEmptyString); - wxVariant(const wxWCharBuffer& val, const wxString& name = wxEmptyString); + wxVariant(const wxScopedCharBuffer& val, const wxString& name = wxEmptyString); + wxVariant(const wxScopedWCharBuffer& val, const wxString& name = wxEmptyString); bool operator== (const wxString& value) const; bool operator!= (const wxString& value) const; @@ -234,12 +223,32 @@ public: wxVariant& operator=(const wxCStrData& value) { return *this = value.AsString(); } template - wxVariant& operator=(const wxCharTypeBuffer& value) + wxVariant& operator=(const wxScopedCharTypeBuffer& value) { return *this = value.data(); } inline operator wxString () const { return MakeString(); } wxString GetString() const; +#if wxUSE_STD_STRING + wxVariant(const std::string& val, const wxString& name = wxEmptyString); + bool operator==(const std::string& value) const + { return operator==(wxString(value)); } + bool operator!=(const std::string& value) const + { return operator!=(wxString(value)); } + wxVariant& operator=(const std::string& value) + { return operator=(wxString(value)); } + operator std::string() const { return (operator wxString()).ToStdString(); } + + wxVariant(const wxStdWideString& val, const wxString& name = wxEmptyString); + bool operator==(const wxStdWideString& value) const + { return operator==(wxString(value)); } + bool operator!=(const wxStdWideString& value) const + { return operator!=(wxString(value)); } + wxVariant& operator=(const wxStdWideString& value) + { return operator=(wxString(value)); } + operator wxStdWideString() const { return (operator wxString()).ToStdWstring(); } +#endif // wxUSE_STD_STRING + // wxUniChar wxVariant(const wxUniChar& val, const wxString& name = wxEmptyString); wxVariant(const wxUniCharRef& val, const wxString& name = wxEmptyString); @@ -285,6 +294,23 @@ public: void operator= (wxObject* value); wxObject* GetWxObjectPtr() const; +#if wxUSE_LONGLONG + // wxLongLong + wxVariant(wxLongLong, const wxString& name = wxEmptyString); + bool operator==(wxLongLong value) const; + bool operator!=(wxLongLong value) const; + void operator=(wxLongLong value); + operator wxLongLong() const { return GetLongLong(); } + wxLongLong GetLongLong() const; + + // wxULongLong + wxVariant(wxULongLong, const wxString& name = wxEmptyString); + bool operator==(wxULongLong value) const; + bool operator!=(wxULongLong value) const; + void operator=(wxULongLong value); + operator wxULongLong() const { return GetULongLong(); } + wxULongLong GetULongLong() const; +#endif // ------------------------------ // list operations @@ -332,16 +358,118 @@ public: #if wxUSE_DATETIME bool Convert(wxDateTime* value) const; #endif // wxUSE_DATETIME +#if wxUSE_LONGLONG + bool Convert(wxLongLong* value) const; + bool Convert(wxULongLong* value) const; + #ifdef wxLongLong_t + bool Convert(wxLongLong_t* value) const + { + wxLongLong temp; + if ( !Convert(&temp) ) + return false; + *value = temp.GetValue(); + return true; + } + bool Convert(wxULongLong_t* value) const + { + wxULongLong temp; + if ( !Convert(&temp) ) + return false; + *value = temp.GetValue(); + return true; + } + #endif // wxLongLong_t +#endif // wxUSE_LONGLONG // Attributes protected: - wxVariantData* m_data; + virtual wxObjectRefData *CreateRefData() const; + virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const; + wxString m_name; private: DECLARE_DYNAMIC_CLASS(wxVariant) }; + +// +// wxVariant <-> wxAny conversion code +// +#if wxUSE_ANY + +#include "wx/any.h" + +// In order to convert wxAny to wxVariant, we need to be able to associate +// wxAnyValueType with a wxVariantData factory function. +typedef wxVariantData* (*wxVariantDataFactory)(const wxAny& any); + +// Actual Any-to-Variant registration must be postponed to a time when all +// global variables have been initialized. Hence this arrangement. +// wxAnyToVariantRegistration instances are kept in global scope and +// wxAnyValueTypeGlobals in any.cpp will use their data when the time is +// right. +class WXDLLIMPEXP_BASE wxAnyToVariantRegistration +{ +public: + wxAnyToVariantRegistration(wxVariantDataFactory factory); + virtual ~wxAnyToVariantRegistration(); + + virtual wxAnyValueType* GetAssociatedType() = 0; + wxVariantDataFactory GetFactory() const { return m_factory; } +private: + wxVariantDataFactory m_factory; +}; + +template +class wxAnyToVariantRegistrationImpl : public wxAnyToVariantRegistration +{ +public: + wxAnyToVariantRegistrationImpl(wxVariantDataFactory factory) + : wxAnyToVariantRegistration(factory) + { + } + + virtual wxAnyValueType* GetAssociatedType() + { + return wxAnyValueTypeImpl::GetInstance(); + } +private: +}; + +#define DECLARE_WXANY_CONVERSION() \ +virtual bool GetAsAny(wxAny* any) const; \ +static wxVariantData* VariantDataFactory(const wxAny& any); + +#define _REGISTER_WXANY_CONVERSION(T, CLASSNAME, FUNC) \ +static wxAnyToVariantRegistrationImpl \ + gs_##CLASSNAME##AnyToVariantRegistration = \ + wxAnyToVariantRegistrationImpl(&FUNC); + +#define REGISTER_WXANY_CONVERSION(T, CLASSNAME) \ +_REGISTER_WXANY_CONVERSION(T, CLASSNAME, CLASSNAME::VariantDataFactory) + +#define IMPLEMENT_TRIVIAL_WXANY_CONVERSION(T, CLASSNAME) \ +bool CLASSNAME::GetAsAny(wxAny* any) const \ +{ \ + *any = m_value; \ + return true; \ +} \ +wxVariantData* CLASSNAME::VariantDataFactory(const wxAny& any) \ +{ \ + return new CLASSNAME(wxANY_AS(any, T)); \ +} \ +REGISTER_WXANY_CONVERSION(T, CLASSNAME) + +#else // if !wxUSE_ANY + +#define DECLARE_WXANY_CONVERSION() +#define REGISTER_WXANY_CONVERSION(T, CLASSNAME) +#define IMPLEMENT_TRIVIAL_WXANY_CONVERSION(T, CLASSNAME) + +#endif // wxUSE_ANY/!wxUSE_ANY + + #define DECLARE_VARIANT_OBJECT(classname) \ DECLARE_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE) @@ -366,6 +494,9 @@ public:\ virtual wxString GetType() const; \ virtual wxClassInfo* GetValueClassInfo(); \ \ + virtual wxVariantData* Clone() const { return new classname##VariantData(m_value); } \ +\ + DECLARE_WXANY_CONVERSION() \ protected:\ classname m_value; \ };\ @@ -394,7 +525,8 @@ expdecl wxVariant& operator << ( wxVariant &variant, const classname &value )\ classname##VariantData *data = new classname##VariantData( value );\ variant.SetData( data );\ return variant;\ -} +} \ +IMPLEMENT_TRIVIAL_WXANY_CONVERSION(classname, classname##VariantData) // implements a wxVariantData-derived class using for the Eq() method the // operator== which must have been provided by "classname" @@ -436,6 +568,13 @@ bool classname##VariantData::Eq(wxVariantData& data) const \ ((classname*)(var.IsValueKindOf(&classname::ms_classInfo) ?\ var.GetWxObjectPtr() : NULL)); +// Replacement for using wxDynamicCast on a wxVariantData object +#ifndef wxNO_RTTI + #define wxDynamicCastVariantData(data, classname) dynamic_cast(data) +#endif + +#define wxStaticCastVariantData(data, classname) static_cast(data) + extern wxVariant WXDLLIMPEXP_BASE wxNullVariant; #endif // wxUSE_VARIANT