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.

622 lines
18 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: gensph.h
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: LazarI
  10. *
  11. * DATE: 23-Dec-2000
  12. *
  13. * DESCRIPTION: generic smart pointers & smart handles templates
  14. *
  15. *****************************************************************************/
  16. #ifndef _GENSPH_H_
  17. #define _GENSPH_H_
  18. // include the core definitions first
  19. #include "coredefs.h"
  20. ////////////////////////////////////////////////
  21. //
  22. // class CGenericSP
  23. //
  24. // a generic smart pointer
  25. // everything starts here -:)
  26. //
  27. template < class T,
  28. class inheritorClass,
  29. class pType = T*,
  30. INT_PTR null = 0,
  31. class pCType = const T* >
  32. class CGenericSP
  33. {
  34. public:
  35. // construction/destruction
  36. CGenericSP(): m_p(GetNull()) {}
  37. CGenericSP(pType p): m_p(GetNull()) { _Attach(p); }
  38. ~CGenericSP() { Reset(); }
  39. // follows common smart pointer impl. -
  40. // operators & methods
  41. void Reset()
  42. {
  43. if( GetNull() != m_p )
  44. {
  45. _Delete(m_p);
  46. m_p = GetNull();
  47. }
  48. }
  49. void Attach(pType p)
  50. {
  51. Reset();
  52. m_p = (p ? p : GetNull());
  53. }
  54. pType Detach()
  55. {
  56. pType p = GetNull();
  57. if( GetNull() != m_p )
  58. {
  59. p = m_p;
  60. m_p = GetNull();
  61. }
  62. return p;
  63. }
  64. template <class AS_TYPE>
  65. AS_TYPE GetPtrAs() const
  66. {
  67. return (GetNull() == m_p) ? reinterpret_cast<AS_TYPE>(NULL) : reinterpret_cast<AS_TYPE>(m_p);
  68. }
  69. pType GetPtr() const
  70. {
  71. return GetPtrAs<pType>();
  72. }
  73. pType* GetPPT()
  74. {
  75. return static_cast<pType*>(&m_p);
  76. }
  77. pCType* GetPPCT()
  78. {
  79. return const_cast<pCType*>(&m_p);
  80. }
  81. void** GetPPV()
  82. {
  83. return reinterpret_cast<void**>(&m_p);
  84. }
  85. operator pType() const
  86. {
  87. return GetPtr();
  88. }
  89. T& operator*() const
  90. {
  91. ASSERT(GetNull() != m_p);
  92. return *m_p;
  93. }
  94. pType* operator&()
  95. {
  96. ASSERT(GetNull() == m_p);
  97. return GetPPT();
  98. }
  99. pType operator->() const
  100. {
  101. ASSERT(GetNull() != m_p);
  102. return (pType)m_p;
  103. }
  104. pType operator=(pType p)
  105. {
  106. _Attach(p);
  107. return m_p;
  108. }
  109. pType operator=(const int i)
  110. {
  111. // this operator is only for NULL assignment
  112. ASSERT(INT2PTR(i, pType) == NULL || INT2PTR(i, pType) == GetNull());
  113. Attach(INT2PTR(i, pType));
  114. return m_p;
  115. }
  116. bool operator!() const
  117. {
  118. return (GetNull() == m_p);
  119. }
  120. bool operator<(pType p) const
  121. {
  122. return (m_p < p);
  123. }
  124. bool operator==(pType p) const
  125. {
  126. return (m_p == p);
  127. }
  128. protected:
  129. pType m_p;
  130. // those will be declared protected, so people won't use them directly
  131. CGenericSP(CGenericSP<T, inheritorClass, pType, null, pCType> &sp): m_p(GetNull())
  132. {
  133. _Attach(sp);
  134. }
  135. void Attach(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
  136. {
  137. static_cast<inheritorClass*>(this)->Attach(static_cast<pType>(sp));
  138. sp.Detach();
  139. }
  140. pType operator=(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
  141. {
  142. _Attach(sp);
  143. return m_p;
  144. }
  145. // NULL support, use these to check for/assign NULL in inheritors
  146. pType GetNull() const { return reinterpret_cast<pType>(null); }
  147. bool IsNull(pType p) const { return GetNull() == p; }
  148. bool IsntNull(pType p) const { return GetNull() != p; }
  149. private:
  150. void _Attach(pType p)
  151. {
  152. // give a chance to inheritors to override the attach
  153. static_cast<inheritorClass*>(this)->Attach(p);
  154. }
  155. void _Attach(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
  156. {
  157. // give a chance to inheritors to override the attach
  158. static_cast<inheritorClass*>(this)->Attach(sp);
  159. }
  160. void _Delete(pType p)
  161. {
  162. // the inheritor class defines static member called Delete(pType p)
  163. // to destroy the object.
  164. if( GetNull() != p )
  165. {
  166. inheritorClass::Delete(p);
  167. }
  168. }
  169. };
  170. // declares standard default contructor, copy constructor, attach
  171. // contructor and assignment operators (they can't be inherited as constructors can't)
  172. // for the CGenericSP class in an inheritor class.
  173. #define DECLARE_GENERICSMARTPTR_CONSTRUCT(T, className) \
  174. private: \
  175. className(className &sp): CGenericSP< T, className >(sp) { } \
  176. T* operator=(className &sp) \
  177. { return CGenericSP< T, className >::operator =(sp); } \
  178. public: \
  179. className() { } \
  180. className(T *p): CGenericSP< T, className >(p) { } \
  181. T* operator=(T *p) \
  182. { return CGenericSP< T, className >::operator =(p); } \
  183. T* operator=(const int i) \
  184. { return CGenericSP< T, className >::operator =(i); } \
  185. #define DECLARE_GENERICSMARTPTR_CONSTRUCT1(T, className, pType) \
  186. private: \
  187. className(className &sp): CGenericSP<T, className, pType>(sp) { } \
  188. pType operator=(className &sp) \
  189. { return CGenericSP<T, className, pType>::operator =(sp); } \
  190. public: \
  191. className() { } \
  192. className(pType p): CGenericSP<T, className, pType>(p) { } \
  193. pType operator=(pType p) \
  194. { return CGenericSP<T, className, pType>::operator =(p); } \
  195. pType operator=(const int i) \
  196. { return CGenericSP<T, className, pType>::operator =(i); } \
  197. #define DECLARE_GENERICSMARTPTR_CONSTRUCT2(T, className, pType, null) \
  198. private: \
  199. className(className &sp): CGenericSP<T, className, pType, null>(sp) { } \
  200. pType operator=(className &sp) \
  201. { return CGenericSP<T, className, pType, null>::operator =(sp); } \
  202. public: \
  203. className() { } \
  204. className(pType p): CGenericSP<T, className, pType, null>(p) { } \
  205. pType operator=(pType p) \
  206. { return CGenericSP<T, className, pType, null>::operator =(p); } \
  207. pType operator=(const int i) \
  208. { return CGenericSP<T, className, pType, null>::operator =(i); } \
  209. ////////////////////////////////////////////////
  210. ////////// AUTO POINTERS ///////////////////////
  211. ////////////////////////////////////////////////
  212. ////////////////////////////////////////////////
  213. //
  214. // class CAutoPtr
  215. //
  216. // simple auto-pointer
  217. // uses delete operator to free memory
  218. //
  219. template <class T>
  220. class CAutoPtr: public CGenericSP< T, CAutoPtr<T> >
  221. {
  222. public:
  223. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtr<T>)
  224. static void Delete(T *p) { delete p; }
  225. };
  226. ////////////////////////////////////////////////
  227. //
  228. // class CAutoPtrArray
  229. //
  230. // simple auto-pointer allocated as array
  231. // uses delete[] operator to free memory
  232. //
  233. template <class T>
  234. class CAutoPtrArray: public CGenericSP< T, CAutoPtrArray<T> >
  235. {
  236. public:
  237. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrArray<T>)
  238. static void Delete(T *p) { delete[] p; }
  239. };
  240. ////////////////////////////////////////////////
  241. //
  242. // class CAutoPtrCRT
  243. //
  244. // simple CRT auto-pointer - allocated with malloc/calloc
  245. // uses free to free the memory
  246. //
  247. template <class T>
  248. class CAutoPtrCRT: public CGenericSP< T, CAutoPtrCRT<T> >
  249. {
  250. public:
  251. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrCRT<T>)
  252. static void Delete(T *p) { free(p); }
  253. };
  254. ////////////////////////////////////////////////
  255. //
  256. // class CAutoPtrSpl
  257. //
  258. // simple spooler auto-pointer -
  259. // uses FreeMem to free memory
  260. //
  261. template <class T>
  262. class CAutoPtrSpl: public CGenericSP< T, CAutoPtrSpl<T> >
  263. {
  264. public:
  265. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrSpl<T>)
  266. static void Delete(T *p) { FreeMem(p); }
  267. };
  268. ////////////////////////////////////////////////
  269. //
  270. // class CAutoPtrBSTR
  271. //
  272. // simple BSTR auto-pointer -
  273. // SysAllocString/SysFreeString
  274. //
  275. class CAutoPtrBSTR: public CGenericSP<BSTR, CAutoPtrBSTR, BSTR>
  276. {
  277. public:
  278. DECLARE_GENERICSMARTPTR_CONSTRUCT1(BSTR, CAutoPtrBSTR, BSTR)
  279. static void Delete(BSTR p) { SysFreeString(p); }
  280. };
  281. ////////////////////////////////////////////////
  282. //
  283. // class CAutoPtrCOM
  284. //
  285. // simple smart COM pointer
  286. //
  287. template <class T>
  288. class CAutoPtrCOM: public CGenericSP< T, CAutoPtrCOM<T> >
  289. {
  290. public:
  291. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrCOM<T>)
  292. static void Delete(T *p) { p->Release(); }
  293. };
  294. ////////////////////////////////////////////////
  295. //
  296. // class CRefPtrCOM
  297. //
  298. // referenced smart COM pointer (ATL style)
  299. // with improvements for robustness
  300. //
  301. template <class T>
  302. class CRefPtrCOM: public CGenericSP< T, CRefPtrCOM<T> >
  303. {
  304. void _AddRefAttach(T *p);
  305. public:
  306. // special case all these
  307. CRefPtrCOM() { }
  308. CRefPtrCOM(const CGenericSP< T, CRefPtrCOM<T> > &sp): CGenericSP< T, CRefPtrCOM<T> >(sp) { }
  309. T* operator=(const CRefPtrCOM<T> &sp) { return CGenericSP< T, CRefPtrCOM<T> >::operator =(sp); }
  310. T* operator=(const int i) { return CGenericSP< T, CRefPtrCOM<T> >::operator =(i); }
  311. // overloaded stuff
  312. void Attach(const CRefPtrCOM<T> &sp) { _AddRefAttach(static_cast<T*>(sp)); }
  313. static void Delete(T *p) { p->Release(); }
  314. // use these functions instead of operators (more clear)
  315. HRESULT CopyFrom(T *p); // AddRef p and assign to this
  316. HRESULT CopyTo(T **ppObj); // AddRef this and assign to ppObj
  317. HRESULT TransferTo(T **ppObj); // assign this to ppObj and assign NULL to this
  318. HRESULT Adopt(T *p); // take ownership of p
  319. private:
  320. // disable contruction, assignment operator & attach from
  321. // a raw pointer - it's not clear what exactly you want:
  322. // to copy (AddRef) the object or to take ownership - use
  323. // the functions above to make clear
  324. void Attach(T* p);
  325. CRefPtrCOM(T *p);
  326. T* operator=(T *p);
  327. };
  328. ////////////////////////////////////////////////
  329. //
  330. // class CAutoPtrShell
  331. //
  332. // smart shell auto pointer -
  333. // uses shell IMalloc to free memory
  334. //
  335. template <class T>
  336. class CAutoPtrShell: public CGenericSP< T, CAutoPtrShell<T> >
  337. {
  338. public:
  339. DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrShell<T>)
  340. static void Delete(T *p)
  341. {
  342. CAutoPtrCOM<IMalloc> spShellMalloc;
  343. if( SUCCEEDED(SHGetMalloc(&spShellMalloc)) )
  344. {
  345. spShellMalloc->Free(p);
  346. }
  347. }
  348. };
  349. ////////////////////////////////////////////////
  350. //
  351. // class CAutoPtrPIDL
  352. //
  353. // smart shell ID list ptr - LPCITEMIDLIST, LPITEMIDLIST.
  354. //
  355. typedef CAutoPtrShell<ITEMIDLIST> CAutoPtrPIDL;
  356. ////////////////////////////////////////////////
  357. ////////// AUTO HANDLES ////////////////////////
  358. ////////////////////////////////////////////////
  359. ////////////////////////////////////////////////
  360. //
  361. // class CAutoHandleNT
  362. //
  363. // NT kernel object handle (closed with CloseHandle)
  364. //
  365. class CAutoHandleNT: public CGenericSP<HANDLE, CAutoHandleNT, HANDLE>
  366. {
  367. public:
  368. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandleNT, HANDLE)
  369. static void Delete(HANDLE h) { VERIFY(CloseHandle(h)); }
  370. };
  371. ////////////////////////////////////////////////
  372. //
  373. // class CAutoHandleHLOCAL
  374. //
  375. // NT local heap handle (closed with LocalFree)
  376. //
  377. class CAutoHandleHLOCAL: public CGenericSP<HLOCAL, CAutoHandleHLOCAL, HLOCAL>
  378. {
  379. public:
  380. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HLOCAL, CAutoHandleHLOCAL, HLOCAL)
  381. static void Delete(HLOCAL h) { VERIFY(NULL == LocalFree(h)); }
  382. };
  383. ////////////////////////////////////////////////
  384. //
  385. // class CAutoHandleHGLOBAL
  386. //
  387. // NT global heap handle (closed with GlobalFree)
  388. //
  389. class CAutoHandleHGLOBAL: public CGenericSP<HGLOBAL, CAutoHandleHGLOBAL, HGLOBAL>
  390. {
  391. public:
  392. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HGLOBAL, CAutoHandleHGLOBAL, HGLOBAL)
  393. static void Delete(HGLOBAL h) { VERIFY(NULL == GlobalFree(h)); }
  394. };
  395. ////////////////////////////////////////////////
  396. //
  397. // class CAutoHandlePrinter
  398. //
  399. // auto printer handle
  400. //
  401. class CAutoHandlePrinter: public CGenericSP<HANDLE, CAutoHandlePrinter, HANDLE>
  402. {
  403. public:
  404. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandlePrinter, HANDLE)
  405. static void Delete(HANDLE h) { CHECK(ClosePrinter(h)); }
  406. };
  407. ////////////////////////////////////////////////
  408. //
  409. // class CAutoHandlePrinterNotify
  410. //
  411. // printer notifications handle -
  412. // Find[Firse/Next/Close]PrinterChangeNotification()
  413. //
  414. class CAutoHandlePrinterNotify: public CGenericSP<HANDLE, CAutoHandlePrinterNotify, HANDLE, -1>
  415. {
  416. public:
  417. DECLARE_GENERICSMARTPTR_CONSTRUCT2(HANDLE, CAutoHandlePrinterNotify, HANDLE, -1)
  418. static void Delete(HANDLE h) { CHECK(FindClosePrinterChangeNotification(h)); }
  419. };
  420. ////////////////////////////////////////////////
  421. //
  422. // class CAutoPtrPrinterNotify
  423. //
  424. // printer notifications memory - spooler should free it.
  425. // Find[Firse/Next/Close]PrinterChangeNotification()
  426. //
  427. class CAutoPtrPrinterNotify: public CGenericSP<PRINTER_NOTIFY_INFO, CAutoPtrPrinterNotify>
  428. {
  429. public:
  430. DECLARE_GENERICSMARTPTR_CONSTRUCT(PRINTER_NOTIFY_INFO, CAutoPtrPrinterNotify)
  431. static void Delete(PRINTER_NOTIFY_INFO *p) { CHECK(FreePrinterNotifyInfo(p)); }
  432. };
  433. ////////////////////////////////////////////////
  434. //
  435. // class CAutoHandleGDI
  436. //
  437. // GDI auto handle (WindowsNT GDI handle wrapper)
  438. //
  439. template <class T>
  440. class CAutoHandleGDI: public CGenericSP< T, CAutoHandleGDI<T>, T >
  441. {
  442. public:
  443. DECLARE_GENERICSMARTPTR_CONSTRUCT1(T, CAutoHandleGDI<T>, T)
  444. static void Delete(T hGDIObj) { VERIFY(DeleteObject(hGDIObj)); }
  445. };
  446. // GDI auto handles
  447. typedef CAutoHandleGDI<HPEN> CAutoHandlePen;
  448. typedef CAutoHandleGDI<HBRUSH> CAutoHandleBrush;
  449. typedef CAutoHandleGDI<HFONT> CAutoHandleFont;
  450. typedef CAutoHandleGDI<HBITMAP> CAutoHandleBitmap;
  451. // etc...
  452. ////////////////////////////////////////////////
  453. //
  454. // class CAutoHandleCursor
  455. //
  456. // auto handle for HCURSOR
  457. //
  458. class CAutoHandleCursor: public CGenericSP<HCURSOR, CAutoHandleCursor, HCURSOR>
  459. {
  460. public:
  461. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HCURSOR, CAutoHandleCursor, HCURSOR)
  462. static void Delete(HCURSOR h) { VERIFY(DestroyCursor(h)); }
  463. };
  464. ////////////////////////////////////////////////
  465. //
  466. // class CAutoHandleIcon
  467. //
  468. // auto handle for HICON
  469. //
  470. class CAutoHandleIcon: public CGenericSP<HICON, CAutoHandleIcon, HICON>
  471. {
  472. public:
  473. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HICON, CAutoHandleIcon, HICON)
  474. static void Delete(HICON h) { VERIFY(DestroyIcon(h)); }
  475. };
  476. ////////////////////////////////////////////////
  477. //
  478. // class CAutoHandleMenu
  479. //
  480. // auto handle for HMENU
  481. //
  482. class CAutoHandleMenu: public CGenericSP<HMENU, CAutoHandleMenu, HMENU>
  483. {
  484. public:
  485. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HMENU, CAutoHandleMenu, HMENU)
  486. static void Delete(HMENU h) { VERIFY(DestroyMenu(h)); }
  487. };
  488. ////////////////////////////////////////////////
  489. //
  490. // class CAutoHandleAccel
  491. //
  492. // auto handle for HACCEL
  493. //
  494. class CAutoHandleAccel: public CGenericSP<HACCEL, CAutoHandleAccel, HACCEL>
  495. {
  496. public:
  497. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HACCEL, CAutoHandleAccel, HACCEL)
  498. static void Delete(HACCEL h) { DestroyAcceleratorTable(h); }
  499. };
  500. #ifdef _INC_COMCTRLP
  501. ////////////////////////////////////////////////
  502. //
  503. // class CAutoHandleHDSA
  504. //
  505. // auto handle for shell HDSA
  506. // (dynamic structure arrays)
  507. //
  508. class CAutoHandleHDSA: public CGenericSP<HDSA, CAutoHandleHDSA, HDSA>
  509. {
  510. public:
  511. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HDSA, CAutoHandleHDSA, HDSA)
  512. static void Delete(HDSA h) { VERIFY(DSA_Destroy(h)); }
  513. };
  514. ////////////////////////////////////////////////
  515. //
  516. // class CAutoHandleMRU
  517. //
  518. // auto handle for MRU (shell common controls)
  519. // CreateMRUList/FreeMRUList
  520. //
  521. class CAutoHandleMRU: public CGenericSP<HANDLE, CAutoHandleMRU, HANDLE>
  522. {
  523. public:
  524. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandleMRU, HANDLE)
  525. static void Delete(HANDLE h) { FreeMRUList(h); }
  526. };
  527. #endif // _INC_COMCTRLP
  528. ////////////////////////////////////////////////
  529. //
  530. // class CAutoHandleHKEY
  531. //
  532. // auto handle for a Windows registry key (HKEY)
  533. // RegCreateKeyEx/RegOpenKeyEx/RegCloseKey
  534. //
  535. class CAutoHandleHKEY: public CGenericSP<HKEY, CAutoHandleHKEY, HKEY>
  536. {
  537. public:
  538. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HKEY, CAutoHandleHKEY, HKEY)
  539. static void Delete(HKEY h) { VERIFY(ERROR_SUCCESS == RegCloseKey(h)); }
  540. };
  541. ////////////////////////////////////////////////
  542. //
  543. // class CAutoHandleHMODULE
  544. //
  545. // auto handle for a HMODULE
  546. // LoadLibrary/FreeLibrary
  547. //
  548. class CAutoHandleHMODULE: public CGenericSP<HMODULE, CAutoHandleHMODULE, HMODULE>
  549. {
  550. public:
  551. DECLARE_GENERICSMARTPTR_CONSTRUCT1(HMODULE, CAutoHandleHMODULE, HMODULE)
  552. static void Delete(HMODULE h) { VERIFY(FreeLibrary(h)); }
  553. };
  554. // include the implementation of the template classes here
  555. #include "gensph.inl"
  556. #endif // endif _GENSPH_H_