From be933ef2241d79558f91796cc5b3a161f72ebf9c Mon Sep 17 00:00:00 2001 From: manuel Date: Mon, 19 Oct 2020 00:52:24 +0200 Subject: sync with upstream --- xbmc/utils/ScopeGuard.h | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 xbmc/utils/ScopeGuard.h (limited to 'xbmc/utils/ScopeGuard.h') diff --git a/xbmc/utils/ScopeGuard.h b/xbmc/utils/ScopeGuard.h new file mode 100644 index 0000000..a1aa0a6 --- /dev/null +++ b/xbmc/utils/ScopeGuard.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include + +namespace KODI +{ +namespace UTILS +{ + +/*! \class CScopeGuard + \brief Generic scopeguard designed to handle any type of handle + + This is not necessary but recommended to cut down on some typing + using CSocketHandle = CScopeGuard; + + CSocketHandle sh(closesocket, open(thingy)); + */ +template +class CScopeGuard +{ + +public: + + CScopeGuard(std::function del, Handle handle = invalid) + : m_handle{handle} + , m_deleter{del} + { }; + + ~CScopeGuard() noexcept + { + reset(); + } + + operator Handle() const + { + return m_handle; + } + + operator bool() const + { + return m_handle != invalid; + } + + /*! \brief attach a new handle to this instance, if there's + already a handle it will be closed. + + \param[in] handle The handle to manage + */ + void attach(Handle handle) + { + reset(); + + m_handle = handle; + } + + /*! \brief release the managed handle so that it won't be auto closed + + \return The handle being managed by the guard + */ + Handle release() + { + Handle h = m_handle; + m_handle = invalid; + return h; + } + + /*! \brief reset the instance, closing any managed handle and setting it to invalid + */ + void reset() + { + if (m_handle != invalid) + { + m_deleter(m_handle); + m_handle = invalid; + } + } + + //Disallow default construction and copying + CScopeGuard() = delete; + CScopeGuard(const CScopeGuard& rhs) = delete; + CScopeGuard& operator= (const CScopeGuard& rhs) = delete; + + //Allow moving + CScopeGuard(CScopeGuard&& rhs) + : m_handle{std::move(rhs.m_handle)}, m_deleter{std::move(rhs.m_deleter)} + { + // Bring moved-from object into released state so destructor will not do anything + rhs.release(); + } + CScopeGuard& operator=(CScopeGuard&& rhs) + { + attach(rhs.release()); + m_deleter = std::move(rhs.m_deleter); + return *this; + } + +private: + Handle m_handle; + std::function m_deleter; +}; + +} +} -- cgit v1.2.3