]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/string.h
another wxUSE_DRAG_AND_DROP==0 compilation fix
[wxWidgets.git] / include / wx / string.h
index 43dfbcb175a75bf17afccb348fe6e057ed6f0bf6..22e0ec6f5ed19560e82abd04b1a09edd7c0c6e65 100644 (file)
@@ -69,7 +69,9 @@
 // use in DLL build under pre-Vista Windows so we disable this code for now, if
 // anybody really needs to use UTF-8 build under Windows with this optimization
 // it would have to be re-tested and probably corrected
-#if wxUSE_UNICODE_UTF8 && !defined(__WXMSW__)
+// CS: under OSX release builds the string destructor/cache cleanup sometimes
+// crashes, disable until we find the true reason or a better workaround
+#if wxUSE_UNICODE_UTF8 && !defined(__WXMSW__) && !defined(__WXOSX__)
     #define wxUSE_STRING_POS_CACHE 1
 #else
     #define wxUSE_STRING_POS_CACHE 0
@@ -613,7 +615,7 @@ private:
 
       return wxTLS_VALUE(s_cache);
   }
-  
+
   // this helper struct is used to ensure that GetCache() is called during
   // static initialization time, i.e. before any threads creation, as otherwise
   // the static s_cache construction inside GetCache() wouldn't be MT-safe
@@ -673,7 +675,7 @@ private:
       // a lot of misses in this function...)
       Cache::Element * const cacheBegin = GetCacheBegin();
 #ifndef wxHAS_COMPILER_TLS
-      // during destruction tls calls may return NULL, in this case return NULL 
+      // during destruction tls calls may return NULL, in this case return NULL
       // immediately without accessing anything else
       if ( cacheBegin == NULL )
         return NULL;
@@ -987,7 +989,7 @@ public:
       iterator(wxString *str, underlying_iterator ptr)
           : m_cur(ptr), m_node(str, &m_cur) {}
 
-      wxString* str() const { return wx_const_cast(wxString*, m_node.m_str); }
+      wxString* str() const { return const_cast<wxString*>(m_node.m_str); }
 
       wxStringIteratorNode m_node;
 
@@ -1808,7 +1810,7 @@ public:
     const wchar_t* t_str() const { return wx_str(); }
 #else
     const char* t_str() const { return wx_str(); }
-#endif 
+#endif
 
 
   // overloaded assignment
@@ -3605,7 +3607,7 @@ private:
 #endif // !wxUSE_STL_BASED_WXSTRING
 
 template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferBase
+class wxStringTypeBufferBase
 {
 public:
     typedef T CharType;
@@ -3645,8 +3647,7 @@ protected:
 };
 
 template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferLengthBase
-    : public wxStringTypeBufferBase<T>
+class wxStringTypeBufferLengthBase : public wxStringTypeBufferBase<T>
 {
 public:
     wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
@@ -3750,25 +3751,57 @@ typedef wxStringInternalBufferLength          wxUTF8StringBufferLength;
 
 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)
 };
@@ -3924,7 +3957,7 @@ inline wxCStrData::wxCStrData(const wxCStrData& data)
 inline wxCStrData::~wxCStrData()
 {
     if ( m_owned )
-        delete wx_const_cast(wxString*, m_str); // cast to silence warnings
+        delete const_cast<wxString*>(m_str); // cast to silence warnings
 }
 
 // simple cases for AsChar() and AsWChar(), the complicated ones are
@@ -4047,7 +4080,7 @@ void wxStringIteratorNode::DoSet(const wxString *str,
     if ( str )
     {
         m_next = str->m_iterators.ptr;
-        wx_const_cast(wxString*, m_str)->m_iterators.ptr = this;
+        const_cast<wxString*>(m_str)->m_iterators.ptr = this;
         if ( m_next )
             m_next->m_prev = this;
     }
@@ -4064,7 +4097,7 @@ void wxStringIteratorNode::clear()
     if ( m_prev )
         m_prev->m_next = m_next;
     else if ( m_str ) // first in the list
-        wx_const_cast(wxString*, m_str)->m_iterators.ptr = m_next;
+        const_cast<wxString*>(m_str)->m_iterators.ptr = m_next;
 
     m_next = m_prev = NULL;
     m_citer = NULL;
@@ -4081,4 +4114,19 @@ void wxStringIteratorNode::clear()
     #include "wx/crt.h"
 #endif
 
+// ----------------------------------------------------------------------------
+// Checks on wxString characters
+// ----------------------------------------------------------------------------
+
+template<bool (T)(const wxUniChar& c)>
+    inline bool wxStringCheck(const wxString& val)
+    {
+        for ( wxString::const_iterator i = val.begin();
+              i != val.end();
+              ++i )
+            if (T(*i) == 0)
+                return false;
+        return true;
+    }
+
 #endif  // _WX_WXSTRING_H_