diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-15 19:27:53 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-01-15 19:27:53 +0100 |
commit | 785293f4bf1beec65d23be0612e545e4c26ec366 (patch) | |
tree | f250c34d82977116498b8049c8055fc3981478ab /compat/safe-ptr.hpp | |
parent | a5acc700d6a3a9b050864cf78a0f9f2305babdff (diff) |
b
Diffstat (limited to 'compat/safe-ptr.hpp')
-rw-r--r-- | compat/safe-ptr.hpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/compat/safe-ptr.hpp b/compat/safe-ptr.hpp new file mode 100644 index 00000000..f6b0b260 --- /dev/null +++ b/compat/safe-ptr.hpp @@ -0,0 +1,61 @@ +#pragma once +#include "compat/assert.hpp" +#include "compat/defs.hpp" +#include <type_traits> +#include <Corrade/Tags.h> +#include <Corrade/Utility/Move.h> + +namespace floormat { + +template<typename T> +class safe_ptr final +{ + T* ptr; + +public: + template<typename... Ts> + requires requires (Ts&&... xs) { + new T{Utility::forward<Ts>(xs)...}; + } + safe_ptr(InPlaceInitT, Ts&&... args) noexcept: + ptr{new T{Utility::forward<Ts>(args)...}} + {} + + explicit safe_ptr(T*&& ptr) noexcept: ptr{ptr} + { + fm_assert(ptr != nullptr); + } + + ~safe_ptr() noexcept + { + if (ptr) + delete ptr; + ptr = (T*)-0xbadbabe; + } + + explicit safe_ptr(safe_ptr&& other) noexcept: ptr{other.ptr} + { + other.ptr = nullptr; + } + + safe_ptr& operator=(safe_ptr&& other) noexcept + { + fm_assert(this != &other); + if (ptr) + delete ptr; + ptr = other.ptr; + other.ptr = nullptr; + return *this; + } + + fm_DECLARE_DELETED_COPY_ASSIGNMENT(safe_ptr); + + //explicit operator bool() const noexcept { return ptr != nullptr; } + + const T& operator*() const noexcept { return *ptr; } + T& operator*() noexcept { return *ptr; } + const T* operator->() const noexcept { return ptr; } + T* operator->() noexcept { return ptr; } +}; + +} // namespace floormat |