]> git.tdb.fi Git - ext/openal.git/blob - common/comptr.h
Import OpenAL Soft 1.23.1 sources
[ext/openal.git] / common / comptr.h
1 #ifndef COMMON_COMPTR_H
2 #define COMMON_COMPTR_H
3
4 #include <cstddef>
5 #include <utility>
6
7 #include "opthelpers.h"
8
9
10 template<typename T>
11 class ComPtr {
12     T *mPtr{nullptr};
13
14 public:
15     ComPtr() noexcept = default;
16     ComPtr(const ComPtr &rhs) : mPtr{rhs.mPtr} { if(mPtr) mPtr->AddRef(); }
17     ComPtr(ComPtr&& rhs) noexcept : mPtr{rhs.mPtr} { rhs.mPtr = nullptr; }
18     ComPtr(std::nullptr_t) noexcept { }
19     explicit ComPtr(T *ptr) noexcept : mPtr{ptr} { }
20     ~ComPtr() { if(mPtr) mPtr->Release(); }
21
22     ComPtr& operator=(const ComPtr &rhs)
23     {
24         if(!rhs.mPtr)
25         {
26             if(mPtr)
27                 mPtr->Release();
28             mPtr = nullptr;
29         }
30         else
31         {
32             rhs.mPtr->AddRef();
33             try {
34                 if(mPtr)
35                     mPtr->Release();
36                 mPtr = rhs.mPtr;
37             }
38             catch(...) {
39                 rhs.mPtr->Release();
40                 throw;
41             }
42         }
43         return *this;
44     }
45     ComPtr& operator=(ComPtr&& rhs)
46     {
47         if(&rhs != this) LIKELY
48         {
49             if(mPtr) mPtr->Release();
50             mPtr = std::exchange(rhs.mPtr, nullptr);
51         }
52         return *this;
53     }
54
55     explicit operator bool() const noexcept { return mPtr != nullptr; }
56
57     T& operator*() const noexcept { return *mPtr; }
58     T* operator->() const noexcept { return mPtr; }
59     T* get() const noexcept { return mPtr; }
60     T** getPtr() noexcept { return &mPtr; }
61
62     T* release() noexcept { return std::exchange(mPtr, nullptr); }
63
64     void swap(ComPtr &rhs) noexcept { std::swap(mPtr, rhs.mPtr); }
65     void swap(ComPtr&& rhs) noexcept { std::swap(mPtr, rhs.mPtr); }
66 };
67
68 #endif