]> git.saurik.com Git - wxWidgets.git/blob - include/wx/scopedptr.h
this one should really work
[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() { 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 typedef T *(wxScopedPtr<T>::*unspecified_bool_type)() const;
51 operator unspecified_bool_type() const
52 {
53 return m_ptr ? &wxScopedPtr<T>::get : NULL;
54 }
55
56 void reset(T * ptr = NULL)
57 {
58 if ( ptr != m_ptr )
59 {
60 delete m_ptr;
61 m_ptr = ptr;
62 }
63 }
64
65 T *release()
66 {
67 T *ptr = m_ptr;
68 m_ptr = NULL;
69 return ptr;
70 }
71
72 T & operator*() const
73 {
74 wxASSERT(m_ptr != NULL);
75 return *m_ptr;
76 }
77
78 T * operator->() const
79 {
80 wxASSERT(m_ptr != NULL);
81 return m_ptr;
82 }
83
84 T * get() const
85 {
86 return m_ptr;
87 }
88
89 void swap(wxScopedPtr& other)
90 {
91 T * const tmp = other.m_ptr;
92 other.m_ptr = m_ptr;
93 m_ptr = tmp;
94 }
95
96 private:
97 T * m_ptr;
98
99 DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedPtr, T)
100 };
101
102 // ----------------------------------------------------------------------------
103 // old macro based implementation
104 // ----------------------------------------------------------------------------
105
106 /* The type being used *must* be complete at the time
107 that wxDEFINE_SCOPED_* is called or a compiler error will result.
108 This is because the class checks for the completeness of the type
109 being used. */
110
111 #define wxDECLARE_SCOPED_PTR(T, name) \
112 class name \
113 { \
114 private: \
115 T * m_ptr; \
116 \
117 name(name const &); \
118 name & operator=(name const &); \
119 \
120 public: \
121 wxEXPLICIT name(T * ptr = NULL) \
122 : m_ptr(ptr) { } \
123 \
124 ~name(); \
125 \
126 void reset(T * ptr = NULL) \
127 { \
128 if (m_ptr != ptr) \
129 { \
130 delete m_ptr; \
131 m_ptr = ptr; \
132 } \
133 } \
134 \
135 T *release() \
136 { \
137 T *ptr = m_ptr; \
138 m_ptr = NULL; \
139 return ptr; \
140 } \
141 \
142 T & operator*() const \
143 { \
144 wxASSERT(m_ptr != NULL); \
145 return *m_ptr; \
146 } \
147 \
148 T * operator->() const \
149 { \
150 wxASSERT(m_ptr != NULL); \
151 return m_ptr; \
152 } \
153 \
154 T * get() const \
155 { \
156 return m_ptr; \
157 } \
158 \
159 void swap(name & ot) \
160 { \
161 T * tmp = ot.m_ptr; \
162 ot.m_ptr = m_ptr; \
163 m_ptr = tmp; \
164 } \
165 };
166
167 #define wxDEFINE_SCOPED_PTR(T, name)\
168 name::~name() \
169 { \
170 wxCHECKED_DELETE(m_ptr); \
171 }
172
173 // this macro can be used for the most common case when you want to declare and
174 // define the scoped pointer at the same time and want to use the standard
175 // naming convention: auto pointer to Foo is called FooPtr
176 #define wxDEFINE_SCOPED_PTR_TYPE(T) \
177 wxDECLARE_SCOPED_PTR(T, T ## Ptr) \
178 wxDEFINE_SCOPED_PTR(T, T ## Ptr)
179
180 // ----------------------------------------------------------------------------
181 // "Tied" scoped pointer: same as normal one but also sets the value of
182 // some other variable to the pointer value
183 // ----------------------------------------------------------------------------
184
185 #define wxDEFINE_TIED_SCOPED_PTR_TYPE(T) \
186 wxDEFINE_SCOPED_PTR_TYPE(T) \
187 class T ## TiedPtr : public T ## Ptr \
188 { \
189 public: \
190 T ## TiedPtr(T **pp, T *p) \
191 : T ## Ptr(p), m_pp(pp) \
192 { \
193 m_pOld = *pp; \
194 *pp = p; \
195 } \
196 \
197 ~ T ## TiedPtr() \
198 { \
199 *m_pp = m_pOld; \
200 } \
201 \
202 private: \
203 T **m_pp; \
204 T *m_pOld; \
205 };
206
207 #endif // _WX_SCOPED_PTR_H_
208