summaryrefslogtreecommitdiff
path: root/src/player/backends/utility/com_ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/player/backends/utility/com_ptr.h')
-rw-r--r--src/player/backends/utility/com_ptr.h148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/player/backends/utility/com_ptr.h b/src/player/backends/utility/com_ptr.h
new file mode 100644
index 0000000..23534b2
--- /dev/null
+++ b/src/player/backends/utility/com_ptr.h
@@ -0,0 +1,148 @@
+# ifndef __TD__COM_PTR_H__
+# define __TD__COM_PTR_H__
+# pragma once
+
+template <typename T>
+class com_ptr
+{
+//private:
+// typedef void (com_ptr::*bool_type)() const;
+// void safe_bool() const {}
+//
+//
+public:
+ com_ptr():
+ _ptr(nullptr)
+ {
+ }
+
+ com_ptr(T* ptr, bool add_ref = false):
+ _ptr(ptr)
+ {
+ if (_ptr && add_ref)
+ _ptr->AddRef();
+ }
+
+ com_ptr(const com_ptr& rhs):
+ _ptr(rhs._ptr)
+ {
+ if (_ptr)
+ _ptr->AddRef();
+ }
+
+ com_ptr(com_ptr&& rhs):
+ _ptr(rhs._ptr)
+ {
+ rhs._ptr = nullptr;
+ }
+
+ template <typename U>
+ com_ptr(const com_ptr<U>& rhs):
+ _ptr(rhs._ptr)
+ {
+ if (_ptr)
+ _ptr->AddRef();
+ }
+
+ ~com_ptr()
+ {
+ if (_ptr)
+ _ptr->Release();
+ }
+
+ com_ptr& operator = (const com_ptr& rhs)
+ {
+ com_ptr(rhs).swap(*this);
+ return *this;
+ }
+
+ com_ptr& operator = (com_ptr&& rhs)
+ {
+ com_ptr(static_cast<com_ptr&&>(rhs)).swap(*this);
+ return *this;
+ }
+
+ template <typename U>
+ com_ptr& operator = (const com_ptr<U>& rhs)
+ {
+ com_ptr(rhs).swap(*this):
+ return *this;
+ }
+
+ com_ptr& operator = (T* rhs)
+ {
+ com_ptr(rhs).swap(*this);
+ return *this;
+ }
+
+ //operator bool_type() const
+ //{
+ // return _ptr ? &com_ptr::safe_bool : nullptr;
+ //}
+
+ //bool_type operator !() const
+ //{
+ // return !((bool_type)*this);
+ //}
+
+ void reset()
+ {
+ com_ptr().swap(*this);
+ }
+
+ void reset(T* rhs)
+ {
+ com_ptr(rhs).swap(*this);
+ }
+
+ void reset(T* rhs, bool add_ref)
+ {
+ com_ptr(rhs, add_ref).swap(*this);
+ }
+
+ T* get() const
+ {
+ return _ptr;
+ }
+
+ T* detach()
+ {
+ auto result = _ptr;
+ _ptr = nullptr;
+ return result;
+ }
+
+ void swap(com_ptr& rhs)
+ {
+ T* temp = rhs._ptr;
+ rhs._ptr = _ptr;
+ _ptr = temp;
+ }
+
+ T& operator * () const { return *_ptr; }
+ T* operator -> () const { return _ptr; }
+
+ operator T* () const { return _ptr; }
+ T** operator & () { return &_ptr; }
+
+private:
+ T* _ptr;
+};
+
+template <typename T, typename U> inline bool operator==(const com_ptr<T>& a, const com_ptr<U>& b) { return a.get() == b.get(); }
+template <typename T, typename U> inline bool operator!=(const com_ptr<T>& a, const com_ptr<U>& b) { return a.get() != b.get(); }
+template <typename T, typename U> inline bool operator==(const com_ptr<T>& a, U* b) { return a.get() == b; }
+template <typename T, typename U> inline bool operator!=(const com_ptr<T>& a, U* b) { return a.get() != b; }
+template <typename T, typename U> inline bool operator==(T* a, const com_ptr<U>& b) { return a == b.get(); }
+template <typename T, typename U> inline bool operator!=(T* a, const com_ptr<U>& b) { return a != b.get(); }
+template <typename T> inline bool operator==(const com_ptr<T>& p, std::nullptr_t) { return p.get() == nullptr; }
+template <typename T> inline bool operator==(std::nullptr_t, const com_ptr<T>& p) { return p.get() == nullptr; }
+template <typename T> inline bool operator!=(const com_ptr<T>& p, std::nullptr_t) { return p.get() != nullptr; }
+template <typename T> inline bool operator!=(std::nullptr_t, const com_ptr<T>& p) { return p.get() != nullptr; }
+template <typename T> inline bool operator<(const com_ptr<T>& a, const com_ptr<T>& b) { return std::less<T*>()(a.get(), b.get()); }
+template <typename T> inline bool operator<=(const com_ptr<T>& a, const com_ptr<T>& b) { return std::less_equal<T*>()(a.get(), b.get()); }
+template <typename T> inline bool operator>(const com_ptr<T>& a, const com_ptr<T>& b) { return std::greater<T*>()(a.get(), b.get()); }
+template <typename T> inline bool operator>=(const com_ptr<T>& a, const com_ptr<T>& b) { return std::greater_equal<T*>()(a.get(), b.get()); }
+template <typename T> void swap(com_ptr<T> & lhs, com_ptr<T> & rhs) { lhs.swap(rhs); }
+
+# endif // __TD__COM_PTR_H__ \ No newline at end of file