#ifndef COMMON_COMPTR_H
|
|
#define COMMON_COMPTR_H
|
|
|
|
#include <cstddef>
|
|
#include <utility>
|
|
|
|
#include "opthelpers.h"
|
|
|
|
|
|
template<typename T>
|
|
class ComPtr {
|
|
T *mPtr{nullptr};
|
|
|
|
public:
|
|
ComPtr() noexcept = default;
|
|
ComPtr(const ComPtr &rhs) : mPtr{rhs.mPtr} { if(mPtr) mPtr->AddRef(); }
|
|
ComPtr(ComPtr&& rhs) noexcept : mPtr{rhs.mPtr} { rhs.mPtr = nullptr; }
|
|
ComPtr(std::nullptr_t) noexcept { }
|
|
explicit ComPtr(T *ptr) noexcept : mPtr{ptr} { }
|
|
~ComPtr() { if(mPtr) mPtr->Release(); }
|
|
|
|
ComPtr& operator=(const ComPtr &rhs)
|
|
{
|
|
if(!rhs.mPtr)
|
|
{
|
|
if(mPtr)
|
|
mPtr->Release();
|
|
mPtr = nullptr;
|
|
}
|
|
else
|
|
{
|
|
rhs.mPtr->AddRef();
|
|
try {
|
|
if(mPtr)
|
|
mPtr->Release();
|
|
mPtr = rhs.mPtr;
|
|
}
|
|
catch(...) {
|
|
rhs.mPtr->Release();
|
|
throw;
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
ComPtr& operator=(ComPtr&& rhs)
|
|
{
|
|
if(likely(&rhs != this))
|
|
{
|
|
if(mPtr) mPtr->Release();
|
|
mPtr = std::exchange(rhs.mPtr, nullptr);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
explicit operator bool() const noexcept { return mPtr != nullptr; }
|
|
|
|
T& operator*() const noexcept { return *mPtr; }
|
|
T* operator->() const noexcept { return mPtr; }
|
|
T* get() const noexcept { return mPtr; }
|
|
T** getPtr() noexcept { return &mPtr; }
|
|
|
|
T* release() noexcept { return std::exchange(mPtr, nullptr); }
|
|
|
|
void swap(ComPtr &rhs) noexcept { std::swap(mPtr, rhs.mPtr); }
|
|
void swap(ComPtr&& rhs) noexcept { std::swap(mPtr, rhs.mPtr); }
|
|
};
|
|
|
|
#endif
|