Leaked source code of windows server 2003
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.

180 lines
6.5 KiB

  1. #if !defined(_FUSION_INC_SMARTPTR_H_INCLUDED_)
  2. #define _FUSION_INC_SMARTPTR_H_INCLUDED_
  3. /*++
  4. Copyright (c) Microsoft Corporation
  5. Module Name:
  6. smartptr.h
  7. Abstract:
  8. Author:
  9. Jay Krell (a-JayK, JayKrell) October 2000
  10. Revision History:
  11. --*/
  12. #pragma once
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include "fusiontrace.h"
  17. #include "csxspreservelasterror.h" // Most destructors should use this.
  18. #include "fusionheap.h"
  19. #include <typeinfo.h>
  20. //
  21. // Need to flesh this out.
  22. // See \\cpvsbuild\Drops\v7.0\raw\current\vs\src\VSEE\lib\Memory\*Pointer*.
  23. //
  24. //
  25. // Split off into ATL style Base/TDerived to avoid compiler ICE;
  26. // Otherwise was void (*Delete)(T*) = SxsDelete<T>
  27. //
  28. template <typename T>
  29. class CSmartPtrBaseTypeHelper
  30. {
  31. public:
  32. #if DBG
  33. #define SXS_TYPE_NAME(t) (typeid(T).name())
  34. #else
  35. #define SXS_TYPE_NAME(t) ("")
  36. #endif // DBG
  37. static T *AllocateSingleton(PCSTR pszFileName, int nLine) { return new(pszFileName, nLine, SXS_TYPE_NAME(T)) T; }
  38. static T *AllocateArray(SIZE_T n, PCSTR pszFileName, int nLine) { return new(pszFileName, nLine, SXS_TYPE_NAME(T)) T[n]; }
  39. #undef SXS_TYPE_NAME
  40. static void DeleteSingleton(T *pt) { CSxsPreserveLastError ple; delete pt; ple.Restore(); }
  41. static void DeleteArray(T *pt) { CSxsPreserveLastError ple; delete []pt; ple.Restore(); }
  42. };
  43. //
  44. // Derived is never used. This is may be by accident or by design.
  45. //
  46. template <typename T, typename /*Derived*/, typename TTypeHelper = CSmartPtrBaseTypeHelper<T> >
  47. class CSmartPtrBase
  48. {
  49. typedef T *TPtr;
  50. typedef T const *TConstPtr;
  51. public:
  52. CSmartPtrBase() : m_p(NULL), m_fDelete(false) { }
  53. ~CSmartPtrBase() { ASSERT_NTC(m_p == NULL); }
  54. operator TPtr () { return m_p; }
  55. operator TConstPtr () const { return m_p; }
  56. TPtr *operator&() { ASSERT_NTC(m_p == NULL); m_fDelete = true; return &m_p; }
  57. TPtr operator->() { return m_p; }
  58. TConstPtr operator->() const { return m_p; }
  59. // this stores null in m_p and returns its previous value
  60. TPtr Detach() { T *p = m_p; m_p = NULL; m_fDelete = false; return p; }
  61. TPtr DetachAndHold() { m_fDelete = false; return m_p; }
  62. void FinalizeSingletonBase() { if (m_p != NULL) { if (m_fDelete) TTypeHelper::DeleteSingleton(m_p); m_p = NULL; } }
  63. void FinalizeArrayBase() { if (m_p != NULL) { if (m_fDelete) TTypeHelper::DeleteArray(m_p); m_p = NULL; } }
  64. protected:
  65. T* m_p;
  66. bool m_fDelete;
  67. void AttachForDeleteBase(T *p) { ASSERT_NTC(m_p == NULL); if (m_p == NULL) { m_p = p; m_fDelete = true; } }
  68. void AttachNoDeleteBase(T *p) { ASSERT_NTC(m_p == NULL); if (m_p == NULL) { m_p = p; m_fDelete = false; } }
  69. BOOL Win32AllocateSingletonBase(PCSTR pszFileName, int nLine) { BOOL fSuccess = FALSE; ASSERT_NTC(m_p == NULL); if ((m_p = TTypeHelper::AllocateSingleton(pszFileName, nLine)) == NULL) goto Exit; m_fDelete = true; fSuccess = TRUE; Exit: return fSuccess; }
  70. BOOL Win32AllocateArrayBase(SIZE_T n, PCSTR pszFileName, int nLine) { FN_PROLOG_WIN32 INTERNAL_ERROR_CHECK(m_p == NULL); IFALLOCFAILED_EXIT(m_p = TTypeHelper::AllocateArray(n, pszFileName, nLine)); m_fDelete = true; FN_EPILOG }
  71. static void DeleteSingleton(T *p) { TTypeHelper::DeleteSingleton(p); }
  72. static void DeleteArray(T *p) { TTypeHelper::DeleteArray(p); }
  73. private:
  74. CSmartPtrBase(const CSmartPtrBase&); // deliberately not implemented
  75. void operator=(const CSmartPtrBase&); // deliberately not implemented
  76. };
  77. template <typename T, typename TTypeHelper = CSmartPtrBaseTypeHelper<T> >
  78. class CSmartPtr : public CSmartPtrBase<T, CSmartPtr>
  79. {
  80. public:
  81. CSmartPtr() : Base() { }
  82. ~CSmartPtr() { if (m_p != NULL) { if (m_fDelete) Base::DeleteSingleton(m_p); m_p = NULL; } }
  83. CSmartPtr &AttachForDelete(T* p) { Base::AttachForDeleteBase(p); return *this; }
  84. CSmartPtr &AttachNoDelete(T* p) { Base::AttachNoDeleteBase(p); return *this; }
  85. bool operator ==(const CSmartPtr &r) const { return m_p == r.m_p; }
  86. BOOL Win32Allocate(PCSTR pszFileName, int nLine) { return Base::Win32AllocateSingletonBase(pszFileName, nLine); }
  87. private:
  88. typedef CSmartPtrBase<T, CSmartPtr> Base;
  89. CSmartPtr(const CSmartPtr&); // deliberately not implemented
  90. operator=(const CSmartPtr&); // deliberately not implemented
  91. };
  92. template <typename T>
  93. class CSmartArrayPtr : public CSmartPtrBase<T, CSmartArrayPtr>
  94. {
  95. typedef CSmartPtrBase<T, CSmartArrayPtr> Base;
  96. public:
  97. CSmartArrayPtr() : Base() { }
  98. ~CSmartArrayPtr() { if (m_p != NULL) { if (m_fDelete) Base::DeleteArray(m_p); m_p = NULL; } }
  99. CSmartArrayPtr &AttachForDelete(T *p) { Base::AttachForDelete(p); return *this; }
  100. CSmartArrayPtr &AttachNoDelete(T *p) { Base::AttachNoDelete(p); return *this; }
  101. bool operator ==(const CSmartArrayPtr &r) const { return m_p == r.m_p; }
  102. bool operator ==(T *prgt) const { return m_p == prgt; }
  103. BOOL Win32Allocate(SIZE_T n, PCSTR pszFileName, int nLine) { return Base::Win32AllocateArrayBase(n, pszFileName, nLine); }
  104. private:
  105. CSmartArrayPtr(const CSmartArrayPtr &);
  106. void operator =(const CSmartArrayPtr &);
  107. };
  108. template <typename T, void (*pfnDestructor)(T *)>
  109. class CSmartPtrWithNamedDestructorHelper
  110. {
  111. public:
  112. static void DeleteSingleton(T *pt) { CSxsPreserveLastError ple; (*pfnDestructor)(pt); ple.Restore(); }
  113. };
  114. template <
  115. typename T,
  116. void (*pfnDestructor)(T *),
  117. typename TTypeHelper = CSmartPtrWithNamedDestructorHelper<T, pfnDestructor> >
  118. class CSmartPtrWithNamedDestructor : public CSmartPtrBase<T, CSmartPtrWithNamedDestructor, TTypeHelper>
  119. {
  120. public:
  121. CSmartPtrWithNamedDestructor() : Base() { }
  122. ~CSmartPtrWithNamedDestructor() { if (m_p != NULL) { if (m_fDelete) Base::DeleteSingleton(m_p); m_p = NULL; } }
  123. CSmartPtrWithNamedDestructor &AttachForDelete(T* p) { Base::AttachForDeleteBase(p); return *this; }
  124. CSmartPtrWithNamedDestructor &AttachNoDelete(T* p) { Base::AttachNoDeleteBase(p); return *this; }
  125. bool operator ==(const CSmartPtrWithNamedDestructor &r) const { return m_p == r.m_p; }
  126. BOOL Win32Allocate(PCSTR pszFileName, int nLine) { return Base::Win32AllocateSingletonBase(pszFileName, nLine); }
  127. void Finalize() { Base::FinalizeSingletonBase(); }
  128. private:
  129. typedef CSmartPtrBase<T, CSmartPtrWithNamedDestructor, TTypeHelper> Base;
  130. CSmartPtrWithNamedDestructor(const CSmartPtrWithNamedDestructor &r); // deliberately not implemented
  131. operator=(const CSmartPtrWithNamedDestructor &r); // deliberately not implemented
  132. };
  133. #endif // !defined(_FUSION_INC_SMARTPTR_H_INCLUDED_)