scopedptr.h 7.6 KB

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