]> git.saurik.com Git - wxWidgets.git/blame_incremental - include/wx/scopedptr.h
Use correct reload flags on all platforms to avoid compilation errors
[wxWidgets.git] / include / wx / scopedptr.h
... / ...
CommitLineData
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
38template <class T>
39class wxScopedPtr
40{
41public:
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
102private:
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) \
118class name \
119{ \
120private: \
121 T * m_ptr; \
122 \
123 name(name const &); \
124 name & operator=(name const &); \
125 \
126public: \
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)\
167void name::reset(T * ptr) \
168{ \
169 if (m_ptr != ptr) \
170 { \
171 wxCHECKED_DELETE(m_ptr); \
172 m_ptr = ptr; \
173 } \
174} \
175name::~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