1 #ifndef COMMON_COMPTR_H
2 #define COMMON_COMPTR_H
10 #define WIN32_LEAN_AND_MEAN
17 ComWrapper(void *reserved
, DWORD coinit
)
18 : mStatus
{CoInitializeEx(reserved
, coinit
)}
20 ComWrapper(DWORD coinit
=COINIT_APARTMENTTHREADED
)
21 : mStatus
{CoInitializeEx(nullptr, coinit
)}
23 ComWrapper(ComWrapper
&& rhs
) { mStatus
= std::exchange(rhs
.mStatus
, E_FAIL
); }
24 ComWrapper(const ComWrapper
&) = delete;
25 ~ComWrapper() { if(SUCCEEDED(mStatus
)) CoUninitialize(); }
27 ComWrapper
& operator=(ComWrapper
&& rhs
)
29 if(SUCCEEDED(mStatus
))
31 mStatus
= std::exchange(rhs
.mStatus
, E_FAIL
);
34 ComWrapper
& operator=(const ComWrapper
&) = delete;
37 HRESULT
status() const noexcept
{ return mStatus
; }
38 explicit operator bool() const noexcept
{ return SUCCEEDED(status()); }
42 if(SUCCEEDED(mStatus
))
49 template<typename T
> /* NOLINTNEXTLINE(clazy-rule-of-three) False positive */
51 using element_type
= T
;
53 static constexpr bool RefIsNoexcept
{noexcept(std::declval
<T
&>().AddRef())
54 && noexcept(std::declval
<T
&>().Release())};
56 ComPtr() noexcept
= default;
57 ComPtr(const ComPtr
&rhs
) noexcept(RefIsNoexcept
) : mPtr
{rhs
.mPtr
}
58 { if(mPtr
) mPtr
->AddRef(); }
59 ComPtr(ComPtr
&& rhs
) noexcept
: mPtr
{rhs
.mPtr
} { rhs
.mPtr
= nullptr; }
60 ComPtr(std::nullptr_t
) noexcept
{ }
61 explicit ComPtr(T
*ptr
) noexcept
: mPtr
{ptr
} { }
62 ~ComPtr() { if(mPtr
) mPtr
->Release(); }
64 /* NOLINTNEXTLINE(bugprone-unhandled-self-assignment) Yes it is. */
65 ComPtr
& operator=(const ComPtr
&rhs
) noexcept(RefIsNoexcept
)
67 if constexpr(RefIsNoexcept
)
69 if(rhs
.mPtr
) rhs
.mPtr
->AddRef();
70 if(mPtr
) mPtr
->Release();
77 if(mPtr
) mPtr
->Release();
82 ComPtr
& operator=(ComPtr
&& rhs
) noexcept(RefIsNoexcept
)
86 if(mPtr
) mPtr
->Release();
87 mPtr
= std::exchange(rhs
.mPtr
, nullptr);
92 void reset(T
*ptr
=nullptr) noexcept(RefIsNoexcept
)
94 if(mPtr
) mPtr
->Release();
98 explicit operator bool() const noexcept
{ return mPtr
!= nullptr; }
100 T
& operator*() const noexcept
{ return *mPtr
; }
101 T
* operator->() const noexcept
{ return mPtr
; }
102 T
* get() const noexcept
{ return mPtr
; }
104 T
* release() noexcept
{ return std::exchange(mPtr
, nullptr); }
106 void swap(ComPtr
&rhs
) noexcept
{ std::swap(mPtr
, rhs
.mPtr
); }
107 void swap(ComPtr
&& rhs
) noexcept
{ std::swap(mPtr
, rhs
.mPtr
); }