]> git.saurik.com Git - wxWidgets.git/blob - include/wx/msw/private/comptr.h
Added wxCOMPtr<> helper class.
[wxWidgets.git] / include / wx / msw / private / comptr.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/msw/private/comptr.h
3 // Purpose: Smart pointer for COM interfaces.
4 // Author: PB
5 // Created: 2012-04-16
6 // RCS-ID: $Id: $
7 // Copyright: (c) 2012 wxWidgets team
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_MSW_PRIVATE_COMPTR_H_
12 #define _WX_MSW_PRIVATE_COMPTR_H_
13
14 // ----------------------------------------------------------------------------
15 // wxCOMPtr: Minimalistic a smart pointer for use with COM interfaces.
16 // ----------------------------------------------------------------------------
17
18 template <class T>
19 class wxCOMPtr
20 {
21 public:
22 typedef T element_type;
23
24 wxCOMPtr()
25 : m_ptr(NULL)
26 {
27 }
28
29 wxEXPLICIT wxCOMPtr(T* ptr)
30 : m_ptr(ptr)
31 {
32 if ( m_ptr )
33 m_ptr->AddRef();
34 }
35
36 wxCOMPtr(const wxCOMPtr& ptr)
37 : m_ptr(ptr.get())
38 {
39 if ( m_ptr )
40 m_ptr->AddRef();
41 }
42
43 ~wxCOMPtr()
44 {
45 if ( m_ptr )
46 m_ptr->Release();
47 }
48
49 void reset(T* ptr = NULL)
50 {
51 if ( m_ptr != ptr)
52 {
53 if ( ptr )
54 ptr->AddRef();
55 if ( m_ptr )
56 m_ptr->Release();
57 m_ptr = ptr;
58 }
59 }
60
61 wxCOMPtr& operator=(const wxCOMPtr& ptr)
62 {
63 reset(ptr.get());
64 return *this;
65 }
66
67 wxCOMPtr& operator=(T* ptr)
68 {
69 reset(ptr);
70 return *this;
71 }
72
73 operator T*() const
74 {
75 return m_ptr;
76 }
77
78 T& operator*() const
79 {
80 return *m_ptr;
81 }
82
83 T* operator->() const
84 {
85 return m_ptr;
86 }
87
88 // It would be better to forbid direct access completely but we do need
89 // for QueryInterface() and similar functions, so provide it but it can
90 // only be used to initialize the pointer, not to modify an existing one.
91 T** operator&()
92 {
93 wxASSERT_MSG(!m_ptr,
94 wxS("Can't get direct access to initialized pointer"));
95
96 return &m_ptr;
97 }
98
99 T* get() const
100 {
101 return m_ptr;
102 }
103
104 bool operator<(T* ptr) const
105 {
106 return get() < ptr;
107 }
108
109 private:
110 T* m_ptr;
111 };
112
113 // Define a helper for the macro below: we just need a function taking a
114 // pointer and not returning anything to avoid warnings about unused return
115 // value of the cast in the macro itself.
116 namespace wxPrivate { void PPV_ARGS_CHECK(void*) { } }
117
118 // Takes the interface name and a pointer to a pointer of the interface type
119 // and expands into the IID of this interface and the same pointer but after a
120 // type-safety check.
121 //
122 // This is similar to the standard IID_PPV_ARGS macro but takes the pointer
123 // type instead of relying on the non-standard Microsoft __uuidof().
124 #define wxIID_PPV_ARGS(IType, pType) \
125 IID_##IType, \
126 (wxPrivate::PPV_ARGS_CHECK(static_cast<IType*>(*pType)), \
127 reinterpret_cast<void**>(pType))
128
129 #endif // _WX_MSW_PRIVATE_COMPTR_H_
130