Fix bug with using uninitialized flags in GetParentForModalDialog().
[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 #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 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 if (m_ptr != ptr) \
135 { \
136 delete m_ptr; \
137 m_ptr = ptr; \
138 } \
139 } \
140 \
141 T *release() \
142 { \
143 T *ptr = m_ptr; \
144 m_ptr = NULL; \
145 return ptr; \
146 } \
147 \
148 T & operator*() const \
149 { \
150 wxASSERT(m_ptr != NULL); \
151 return *m_ptr; \
152 } \
153 \
154 T * operator->() const \
155 { \
156 wxASSERT(m_ptr != NULL); \
157 return m_ptr; \
158 } \
159 \
160 T * get() const \
161 { \
162 return m_ptr; \
163 } \
164 \
165 void swap(name & ot) \
166 { \
167 T * tmp = ot.m_ptr; \
168 ot.m_ptr = m_ptr; \
169 m_ptr = tmp; \
170 } \
171 };
172
173 #define wxDEFINE_SCOPED_PTR(T, name)\
174 name::~name() \
175 { \
176 wxCHECKED_DELETE(m_ptr); \
177 }
178
179 // this macro can be used for the most common case when you want to declare and
180 // define the scoped pointer at the same time and want to use the standard
181 // naming convention: auto pointer to Foo is called FooPtr
182 #define wxDEFINE_SCOPED_PTR_TYPE(T) \
183 wxDECLARE_SCOPED_PTR(T, T ## Ptr) \
184 wxDEFINE_SCOPED_PTR(T, T ## Ptr)
185
186 // ----------------------------------------------------------------------------
187 // "Tied" scoped pointer: same as normal one but also sets the value of
188 // some other variable to the pointer value
189 // ----------------------------------------------------------------------------
190
191 #define wxDEFINE_TIED_SCOPED_PTR_TYPE(T) \
192 wxDEFINE_SCOPED_PTR_TYPE(T) \
193 class T ## TiedPtr : public T ## Ptr \
194 { \
195 public: \
196 T ## TiedPtr(T **pp, T *p) \
197 : T ## Ptr(p), m_pp(pp) \
198 { \
199 m_pOld = *pp; \
200 *pp = p; \
201 } \
202 \
203 ~ T ## TiedPtr() \
204 { \
205 *m_pp = m_pOld; \
206 } \
207 \
208 private: \
209 T **m_pp; \
210 T *m_pOld; \
211 };
212
213 #endif // _WX_SCOPED_PTR_H_
214