1///////////////////////////////////////////////////////////////////////////// 2// Name: wx/ptr_scpd.h 3// Purpose: scoped smart pointer class 4// Author: Jesse Lovelace <jllovela@eos.ncsu.edu> 5// Modified by: 6// Created: 06/01/02 7// RCS-ID: $Id: ptr_scpd.h 35688 2005-09-25 19:59:19Z VZ $ 8// Copyright: (c) Jesse Lovelace and original Boost authors (see below) 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_POINTER__ 29#define __WX_SCOPED_POINTER__ 30 31#include "wx/defs.h" 32 33/* 34 checked deleters are used to make sure that the type being deleted is really 35 a complete type.: otherwise sizeof() would result in a compile-time error 36 37 do { ... } while ( 0 ) construct is used to have an anonymous scope 38 (otherwise we could have name clashes between different "complete"s) but 39 still force a semicolon after the macro 40*/ 41 42#ifdef __WATCOMC__ 43 #define wxFOR_ONCE(name) for(int name=0; name<1; name++) 44 #define wxPRE_NO_WARNING_SCOPE(name) wxFOR_ONCE(wxMAKE_UNIQUE_NAME(name)) 45 #define wxPOST_NO_WARNING_SCOPE(name) 46#else 47 #define wxPRE_NO_WARNING_SCOPE(name) do 48 #define wxPOST_NO_WARNING_SCOPE(name) while ( wxFalse ) 49#endif 50 51#define wxCHECKED_DELETE(ptr) \ 52 wxPRE_NO_WARNING_SCOPE(scope_var1) \ 53 { \ 54 typedef char complete[sizeof(*ptr)]; \ 55 delete ptr; \ 56 } wxPOST_NO_WARNING_SCOPE(scope_var1) 57 58#define wxCHECKED_DELETE_ARRAY(ptr) \ 59 wxPRE_NO_WARNING_SCOPE(scope_var2) \ 60 { \ 61 typedef char complete[sizeof(*ptr)]; \ 62 delete [] ptr; \ 63 } wxPOST_NO_WARNING_SCOPE(scope_var2) 64 65/* These scoped pointers are *not* assignable and cannot be used 66 within a container. Look for wxDECLARE_SHARED_PTR for this 67 functionality. 68 69 In addition, the type being used *must* be complete at the time 70 that wxDEFINE_SCOPED_* is called or a compiler error will result. 71 This is because the class checks for the completeness of the type 72 being used. 73*/ 74 75 76#define wxDECLARE_SCOPED_PTR(T, name) \ 77class name \ 78{ \ 79private: \ 80 T * m_ptr; \ 81 \ 82 name(name const &); \ 83 name & operator=(name const &); \ 84 \ 85public: \ 86 wxEXPLICIT name(T * ptr = NULL) \ 87 : m_ptr(ptr) { } \ 88 \ 89 ~name(); \ 90 \ 91 void reset(T * ptr = NULL) \ 92 { \ 93 if (m_ptr != ptr) \ 94 { \ 95 delete m_ptr; \ 96 m_ptr = ptr; \ 97 } \ 98 } \ 99 \ 100 T *release() \ 101 { \ 102 T *ptr = m_ptr; \ 103 m_ptr = NULL; \ 104 return ptr; \ 105 } \ 106 \ 107 T & operator*() const \ 108 { \ 109 wxASSERT(m_ptr != NULL); \ 110 return *m_ptr; \ 111 } \ 112 \ 113 T * operator->() const \ 114 { \ 115 wxASSERT(m_ptr != NULL); \ 116 return m_ptr; \ 117 } \ 118 \ 119 T * get() const \ 120 { \ 121 return m_ptr; \ 122 } \ 123 \ 124 void swap(name & ot) \ 125 { \ 126 T * tmp = ot.m_ptr; \ 127 ot.m_ptr = m_ptr; \ 128 m_ptr = tmp; \ 129 } \ 130}; 131 132#define wxDEFINE_SCOPED_PTR(T, name)\ 133name::~name() \ 134{ \ 135 wxCHECKED_DELETE(m_ptr); \ 136} 137 138// this macro can be used for the most common case when you want to declare and 139// define the scoped pointer at the same time and want to use the standard 140// naming convention: auto pointer to Foo is called FooPtr 141#define wxDEFINE_SCOPED_PTR_TYPE(T) \ 142 wxDECLARE_SCOPED_PTR(T, T ## Ptr) \ 143 wxDEFINE_SCOPED_PTR(T, T ## Ptr) 144 145// the same but for arrays instead of simple pointers 146#define wxDECLARE_SCOPED_ARRAY(T, name)\ 147class name \ 148{ \ 149private: \ 150 T * m_ptr; \ 151 name(name const &); \ 152 name & operator=(name const &); \ 153 \ 154public: \ 155 wxEXPLICIT name(T * p = NULL) : m_ptr(p) \ 156 {} \ 157 \ 158 ~name(); \ 159 void reset(T * p = NULL); \ 160 \ 161 T & operator[](long int i) const\ 162 { \ 163 wxASSERT(m_ptr != NULL); \ 164 wxASSERT(i >= 0); \ 165 return m_ptr[i]; \ 166 } \ 167 \ 168 T * get() const \ 169 { \ 170 return m_ptr; \ 171 } \ 172 \ 173 void swap(name & ot) \ 174 { \ 175 T * tmp = ot.m_ptr; \ 176 ot.m_ptr = m_ptr; \ 177 m_ptr = tmp; \ 178 } \ 179}; 180 181#define wxDEFINE_SCOPED_ARRAY(T, name) \ 182name::~name() \ 183{ \ 184 wxCHECKED_DELETE_ARRAY(m_ptr); \ 185} \ 186void name::reset(T * p){ \ 187 if (m_ptr != p) \ 188 { \ 189 wxCHECKED_DELETE_ARRAY(m_ptr); \ 190 m_ptr = p; \ 191 } \ 192} 193 194// ---------------------------------------------------------------------------- 195// "Tied" scoped pointer: same as normal one but also sets the value of 196// some other variable to the pointer value 197// ---------------------------------------------------------------------------- 198 199#define wxDEFINE_TIED_SCOPED_PTR_TYPE(T) \ 200 wxDEFINE_SCOPED_PTR_TYPE(T) \ 201 class T ## TiedPtr : public T ## Ptr \ 202 { \ 203 public: \ 204 T ## TiedPtr(T **pp, T *p) \ 205 : T ## Ptr(p), m_pp(pp) \ 206 { \ 207 m_pOld = *pp; \ 208 *pp = p; \ 209 } \ 210 \ 211 ~ T ## TiedPtr() \ 212 { \ 213 *m_pp = m_pOld; \ 214 } \ 215 \ 216 private: \ 217 T **m_pp; \ 218 T *m_pOld; \ 219 }; 220 221#endif // __WX_SCOPED_POINTER__ 222 223