Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: autoptr.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef AUTOPTR_H_INCLUDED
  11. #define AUTOPTR_H_INCLUDED
  12. #ifndef ASSERT
  13. #ifndef _INC_CRTDBG
  14. #include <crtdbg.h>
  15. #endif // _INC_CRTDBG
  16. #define ASSERT(x) _ASSERT(x)
  17. #endif // ASSERT
  18. #include "cpputil.h"
  19. /*+-------------------------------------------------------------------------*
  20. * CAutoResourceManagementBase
  21. *
  22. * This is a base class that implements common functionality for the class
  23. * of smart resource handlers which release resource when it's destroyed. All
  24. * classes based on this class will behave identically, except the manner
  25. * in which they release their resources.
  26. *
  27. * DeleterClass is typically the class that derives from CAutoResourceManagementBase,
  28. * and must implement
  29. *
  30. * static void _Delete(ResourceType h);
  31. *
  32. * See CAutoPtr below for an example.
  33. *--------------------------------------------------------------------------*/
  34. template<typename ResourceType, typename DeleterClass>
  35. class CAutoResourceManagementBase
  36. {
  37. typedef CAutoResourceManagementBase<ResourceType, DeleterClass> ThisClass;
  38. typedef ThisClass Releaser;
  39. DECLARE_NOT_COPIABLE (ThisClass)
  40. DECLARE_NOT_ASSIGNABLE (ThisClass)
  41. // protected ctor so only derived classes can intantiate
  42. protected:
  43. explicit CAutoResourceManagementBase(ResourceType h = 0) throw() : m_hResource(h) {}
  44. public:
  45. ~CAutoResourceManagementBase() throw()
  46. {
  47. Delete();
  48. }
  49. void Attach(ResourceType p) throw()
  50. {
  51. ASSERT(m_hResource == NULL);
  52. m_hResource = p;
  53. }
  54. ResourceType Detach() throw()
  55. {
  56. ResourceType const p = m_hResource;
  57. m_hResource = NULL;
  58. return p;
  59. }
  60. /*
  61. * Returns the address of the pointer contained in this class.
  62. * This is useful when using the COM/OLE interfaces to create
  63. * allocate the object that this class manages.
  64. */
  65. ResourceType* operator&() throw()
  66. {
  67. /*
  68. * This object must be empty now, or the data pointed to will be leaked.
  69. */
  70. ASSERT (m_hResource == NULL);
  71. return &m_hResource;
  72. }
  73. operator ResourceType() const throw()
  74. {
  75. return m_hResource;
  76. }
  77. bool operator==(int p) const throw()
  78. {
  79. ASSERT(p == NULL);
  80. return m_hResource == NULL;
  81. }
  82. bool operator!=(int p) const throw()
  83. {
  84. ASSERT(p == NULL);
  85. return m_hResource != NULL;
  86. }
  87. bool operator!() const throw()
  88. {
  89. return m_hResource == NULL;
  90. }
  91. void Delete() throw()
  92. {
  93. if (m_hResource != NULL)
  94. {
  95. DeleterClass::_Delete (m_hResource);
  96. m_hResource = NULL;
  97. }
  98. }
  99. private:
  100. ResourceType m_hResource;
  101. }; // class CAutoResourceManagementBase
  102. /*+-------------------------------------------------------------------------*
  103. * CAutoPtrBase
  104. *
  105. * This is a base class that implements common functionality for the class
  106. * of smart pointers which delete its pointee when it's destroyed. All
  107. * classes based on this class will behave identically, except the manner
  108. * in which they destroy their pointees.
  109. *
  110. * DeleterClass is typically the class that derives from CAutoPtrBase, and
  111. * must implement
  112. *
  113. * static void _Delete(T* p);
  114. *
  115. * This template reuses CAutoResourceManagementBase to manage the pointer
  116. *
  117. * See CAutoPtr below for an example.
  118. *--------------------------------------------------------------------------*/
  119. template<typename T, typename DeleterClass>
  120. class CAutoPtrBase : public CAutoResourceManagementBase<T*, DeleterClass>
  121. {
  122. typedef CAutoPtrBase<T, DeleterClass> ThisClass;
  123. typedef CAutoResourceManagementBase<T*, DeleterClass> BaseClass;
  124. typedef BaseClass Releaser;
  125. DECLARE_NOT_COPIABLE (ThisClass)
  126. DECLARE_NOT_ASSIGNABLE (ThisClass)
  127. // protected ctor so only derived classes can intantiate
  128. protected:
  129. explicit CAutoPtrBase(T* p = 0) throw() : BaseClass(p) {}
  130. public:
  131. T& operator*() const throw()
  132. {
  133. T* ptr = *this; // use operator defined by the BaseClass for conversion
  134. ASSERT(ptr != NULL);
  135. return *ptr;
  136. }
  137. T* operator->() const throw()
  138. {
  139. T* ptr = *this; // use operator defined by the BaseClass for conversion
  140. ASSERT(ptr != NULL);
  141. return ptr;
  142. }
  143. }; // class CAutoPtrBase
  144. /*+-------------------------------------------------------------------------*
  145. * CAutoPtr
  146. *
  147. * CAutoPtrBase-based class that deletes pointers allocated with
  148. * operator new.
  149. *--------------------------------------------------------------------------*/
  150. template<class T>
  151. class CAutoPtr : public CAutoPtrBase<T, CAutoPtr<T> >
  152. {
  153. typedef CAutoPtrBase<T, CAutoPtr<T> > BaseClass;
  154. friend BaseClass::Releaser;
  155. public:
  156. explicit CAutoPtr(T* p = 0) throw() : BaseClass(p)
  157. {}
  158. private:
  159. // only CAutoPtrBase should call this
  160. static void _Delete (T* p)
  161. {
  162. delete p;
  163. }
  164. };
  165. /*+-------------------------------------------------------------------------*
  166. * CAutoArrayPtr
  167. *
  168. * CAutoPtrBase-based class that deletes pointers allocated with
  169. * operator new[].
  170. *--------------------------------------------------------------------------*/
  171. template<class T>
  172. class CAutoArrayPtr : public CAutoPtrBase<T, CAutoArrayPtr<T> >
  173. {
  174. typedef CAutoPtrBase<T, CAutoArrayPtr<T> > BaseClass;
  175. friend BaseClass::Releaser;
  176. public:
  177. explicit CAutoArrayPtr(T* p = 0) throw() : BaseClass(p)
  178. {}
  179. private:
  180. // only CAutoPtrBase should call this
  181. static void _Delete (T* p)
  182. {
  183. delete[] p;
  184. }
  185. };
  186. /*+-------------------------------------------------------------------------*
  187. * CCoTaskMemPtr
  188. *
  189. * CAutoPtrBase-based class that deletes pointers allocated with
  190. * CoTaskMemAlloc.
  191. *--------------------------------------------------------------------------*/
  192. template<class T>
  193. class CCoTaskMemPtr : public CAutoPtrBase<T, CCoTaskMemPtr<T> >
  194. {
  195. typedef CAutoPtrBase<T, CCoTaskMemPtr<T> > BaseClass;
  196. friend BaseClass::Releaser;
  197. public:
  198. explicit CCoTaskMemPtr(T* p = 0) throw() : BaseClass(p)
  199. {}
  200. private:
  201. // only CAutoPtrBase should call this
  202. static void _Delete (T* p)
  203. {
  204. if (p != NULL)
  205. CoTaskMemFree (p);
  206. }
  207. };
  208. /*+-------------------------------------------------------------------------*
  209. * CAutoGlobalPtr
  210. *
  211. * CAutoPtrBase-based class that deletes pointers allocated with GlobalAlloc.
  212. *--------------------------------------------------------------------------*/
  213. template<class T>
  214. class CAutoGlobalPtr : public CAutoPtrBase<T, CAutoGlobalPtr<T> >
  215. {
  216. typedef CAutoPtrBase<T, CAutoGlobalPtr<T> > BaseClass;
  217. friend BaseClass::Releaser;
  218. public:
  219. explicit CAutoGlobalPtr(T* p = 0) throw() : BaseClass(p)
  220. {}
  221. private:
  222. // only CAutoPtrBase should call this
  223. static void _Delete (T* p)
  224. {
  225. if (p != NULL)
  226. GlobalFree (p);
  227. }
  228. };
  229. /*+-------------------------------------------------------------------------*
  230. * CAutoLocalPtr
  231. *
  232. * CAutoPtrBase-based class that deletes pointers allocated with LocalAlloc.
  233. *--------------------------------------------------------------------------*/
  234. template<class T>
  235. class CAutoLocalPtr : public CAutoPtrBase<T, CAutoLocalPtr<T> >
  236. {
  237. typedef CAutoPtrBase<T, CAutoLocalPtr<T> > BaseClass;
  238. friend BaseClass::Releaser;
  239. public:
  240. explicit CAutoLocalPtr(T* p = 0) throw() : BaseClass(p)
  241. {}
  242. private:
  243. // only CAutoPtrBase should call this
  244. static void _Delete (T* p)
  245. {
  246. if (p != NULL)
  247. LocalFree (p);
  248. }
  249. };
  250. /*+-------------------------------------------------------------------------*
  251. * CHeapAllocMemPtr
  252. *
  253. * CAutoPtrBase-based class that deletes pointers allocated from the process
  254. * default heap with HeapAlloc.
  255. *--------------------------------------------------------------------------*/
  256. template<class T>
  257. class CHeapAllocMemPtr : public CAutoPtrBase<T, CHeapAllocMemPtr<T> >
  258. {
  259. typedef CAutoPtrBase<T, CHeapAllocMemPtr<T> > BaseClass;
  260. friend BaseClass::Releaser;
  261. public:
  262. explicit CHeapAllocMemPtr(T* p = 0) throw() : BaseClass(p)
  263. {}
  264. private:
  265. // only CAutoPtrBase should call this
  266. static void _Delete (T* p)
  267. {
  268. if (p != NULL)
  269. HeapFree(::GetProcessHeap(), 0, p);
  270. }
  271. };
  272. /*+-------------------------------------------------------------------------*
  273. * CAutoWin32Handle
  274. *
  275. * CAutoPtrBase-based class that closes HANDLE on destruction
  276. *--------------------------------------------------------------------------*/
  277. class CAutoWin32Handle : public CAutoResourceManagementBase<HANDLE, CAutoWin32Handle>
  278. {
  279. typedef CAutoResourceManagementBase<HANDLE, CAutoWin32Handle> BaseClass;
  280. friend BaseClass::Releaser;
  281. public:
  282. explicit CAutoWin32Handle(HANDLE p = NULL) throw() : BaseClass(p) {}
  283. bool IsValid()
  284. {
  285. return IsValid(*this); // use base class operator to convet to HANDLE
  286. }
  287. private:
  288. static bool IsValid (HANDLE p)
  289. {
  290. return (p != NULL && p != INVALID_HANDLE_VALUE);
  291. }
  292. // only CAutoResourceManagementBase should call this
  293. static void _Delete (HANDLE p)
  294. {
  295. if (IsValid(p))
  296. CloseHandle(p);
  297. }
  298. };
  299. /*+-------------------------------------------------------------------------*
  300. * CAutoAssignOnExit
  301. *
  302. * instances of this template class assign the value in destructor.
  303. *
  304. * USAGE: Say you have variable "int g_status" which must be set to S_OK before
  305. * you leave the function. To do so declare following in the function:
  306. *
  307. * CAutoAssignOnExit<int,S_OK> any_object_name(g_status);
  308. *--------------------------------------------------------------------------*/
  309. template<typename T, T value>
  310. class CAutoAssignOnExit
  311. {
  312. T& m_rVariable; // variable, which needs to be modified in destructor
  313. public:
  314. // constructor
  315. CAutoAssignOnExit( T& rVariable ) : m_rVariable(rVariable) {}
  316. // destructor
  317. ~CAutoAssignOnExit()
  318. {
  319. // assign designated final value
  320. m_rVariable = value;
  321. }
  322. };
  323. #endif // AUTOPTR_H_INCLUDED