renamed wx/ptr_shrd.h to wx/sharedptr.h; split wx/ptr_scpd.h in wx/scopedptr.h and wx/scopedarray.h; extracted common parts into new wx/checkeddelete.h

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58634 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-02-03 12:01:46 +00:00
parent 6143d648c8
commit 664e13143e
40 changed files with 504 additions and 382 deletions

View File

@@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/checkeddelete.h
// Purpose: wxCHECKED_DELETE() macro
// Author: Vadim Zeitlin
// Created: 2009-02-03
// RCS-ID: $Id$
// Copyright: (c) 2002-2009 wxWidgets dev team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_CHECKEDDELETE_H_
#define _WX_CHECKEDDELETE_H_
// TODO: provide wxCheckedDelete[Array]() template functions too
// ----------------------------------------------------------------------------
// wxCHECKED_DELETE and wxCHECKED_DELETE_ARRAY macros
// ----------------------------------------------------------------------------
/*
checked deleters are used to make sure that the type being deleted is really
a complete type.: otherwise sizeof() would result in a compile-time error
do { ... } while ( 0 ) construct is used to have an anonymous scope
(otherwise we could have name clashes between different "complete"s) but
still force a semicolon after the macro
*/
#ifdef __WATCOMC__
#define wxFOR_ONCE(name) for(int name=0; name<1; name++)
#define wxPRE_NO_WARNING_SCOPE(name) wxFOR_ONCE(wxMAKE_UNIQUE_NAME(name))
#define wxPOST_NO_WARNING_SCOPE(name)
#else
#define wxPRE_NO_WARNING_SCOPE(name) do
#define wxPOST_NO_WARNING_SCOPE(name) while ( wxFalse )
#endif
#define wxCHECKED_DELETE(ptr) \
wxPRE_NO_WARNING_SCOPE(scope_var1) \
{ \
typedef char complete[sizeof(*ptr)]; \
delete ptr; \
} wxPOST_NO_WARNING_SCOPE(scope_var1)
#define wxCHECKED_DELETE_ARRAY(ptr) \
wxPRE_NO_WARNING_SCOPE(scope_var2) \
{ \
typedef char complete[sizeof(*ptr)]; \
delete [] ptr; \
} wxPOST_NO_WARNING_SCOPE(scope_var2)
#endif // _WX_CHECKEDDELETE_H_

View File

@@ -791,7 +791,6 @@ public:
// For drag operations
void SetDataObject( wxDataObject *obj ) { m_dataObject = obj; }
wxDataObject *GetDataObject() const { return m_dataObject; }
#endif // wxUSE_DRAG_AND_DROP
// For drop operations
void SetDataFormat( const wxDataFormat &format ) { m_dataFormat = format; }
@@ -800,6 +799,7 @@ public:
size_t GetDataSize() const { return m_dataSize; }
void SetDataBuffer( void* buf ) { m_dataBuffer = buf;}
void *GetDataBuffer() const { return m_dataBuffer; }
#endif // wxUSE_DRAG_AND_DROP
virtual wxEvent *Clone() const { return new wxDataViewEvent(*this); }

120
include/wx/scopedarray.h Normal file
View File

@@ -0,0 +1,120 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/scopedarray.h
// Purpose: scoped smart pointer class
// Author: Vadim Zeitlin
// Created: 2009-02-03
// RCS-ID: $Id$
// Copyright: (c) Jesse Lovelace and original Boost authors (see below)
// (c) 2009 Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_SCOPED_ARRAY_H_
#define _WX_SCOPED_ARRAY_H_
#include "wx/defs.h"
#include "wx/checkeddelete.h"
// ----------------------------------------------------------------------------
// wxScopedArray: A scoped array
// ----------------------------------------------------------------------------
template <class T>
class wxScopedArray
{
public:
typedef T element_type;
wxEXPLICIT wxScopedArray(T * array = NULL) : m_array(array) { }
~wxScopedArray() { delete [] m_array; }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxScopedArray<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
return m_array ? &wxScopedArray<T>::get : NULL;
}
void reset(T *array = NULL)
{
if ( array != m_array )
{
delete m_array;
m_array = array;
}
}
T& operator[](size_t n) const { return m_array[n]; }
T *get() const { return m_array; }
void swap(wxScopedArray &other)
{
T * const tmp = other.m_array;
other.m_array = m_array;
m_array = tmp;
}
private:
T *m_array;
DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedArray, T)
};
// ----------------------------------------------------------------------------
// old macro based implementation
// ----------------------------------------------------------------------------
// the same but for arrays instead of simple pointers
#define wxDECLARE_SCOPED_ARRAY(T, name)\
class name \
{ \
private: \
T * m_ptr; \
name(name const &); \
name & operator=(name const &); \
\
public: \
wxEXPLICIT name(T * p = NULL) : m_ptr(p) \
{} \
\
~name(); \
void reset(T * p = NULL); \
\
T & operator[](long int i) const\
{ \
wxASSERT(m_ptr != NULL); \
wxASSERT(i >= 0); \
return m_ptr[i]; \
} \
\
T * get() const \
{ \
return m_ptr; \
} \
\
void swap(name & ot) \
{ \
T * tmp = ot.m_ptr; \
ot.m_ptr = m_ptr; \
m_ptr = tmp; \
} \
};
#define wxDEFINE_SCOPED_ARRAY(T, name) \
name::~name() \
{ \
wxCHECKED_DELETE_ARRAY(m_ptr); \
} \
void name::reset(T * p){ \
if (m_ptr != p) \
{ \
wxCHECKED_DELETE_ARRAY(m_ptr); \
m_ptr = p; \
} \
}
#endif // _WX_SCOPED_ARRAY_H_

View File

@@ -1,8 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/ptr_scpd.h
// Name: wx/scopedptr.h
// Purpose: scoped smart pointer class
// Author: Jesse Lovelace <jllovela@eos.ncsu.edu>
// Modified by: Vadim Zeitlin to add template wxScopedArray
// Created: 06/01/02
// RCS-ID: $Id$
// Copyright: (c) Jesse Lovelace and original Boost authors (see below)
@@ -26,10 +25,11 @@
// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
//
#ifndef __WX_SCOPED_POINTER__
#define __WX_SCOPED_POINTER__
#ifndef _WX_SCOPED_PTR_H_
#define _WX_SCOPED_PTR_H_
#include "wx/defs.h"
#include "wx/checkeddelete.h"
// ----------------------------------------------------------------------------
// wxScopedPtr: A scoped pointer
@@ -99,90 +99,10 @@ private:
DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedPtr, T)
};
// ----------------------------------------------------------------------------
// wxScopedArray: A scoped array
// ----------------------------------------------------------------------------
template <class T>
class wxScopedArray
{
public:
typedef T element_type;
wxEXPLICIT wxScopedArray(T * array = NULL) : m_array(array) { }
~wxScopedArray() { delete [] m_array; }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxScopedArray<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
return m_array ? &wxScopedArray<T>::get : NULL;
}
void reset(T *array = NULL)
{
if ( array != m_array )
{
delete m_array;
m_array = array;
}
}
T& operator[](size_t n) const { return m_array[n]; }
T *get() const { return m_array; }
void swap(wxScopedArray &other)
{
T * const tmp = other.m_array;
other.m_array = m_array;
m_array = tmp;
}
private:
T *m_array;
DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedArray, T)
};
// ----------------------------------------------------------------------------
// old macro based implementation
// ----------------------------------------------------------------------------
/*
checked deleters are used to make sure that the type being deleted is really
a complete type.: otherwise sizeof() would result in a compile-time error
do { ... } while ( 0 ) construct is used to have an anonymous scope
(otherwise we could have name clashes between different "complete"s) but
still force a semicolon after the macro
*/
#ifdef __WATCOMC__
#define wxFOR_ONCE(name) for(int name=0; name<1; name++)
#define wxPRE_NO_WARNING_SCOPE(name) wxFOR_ONCE(wxMAKE_UNIQUE_NAME(name))
#define wxPOST_NO_WARNING_SCOPE(name)
#else
#define wxPRE_NO_WARNING_SCOPE(name) do
#define wxPOST_NO_WARNING_SCOPE(name) while ( wxFalse )
#endif
#define wxCHECKED_DELETE(ptr) \
wxPRE_NO_WARNING_SCOPE(scope_var1) \
{ \
typedef char complete[sizeof(*ptr)]; \
delete ptr; \
} wxPOST_NO_WARNING_SCOPE(scope_var1)
#define wxCHECKED_DELETE_ARRAY(ptr) \
wxPRE_NO_WARNING_SCOPE(scope_var2) \
{ \
typedef char complete[sizeof(*ptr)]; \
delete [] ptr; \
} wxPOST_NO_WARNING_SCOPE(scope_var2)
/* The type being used *must* be complete at the time
that wxDEFINE_SCOPED_* is called or a compiler error will result.
This is because the class checks for the completeness of the type
@@ -257,55 +177,6 @@ name::~name() \
wxDECLARE_SCOPED_PTR(T, T ## Ptr) \
wxDEFINE_SCOPED_PTR(T, T ## Ptr)
// the same but for arrays instead of simple pointers
#define wxDECLARE_SCOPED_ARRAY(T, name)\
class name \
{ \
private: \
T * m_ptr; \
name(name const &); \
name & operator=(name const &); \
\
public: \
wxEXPLICIT name(T * p = NULL) : m_ptr(p) \
{} \
\
~name(); \
void reset(T * p = NULL); \
\
T & operator[](long int i) const\
{ \
wxASSERT(m_ptr != NULL); \
wxASSERT(i >= 0); \
return m_ptr[i]; \
} \
\
T * get() const \
{ \
return m_ptr; \
} \
\
void swap(name & ot) \
{ \
T * tmp = ot.m_ptr; \
ot.m_ptr = m_ptr; \
m_ptr = tmp; \
} \
};
#define wxDEFINE_SCOPED_ARRAY(T, name) \
name::~name() \
{ \
wxCHECKED_DELETE_ARRAY(m_ptr); \
} \
void name::reset(T * p){ \
if (m_ptr != p) \
{ \
wxCHECKED_DELETE_ARRAY(m_ptr); \
m_ptr = p; \
} \
}
// ----------------------------------------------------------------------------
// "Tied" scoped pointer: same as normal one but also sets the value of
// some other variable to the pointer value
@@ -333,5 +204,5 @@ void name::reset(T * p){ \
T *m_pOld; \
};
#endif // __WX_SCOPED_POINTER__
#endif // _WX_SCOPED_PTR_H_

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/ptr_shrd.h
// Name: wx/sharedptr.h
// Purpose: Shared pointer based on the counted_ptr<> template, which
// is in the public domain
// Author: Robert Roebling, Yonat Sharon
@@ -8,8 +8,8 @@
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_SHARED_PTRH__
#define _WX_SHARED_PTRH__
#ifndef _WX_SHAREDPTR_H_
#define _WX_SHAREDPTR_H_
#include "wx/defs.h"
#include "wx/atomic.h"
@@ -18,25 +18,25 @@
// wxSharedPtr: A smart pointer with non-intrusive reference counting.
// ----------------------------------------------------------------------------
template <class T>
template <class T>
class wxSharedPtr
{
public:
typedef T element_type;
wxEXPLICIT wxSharedPtr( T* ptr = NULL )
: m_ref(NULL)
{
if (ptr)
m_ref = new reftype(ptr);
: m_ref(NULL)
{
if (ptr)
m_ref = new reftype(ptr);
}
~wxSharedPtr() { Release(); }
wxSharedPtr(const wxSharedPtr& tocopy) { Acquire(tocopy.m_ref); }
wxSharedPtr& operator=( const wxSharedPtr& tocopy )
{
if (this != &tocopy)
if (this != &tocopy)
{
Release();
Acquire(tocopy.m_ref);
@@ -46,11 +46,11 @@ public:
wxSharedPtr& operator=( T* ptr )
{
if (get() != ptr)
if (get() != ptr)
{
Release();
if (ptr)
m_ref = new reftype(ptr);
if (ptr)
m_ref = new reftype(ptr);
}
return *this;
}
@@ -67,56 +67,56 @@ public:
}
T& operator*() const
{
wxASSERT(m_ref != NULL);
wxASSERT(m_ref->m_ptr != NULL);
{
wxASSERT(m_ref != NULL);
wxASSERT(m_ref->m_ptr != NULL);
return *(m_ref->m_ptr);
}
T* operator->() const
{
wxASSERT(m_ref != NULL);
wxASSERT(m_ref->m_ptr != NULL);
{
wxASSERT(m_ref != NULL);
wxASSERT(m_ref->m_ptr != NULL);
return m_ref->m_ptr;
}
T* get() const
{
return m_ref ? m_ref->m_ptr : NULL;
T* get() const
{
return m_ref ? m_ref->m_ptr : NULL;
}
void reset( T* ptr = NULL )
{
Release();
if (ptr)
m_ref = new reftype(ptr);
if (ptr)
m_ref = new reftype(ptr);
}
bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); }
long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); }
private:
struct reftype
struct reftype
{
reftype( T* ptr = NULL, unsigned count = 1 ) : m_ptr(ptr), m_count(count) {}
T* m_ptr;
wxAtomicInt m_count;
}* m_ref;
void Acquire(reftype* ref)
void Acquire(reftype* ref)
{
m_ref = ref;
if (ref)
if (ref)
wxAtomicInc( ref->m_count );
}
void Release()
{
if (m_ref)
if (m_ref)
{
wxAtomicDec( m_ref->m_count );
if (m_ref->m_count == 0)
if (m_ref->m_count == 0)
{
delete m_ref->m_ptr;
delete m_ref;
@@ -138,6 +138,4 @@ bool operator != (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
return a.get() != b.get();
}
#endif // _WX_SHARED_PTRH__
#endif // _WX_SHAREDPTR_H_