From: Julian Smart Date: Fri, 19 Oct 2007 15:01:54 +0000 (+0000) Subject: Added wxVariantData::Clone and wxVariant::Unshare X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/c8058a09e5147657342e02e50cf471d7b751abc1 Added wxVariantData::Clone and wxVariant::Unshare git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49246 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index bc46d45cb3..74998a35ca 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -111,6 +111,10 @@ Changes in behaviour which may result in compilation errors - Removed global GetLine() function from wx/protocol/protocol.h, use wxProtocol::ReadLine() instead. + +- wxVariant no longer derives from wxObject. wxVariantData also no longer + derives from wxObject; instead of using wxDynamicCast with wxVariantData you + can use the macro wxDynamicCastVariantData with the same arguments. Deprecated methods and their replacements @@ -156,6 +160,8 @@ All: - Documentation now includes the wx library in which each class is defined. - wxrc --gettext now generates references to source .xrc files (Heikki Linnakangas). +- wxVariant::Unshare allows exclusive allocation of data that must be shared, + if the wxVariantData::Clone function is implemented. All (Unix): diff --git a/docs/latex/wx/variant.tex b/docs/latex/wx/variant.tex index 8343da9923..db82e17c9e 100644 --- a/docs/latex/wx/variant.tex +++ b/docs/latex/wx/variant.tex @@ -74,7 +74,14 @@ IMPLEMENT_VARIANT_OBJECT(wxBitmap) Note that as of wxWidgets 2.9.0, wxVariantData no longer inherits from wxObject and wxVariant no longer uses the type-unsafe wxList class for list -operations but the type-safe wxVariantList class. +operations but the type-safe wxVariantList class. Also, wxVariantData now +supports the Clone function for implementing the \helpref{wxVariant::Unshare}{wxvariantunshare} function. +Clone is implemented automatically by IMPLEMENT\_VARIANT\_OBJECT. + +Since wxVariantData no longer derives from wxObject, any code that tests the type +of the data using wxDynamicCast will require adjustment. You can use the macro +wxDynamicCastVariantData with the same arguments as wxDynamicCast, to use C++ RTTI +type information instead of wxWidgets RTTI. \wxheading{Derived from} @@ -364,6 +371,15 @@ is of type list, but the number of elements in the list is zero. Sets the internal variant data, deleting the existing data if there is any. +\membersection{wxVariant::Unshare}\label{wxvariantunshare} + +\func{bool}{Unshare}{\void} + +Makes sure that any data associated with this variant is not shared with other +variants. For this to work, \helpref{wxVariantData::Clone}{wxvariantdataclone} must +be implemented for the data types you are working with. Clone is implemented +for all the default data types. + \membersection{wxVariant::operator $=$}\label{wxvariantassignment} \func{void}{operator $=$}{\param{const wxVariant\& }{value}} @@ -544,6 +560,14 @@ No base class Default constructor. +\membersection{wxVariantData::Clone}\label{wxvariantdataclone} + +\constfunc{wxVariantData*}{Clone}{\void} + +This function can be overridden to clone the data. +Implement Clone if you wish \helpref{wxVariant::Unshare}{wxvariantunshare} to work +for your data. This function is implemented for all built-in data types. + \membersection{wxVariantData::DecRef}\label{wxvariantdatadecref} \func{void}{DecRef}{\void} @@ -555,7 +579,6 @@ Note that destructor of wxVariantData is protected, so delete cannot be used as normal. Instead, \helpref{DecRef}{wxvariantdatadecref} should be called. - \membersection{wxVariantData::Eq}\label{wxvariantdataeq} \constfunc{bool}{Eq}{\param{wxVariantData\&}{ data}} diff --git a/include/wx/variant.h b/include/wx/variant.h index dffe0a0190..31fbbc8acb 100644 --- a/include/wx/variant.h +++ b/include/wx/variant.h @@ -81,6 +81,10 @@ public: // If it based on wxObject return the ClassInfo. virtual wxClassInfo* GetValueClassInfo() { return NULL; } + // Implement this to make wxVariant::AllocExcusive work. Returns + // a copy of the data. + virtual wxVariantData* Clone() const { return NULL; } + void IncRef() { m_count++; } void DecRef() { @@ -104,7 +108,7 @@ private: * 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); @@ -146,6 +150,9 @@ public: // 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(); @@ -365,6 +372,8 @@ public:\ \ virtual wxString GetType() const; \ virtual wxClassInfo* GetValueClassInfo(); \ +\ + virtual wxVariantData* Clone() const { return new classname##VariantData(m_value); } \ \ protected:\ classname m_value; \ @@ -436,6 +445,9 @@ bool classname##VariantData::Eq(wxVariantData& data) const \ ((classname*)(var.IsValueKindOf(&classname::ms_classInfo) ?\ var.GetWxObjectPtr() : NULL)); +// Replacement for using wxDynamicCast on a wxVariantData object +#define wxDynamicCastVariantData(data, classname) dynamic_cast(data) + extern wxVariant WXDLLIMPEXP_BASE wxNullVariant; #endif // wxUSE_VARIANT diff --git a/src/common/variant.cpp b/src/common/variant.cpp index 8f3344671f..5120dc5554 100644 --- a/src/common/variant.cpp +++ b/src/common/variant.cpp @@ -130,7 +130,6 @@ bool wxVariant::operator!= (const wxVariant& variant) const return (!(*this == variant)); } - wxString wxVariant::MakeString() const { if (!IsNull()) @@ -177,6 +176,30 @@ void wxVariant::UnRef() } } +bool wxVariant::Unshare() +{ + if ( m_data && m_data->GetRefCount() > 1 ) + { + // note that ref is not going to be destroyed in this case... + const wxVariantData* ref = m_data; + UnRef(); + + // ... so we can still access it + m_data = ref->Clone(); + + wxASSERT_MSG( (m_data && m_data->GetRefCount() == 1), + _T("wxVariant::AllocExclusive() failed.") ); + + if (!m_data || m_data->GetRefCount() != 1) + return false; + else + return true; + } + //else: data is null or ref count is 1, so we are exclusive owners of m_refData anyhow + else + return true; +} + // Returns a string representing the type of the variant, // e.g. "string", "bool", "list", "double", "long" @@ -227,6 +250,8 @@ public: virtual bool Write(wxOutputStream &str) const; #endif // wxUSE_STREAMS + wxVariantData* Clone() const { return new wxVariantDataLong(m_value); } + virtual wxString GetType() const { return wxT("long"); } protected: @@ -377,6 +402,7 @@ public: #endif // wxUSE_STREAMS virtual wxString GetType() const { return wxT("double"); } + wxVariantData* Clone() const { return new wxVariantDoubleData(m_value); } protected: double m_value; }; @@ -514,6 +540,7 @@ public: #endif // wxUSE_STREAMS virtual wxString GetType() const { return wxT("bool"); } + wxVariantData* Clone() const { return new wxVariantDataBool(m_value); } protected: bool m_value; }; @@ -651,6 +678,7 @@ public: virtual bool Write(wxOutputStream& str) const; #endif // wxUSE_STREAMS virtual wxString GetType() const { return wxT("char"); } + wxVariantData* Clone() const { return new wxVariantDataChar(m_value); } protected: wxUniChar m_value; @@ -802,6 +830,7 @@ public: virtual bool Write(wxOutputStream& str) const; #endif // wxUSE_STREAMS virtual wxString GetType() const { return wxT("string"); } + wxVariantData* Clone() const { return new wxVariantDataString(m_value); } protected: wxString m_value; @@ -955,10 +984,10 @@ public: #endif virtual bool Read(wxString& str); virtual wxString GetType() const ; - virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; } + virtual wxVariantData* Clone() const { return new wxVariantDataWxObjectPtr(m_value); } virtual wxClassInfo* GetValueClassInfo(); - + protected: wxObject* m_value; }; @@ -975,13 +1004,13 @@ bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const wxString wxVariantDataWxObjectPtr::GetType() const { wxString returnVal(wxT("wxObject*")); - + if (m_value) { returnVal = m_value->GetClassInfo()->GetClassName(); returnVal += wxT("*"); } - + return returnVal; } @@ -1076,7 +1105,7 @@ public: #endif virtual bool Read(wxString& str); virtual wxString GetType() const { return wxT("void*"); } - virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; } + virtual wxVariantData* Clone() const { return new wxVariantDataVoidPtr(m_value); } protected: void* m_value; @@ -1193,7 +1222,7 @@ public: #endif virtual bool Read(wxString& str); virtual wxString GetType() const { return wxT("datetime"); } - virtual wxVariantData* Clone() { return new wxVariantDataDateTime; } + virtual wxVariantData* Clone() const { return new wxVariantDataDateTime(m_value); } protected: wxDateTime m_value; @@ -1357,7 +1386,7 @@ public: #endif virtual bool Read(wxString& str); virtual wxString GetType() const { return wxT("arrstring"); } - virtual wxVariantData* Clone() { return new wxVariantDataArrayString; } + virtual wxVariantData* Clone() const { return new wxVariantDataArrayString(m_value); } protected: wxArrayString m_value; @@ -1484,6 +1513,7 @@ public: void Clear(); + wxVariantData* Clone() const { return new wxVariantDataList(m_value); } protected: wxVariantList m_value; };