]> git.saurik.com Git - wxWidgets.git/blob - include/wx/scopedptr.h
Dramatically optimise inserting many items in wxGenericListCtrl.
[wxWidgets.git] / include / wx / scopedptr.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/scopedptr.h
3 // Purpose: scoped smart pointer class
4 // Author: Jesse Lovelace <jllovela@eos.ncsu.edu>
5 // Created: 06/01/02
6 // RCS-ID: $Id$
7 // Copyright: (c) Jesse Lovelace and original Boost authors (see below)
8 // (c) 2009 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // This class closely follows the implementation of the boost
13 // library scoped_ptr and is an adaption for c++ macro's in
14 // the wxWidgets project. The original authors of the boost
15 // scoped_ptr are given below with their respective copyrights.
16
17 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
18 // Copyright (c) 2001, 2002 Peter Dimov
19 //
20 // Permission to copy, use, modify, sell and distribute this software
21 // is granted provided this copyright notice appears in all copies.
22 // This software is provided "as is" without express or implied
23 // warranty, and with no claim as to its suitability for any purpose.
24 //
25 // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
26 //
27
28 #ifndef _WX_SCOPED_PTR_H_
29 #define _WX_SCOPED_PTR_H_
30
31 #include "wx/defs.h"
32 #include "wx/checkeddelete.h"
33
34 // ----------------------------------------------------------------------------
35 // wxScopedPtr: A scoped pointer
36 // ----------------------------------------------------------------------------
37
38 template <class T>
39 class wxScopedPtr
40 {
41 public:
42 typedef T element_type;
43
44 wxEXPLICIT wxScopedPtr(T * ptr = NULL) : m_ptr(ptr) { }
45
46 ~wxScopedPtr() { wxCHECKED_DELETE(m_ptr); }
47
48 // test for pointer validity: defining conversion to unspecified_bool_type
49 // and not more obvious bool to avoid implicit conversions to integer types
50 #ifdef __BORLANDC__
51 // this compiler is too dumb to use unspecified_bool_type operator in tests
52 // of the form "if ( !ptr )"
53 typedef bool unspecified_bool_type;
54 #else
55 typedef T *(wxScopedPtr<T>::*unspecified_bool_type)() const;
56 #endif // __BORLANDC__
57 operator unspecified_bool_type() const
58 {
59 return m_ptr ? &wxScopedPtr<T>::get : NULL;
60 }
61
62 void reset(T * ptr = NULL)
63 {
64 if ( ptr != m_ptr )
65 {
66 wxCHECKED_DELETE(m_ptr);
67 m_ptr = ptr;
68 }
69 }
70
71 T *release()
72 {
73 T *ptr = m_ptr;
74 m_ptr = NULL;
75 return ptr;
76 }
77
78 T & operator*() const
79 {
80 wxASSERT(m_ptr != NULL);
81 return *m_ptr;
82 }
83
84 T * operator->() const
85 {
86 wxASSERT(m_ptr != NULL);
87 return m_ptr;
88 }
89
90 T * get() const
91 {
92 return m_ptr;
93 }
94
95 void swap(wxScopedPtr& other)
96 {
97 T * const tmp = other.m_ptr;
98 other.m_ptr = m_ptr;
99 m_ptr = tmp;
100 }
101
102 private:
103 T * m_ptr;
104
105 DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedPtr, T)
106 };
107
108 // ----------------------------------------------------------------------------
109 // old macro based implementation
110 // ----------------------------------------------------------------------------
111
112 /* The type being used *must* be complete at the time
113 that wxDEFINE_SCOPED_* is called or a compiler error will result.
114 This is because the class checks for the completeness of the type
115 being used. */
116
117 #define wxDECLARE_SCOPED_PTR(T, name) \
118 class name \
119 { \
120 private: \
121 T * m_ptr; \
122 \
123 name(name const &); \
124 name & operator=(name const &); \
125 \
126 public: \
127 wxEXPLICIT name(T * ptr = NULL) \
128 : m_ptr(ptr) { } \
129 \
130 ~name(); \
131 \
132 void reset(T * ptr = NULL); \
133 \
134 T *release() \
135 { \
136 T *ptr = m_ptr; \
137 m_ptr = NULL; \
138 return ptr; \
139 } \
140 \
141 T & operator*() const \
142 { \
143 wxASSERT(m_ptr != NULL); \
144 return *m_ptr; \
145 } \
146 \
147 T * operator->() const \
148 { \
149 wxASSERT(m_ptr != NULL); \
150 return m_ptr; \
151 } \
152 \
153 T * get() const \
154 { \
155 return m_ptr; \
156 } \
157 \
158 void swap(name & ot) \
159 { \
160 T * tmp = ot.m_ptr; \
161 ot.m_ptr = m_ptr; \
162 m_ptr = tmp; \
163 } \
164 };
165
166 #define wxDEFINE_SCOPED_PTR(T, name)\
167 void name::reset(T * ptr) \
168 { \
169 if (m_ptr != ptr) \
170 { \
171 wxCHECKED_DELETE(m_ptr); \
172 m_ptr = ptr; \
173 } \
174 } \
175 name::~name() \
176 { \
177 wxCHECKED_DELETE(m_ptr); \
178 }
179
180 // this macro can be used for the most common case when you want to declare and
181 // define the scoped pointer at the same time and want to use the standard
182 // naming convention: auto pointer to Foo is called FooPtr
183 #define wxDEFINE_SCOPED_PTR_TYPE(T) \
184 wxDECLARE_SCOPED_PTR(T, T ## Ptr) \
185 wxDEFINE_SCOPED_PTR(T, T ## Ptr)
186
187 // ----------------------------------------------------------------------------
188 // "Tied" scoped pointer: same as normal one but also sets the value of
189 // some other variable to the pointer value
190 // ----------------------------------------------------------------------------
191
192 #define wxDEFINE_TIED_SCOPED_PTR_TYPE(T) \
193 wxDEFINE_SCOPED_PTR_TYPE(T) \
194 class T ## TiedPtr : public T ## Ptr \
195 { \
196 public: \
197 T ## TiedPtr(T **pp, T *p) \
198 : T ## Ptr(p), m_pp(pp) \
199 { \
200 m_pOld = *pp; \
201 *pp = p; \
202 } \
203 \
204 ~ T ## TiedPtr() \
205 { \
206 *m_pp = m_pOld; \
207 } \
208 \
209 private: \
210 T **m_pp; \
211 T *m_pOld; \
212 };
213
214 #endif // _WX_SCOPED_PTR_H_
215