summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/ScopeGuard.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/utils/ScopeGuard.h')
-rw-r--r--xbmc/utils/ScopeGuard.h111
1 files changed, 111 insertions, 0 deletions
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 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#pragma once
10
11#include <functional>
12
13namespace KODI
14{
15namespace UTILS
16{
17
18/*! \class CScopeGuard
19 \brief Generic scopeguard designed to handle any type of handle
20
21 This is not necessary but recommended to cut down on some typing
22 using CSocketHandle = CScopeGuard<SOCKET, INVALID_SOCKET, closesocket>;
23
24 CSocketHandle sh(closesocket, open(thingy));
25 */
26template<typename Handle, Handle invalid, typename Deleter>
27class CScopeGuard
28{
29
30public:
31
32 CScopeGuard(std::function<Deleter> del, Handle handle = invalid)
33 : m_handle{handle}
34 , m_deleter{del}
35 { };
36
37 ~CScopeGuard() noexcept
38 {
39 reset();
40 }
41
42 operator Handle() const
43 {
44 return m_handle;
45 }
46
47 operator bool() const
48 {
49 return m_handle != invalid;
50 }
51
52 /*! \brief attach a new handle to this instance, if there's
53 already a handle it will be closed.
54
55 \param[in] handle The handle to manage
56 */
57 void attach(Handle handle)
58 {
59 reset();
60
61 m_handle = handle;
62 }
63
64 /*! \brief release the managed handle so that it won't be auto closed
65
66 \return The handle being managed by the guard
67 */
68 Handle release()
69 {
70 Handle h = m_handle;
71 m_handle = invalid;
72 return h;
73 }
74
75 /*! \brief reset the instance, closing any managed handle and setting it to invalid
76 */
77 void reset()
78 {
79 if (m_handle != invalid)
80 {
81 m_deleter(m_handle);
82 m_handle = invalid;
83 }
84 }
85
86 //Disallow default construction and copying
87 CScopeGuard() = delete;
88 CScopeGuard(const CScopeGuard& rhs) = delete;
89 CScopeGuard& operator= (const CScopeGuard& rhs) = delete;
90
91 //Allow moving
92 CScopeGuard(CScopeGuard&& rhs)
93 : m_handle{std::move(rhs.m_handle)}, m_deleter{std::move(rhs.m_deleter)}
94 {
95 // Bring moved-from object into released state so destructor will not do anything
96 rhs.release();
97 }
98 CScopeGuard& operator=(CScopeGuard&& rhs)
99 {
100 attach(rhs.release());
101 m_deleter = std::move(rhs.m_deleter);
102 return *this;
103 }
104
105private:
106 Handle m_handle;
107 std::function<Deleter> m_deleter;
108};
109
110}
111}