// ----------------------------------------------------------------------------
template <typename T>
-class WXDLLIMPEXP_BASE wxCharTypeBuffer
+class wxCharTypeBuffer
{
public:
typedef T CharType;
if ( str )
m_data = new Data(wxStrdup(str));
else
- m_data = &NullData;
+ m_data = GetNullData();
}
wxCharTypeBuffer(size_t len)
// that ref-counting is used, it's not really needed.
CharType *release() const
{
- if ( m_data == &NullData )
+ if ( m_data == GetNullData() )
return NULL;
wxASSERT_MSG( m_data->m_owned, _T("can't release non-owned buffer") );
if ( !str )
return false;
- if ( m_data == &NullData )
+ if ( m_data == GetNullData() )
{
m_data = new Data(str);
}
};
// placeholder for NULL string, to simplify this code
- // NB: this is defined in string.cpp, not (non-existent) buffer.cpp
-#ifdef __MINGW32__
- // MinGW requires explicit WXDLLIMPEXP_DATA_BASE to avoid compilation
- // errors
- static WXDLLIMPEXP_DATA_BASE(Data) NullData;
-#else
- // but Visual C++ doesn't like it
- static Data NullData;
-#endif
+ static Data *GetNullData()
+ {
+ static Data s_nullData(NULL);
+
+ return &s_nullData;
+ }
void IncRef()
{
- if ( m_data == &NullData ) // exception, not ref-counted
+ if ( m_data == GetNullData() ) // exception, not ref-counted
return;
m_data->m_ref++;
}
void DecRef()
{
- if ( m_data == &NullData ) // exception, not ref-counted
+ if ( m_data == GetNullData() ) // exception, not ref-counted
return;
if ( --m_data->m_ref == 0 )
delete m_data;
- m_data = &NullData;
+ m_data = GetNullData();
}
private:
WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<char> )
-class WXDLLIMPEXP_BASE wxCharBuffer : public wxCharTypeBuffer<char>
+class wxCharBuffer : public wxCharTypeBuffer<char>
{
public:
typedef wxCharTypeBuffer<char> wxCharTypeBufferBase;
#if wxUSE_WCHAR_T
WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<wchar_t> )
-class WXDLLIMPEXP_BASE wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
+class wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
{
public:
typedef wxCharTypeBuffer<wchar_t> wxCharTypeBufferBase;
};
-class WXDLLIMPEXP_BASE wxMemoryBuffer
+class wxMemoryBuffer
{
public:
// ctor and dtor
#endif // !wxUSE_STL_BASED_WXSTRING
template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferBase
+class wxStringTypeBufferBase
{
public:
typedef T CharType;
};
template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferLengthBase
- : public wxStringTypeBufferBase<T>
+class wxStringTypeBufferLengthBase : public wxStringTypeBufferBase<T>
{
public:
wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferBase<char> )
-class WXDLLIMPEXP_BASE wxUTF8StringBuffer : public wxStringTypeBufferBase<char>
+// Note about inlined dtors in the classes below: this is done not for
+// performance reasons but just to avoid linking errors in the MSVC DLL build
+// under Windows: if a class has non-inline methods it must be declared as
+// being DLL-exported but, due to an extremely interesting feature of MSVC 7
+// and later, any template class which is used as a base of a DLL-exported
+// class is implicitly made DLL-exported too, as explained at the bottom of
+// http://msdn.microsoft.com/en-us/library/twa2aw10.aspx (just to confirm: yes,
+// _inheriting_ from a class can change whether it is being exported from DLL)
+//
+// But this results in link errors because the base template class is not DLL-
+// exported, whether it is declared with WXDLLIMPEXP_BASE or not, because it
+// does have only inline functions. So the simplest fix is to just make all the
+// functions of these classes inline too.
+
+class wxUTF8StringBuffer : public wxStringTypeBufferBase<char>
{
public:
wxUTF8StringBuffer(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferBase<char>(str, lenWanted) {}
- ~wxUTF8StringBuffer();
+ ~wxUTF8StringBuffer()
+ {
+ wxMBConvStrictUTF8 conv;
+ size_t wlen = conv.ToWChar(NULL, 0, m_buf);
+ wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
+
+ wxStringInternalBuffer wbuf(m_str, wlen);
+ conv.ToWChar(wbuf, wlen, m_buf);
+ }
DECLARE_NO_COPY_CLASS(wxUTF8StringBuffer)
};
WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferLengthBase<char> )
-class WXDLLIMPEXP_BASE wxUTF8StringBufferLength
- : public wxStringTypeBufferLengthBase<char>
+class wxUTF8StringBufferLength : public wxStringTypeBufferLengthBase<char>
{
public:
wxUTF8StringBufferLength(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferLengthBase<char>(str, lenWanted) {}
- ~wxUTF8StringBufferLength();
+ ~wxUTF8StringBufferLength()
+ {
+ wxCHECK_RET(m_lenSet, "length not set");
+
+ wxMBConvStrictUTF8 conv;
+ size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len);
+ wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
+
+ wxStringInternalBufferLength wbuf(m_str, wlen);
+ conv.ToWChar(wbuf, wlen, m_buf, m_len);
+ wbuf.SetLength(wlen);
+ }
DECLARE_NO_COPY_CLASS(wxUTF8StringBufferLength)
};
}
return count;
}
-
-// ----------------------------------------------------------------------------
-// wxUTF8StringBuffer
-// ----------------------------------------------------------------------------
-
-#if wxUSE_UNICODE_WCHAR
-wxUTF8StringBuffer::~wxUTF8StringBuffer()
-{
- wxMBConvStrictUTF8 conv;
- size_t wlen = conv.ToWChar(NULL, 0, m_buf);
- wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
-
- wxStringInternalBuffer wbuf(m_str, wlen);
- conv.ToWChar(wbuf, wlen, m_buf);
-}
-
-wxUTF8StringBufferLength::~wxUTF8StringBufferLength()
-{
- wxCHECK_RET(m_lenSet, "length not set");
-
- wxMBConvStrictUTF8 conv;
- size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len);
- wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
-
- wxStringInternalBufferLength wbuf(m_str, wlen);
- conv.ToWChar(wbuf, wlen, m_buf, m_len);
- wbuf.SetLength(wlen);
-}
-#endif // wxUSE_UNICODE_WCHAR
-
-// ----------------------------------------------------------------------------
-// wxCharBufferType<T>
-// ----------------------------------------------------------------------------
-
-#ifndef __VMS_BROKEN_TEMPLATES
-template<>
-#endif
-wxCharTypeBuffer<char>::Data
-wxCharTypeBuffer<char>::NullData(NULL);
-
-#ifndef __VMS_BROKEN_TEMPLATES
-template<>
-#endif
-wxCharTypeBuffer<wchar_t>::Data
-wxCharTypeBuffer<wchar_t>::NullData(NULL);
return result;
}
-
-
-#if SIZEOF_WCHAR_T != 2
-template<>
-wxCharTypeBuffer<wxChar16>::Data
-wxCharTypeBuffer<wxChar16>::NullData(NULL);
-#endif
-
-#if SIZEOF_WCHAR_T != 4
-template<>
-wxCharTypeBuffer<wxChar32>::Data
-wxCharTypeBuffer<wxChar32>::NullData(NULL);
-#endif