]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/buffer.h
added template wxScopedArray<> too
[wxWidgets.git] / include / wx / buffer.h
index 1144aa420d0392c9a9d7121ee75a7c8110df69b9..4cc340aa518fa7248e26b58781b93958a3596c5a 100644 (file)
@@ -26,8 +26,46 @@ class WXDLLIMPEXP_FWD_BASE wxCStrData;
 // of new/delete
 // ----------------------------------------------------------------------------
 
+// helpers used by wxCharTypeBuffer
+namespace wxPrivate
+{
+
+struct UntypedBufferData
+{
+    enum Kind
+    {
+        Owned,
+        NonOwned
+    };
+
+    UntypedBufferData(void *str, Kind kind = Owned)
+        : m_str(str), m_ref(1), m_owned(kind == Owned) {}
+
+    ~UntypedBufferData()
+    {
+        if ( m_owned )
+            free(m_str);
+    }
+
+    void *m_str;
+
+    // "short" to have sizeof(Data)=8 on 32bit archs
+    unsigned short m_ref;
+
+    bool m_owned;
+};
+
+// this has to be defined inside the DLL (and not e.g. as a static variable
+// inside an inline function) as otherwise MSVC gives link errors when the
+// functions are effectively inlined (i.e. in non-debug build)
+//
+// NB: this is defined in string.cpp and not the (non-existent) buffer.cpp
+extern WXDLLIMPEXP_DATA_BASE(UntypedBufferData * const) untypedNullDataPtr;
+
+} // namespace wxPrivate
+
 template <typename T>
-class WXDLLIMPEXP_BASE wxCharTypeBuffer
+class wxCharTypeBuffer
 {
 public:
     typedef T CharType;
@@ -37,20 +75,20 @@ public:
         if ( str )
             m_data = new Data(wxStrdup(str));
         else
-            m_data = &NullData;
+            m_data = GetNullData();
     }
 
     wxCharTypeBuffer(size_t len)
     {
         m_data = new Data((CharType *)malloc((len + 1)*sizeof(CharType)));
-        m_data->m_str[len] = (CharType)0;
+        m_data->Get()[len] = (CharType)0;
     }
 
     static const wxCharTypeBuffer CreateNonOwned(const CharType *str)
     {
         wxCharTypeBuffer buf;
         if ( str )
-            buf.m_data = new Data(wx_const_cast(CharType*, str), Data::NonOwned);
+            buf.m_data = new Data(const_cast<CharType*>(str), Data::NonOwned);
         return buf;
     }
 
@@ -59,17 +97,23 @@ public:
         DecRef();
     }
 
-    CharType *release()
+    // NB: this method is only const for backward compatibility. It used to
+    //     be needed for auto_ptr-like semantics of the copy ctor, but now
+    //     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") );
         wxASSERT_MSG( m_data->m_ref == 1, _T("can't release shared buffer") );
 
-        CharType *p = m_data->m_str;
-        m_data->m_str = NULL;
-        DecRef();
+        CharType * const p = m_data->Get();
+
+        wxCharTypeBuffer *self = const_cast<wxCharTypeBuffer*>(this);
+        self->m_data->Set(NULL);
+        self->DecRef();
+
         return p;
     }
 
@@ -115,69 +159,57 @@ public:
         if ( !str )
             return false;
 
-        if ( m_data == &NullData )
+        if ( m_data == GetNullData() )
         {
             m_data = new Data(str);
         }
         else
         {
-            m_data->m_str = str;
+            m_data->Set(str);
             m_data->m_owned = true;
         }
 
         return true;
     }
 
-    CharType *data() { return m_data->m_str; }
-    const CharType *data() const { return  m_data->m_str; }
+    CharType *data() { return m_data->Get(); }
+    const CharType *data() const { return  m_data->Get(); }
     operator const CharType *() const { return data(); }
     CharType operator[](size_t n) const { return data()[n]; }
 
 private:
     // reference-counted data
-    struct Data
+    struct Data : public wxPrivate::UntypedBufferData
     {
-        enum Kind
-        {
-            Owned,
-            NonOwned
-        };
-
         Data(CharType *str, Kind kind = Owned)
-            : m_str(str), m_ref(1), m_owned(kind == Owned) {}
-
-        ~Data()
+            : wxPrivate::UntypedBufferData(str, kind)
         {
-            if ( m_owned )
-                free(m_str);
         }
 
-        CharType *m_str;
-
-        // "short" to have sizeof(Data)=8 on 32bit archs
-        unsigned short m_ref;
-
-        bool m_owned;
+        CharType *Get() const { return static_cast<CharType *>(m_str); }
+        void Set(CharType *str) { m_str = str; }
     };
 
     // placeholder for NULL string, to simplify this code
-    // NB: this is defined in string.cpp, not (non-existent) buffer.cpp
-    static Data NullData;
+    static Data *GetNullData()
+    {
+        return static_cast<Data *>(wxPrivate::untypedNullDataPtr);
+    }
 
     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:
@@ -186,7 +218,7 @@ private:
 
 WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<char> )
 
-class WXDLLIMPEXP_BASE wxCharBuffer : public wxCharTypeBuffer<char>
+class wxCharBuffer : public wxCharTypeBuffer<char>
 {
 public:
     typedef wxCharTypeBuffer<char> wxCharTypeBufferBase;
@@ -203,7 +235,7 @@ public:
 #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;
@@ -329,7 +361,7 @@ private:
 };
 
 
-class WXDLLIMPEXP_BASE wxMemoryBuffer
+class wxMemoryBuffer
 {
 public:
     // ctor and dtor