#pragma once #include #include namespace hex { namespace impl { class AutoResetBase { public: virtual ~AutoResetBase() = default; private: friend void ImHexApi::System::impl::cleanup(); virtual void reset() = 0; }; } template class AutoReset : public impl::AutoResetBase { public: using Type = T; AutoReset() noexcept { try { ImHexApi::System::impl::addAutoResetObject(this); } catch (std::exception &e) { log::error("Failed to register AutoReset object: {}", e.what()); } } explicit(false) AutoReset(const T &value) : AutoReset() { m_value = value; m_valid = true; } explicit(false) AutoReset(T &&value) noexcept : AutoReset() { m_value = std::move(value); m_valid = true; } ~AutoReset() override { ImHexApi::System::impl::removeAutoResetObject(this); } T* operator->() { return &m_value; } const T* operator->() const { return &m_value; } T& operator*() { return m_value; } const T& operator*() const { return m_value; } operator T&() { return m_value; } operator const T&() const { return m_value; } AutoReset& operator=(const T &value) { m_value = value; m_valid = true; return *this; } AutoReset& operator=(T &&value) noexcept { m_value = std::move(value); m_valid = true; return *this; } [[nodiscard]] bool isValid() const { return m_valid; } private: void reset() override { if constexpr (requires(T t) { t.reset(); }) { m_value.reset(); } else if constexpr (requires(T t) { t.clear(); }) { m_value.clear(); } else if constexpr (std::is_pointer_v) { m_value = nullptr; // cppcheck-suppress nullPointer } else { m_value = { }; } m_valid = false; } private: bool m_valid = true; T m_value; }; }