Sane C++ Libraries
C++ Platform Abstraction Libraries
UniqueHandle.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/TypeTraits.h" // ReturnType<T>
5
6namespace SC
7{
10
16
65template <typename Definition>
67{
68 using Handle = typename Definition::Handle;
69 using CloseReturnType = typename TypeTraits::ReturnType<decltype(Definition::releaseHandle)>::type;
70
71 static constexpr Handle Invalid = Definition::Invalid;
72
73 UniqueHandle() = default;
74 UniqueHandle(const UniqueHandle& v) = delete;
75 UniqueHandle& operator=(const UniqueHandle& other) = delete;
76 UniqueHandle(UniqueHandle&& v) : handle(v.handle) { v.detach(); }
77 UniqueHandle(const Handle& externalHandle) : handle(externalHandle) {}
78 ~UniqueHandle() { (void)close(); }
79
83 [[nodiscard]] CloseReturnType assign(UniqueHandle&& other)
84 {
85 if (other.handle == handle)
86 return CloseReturnType(false);
87 if (close())
88 {
89 handle = other.handle;
90 other.detach();
91 return CloseReturnType(true);
92 }
93 return CloseReturnType(false);
94 }
95
99 [[nodiscard]] CloseReturnType assign(const Handle& externalHandle)
100 {
101 if (handle == externalHandle)
102 return CloseReturnType(false);
103 if (close())
104 {
105 handle = externalHandle;
106 return CloseReturnType(true);
107 }
108 return CloseReturnType(false);
109 }
110
111 UniqueHandle& operator=(UniqueHandle&& other)
112 {
113 (void)(assign(forward<UniqueHandle>(other)));
114 return *this;
115 }
116
119 [[nodiscard]] bool isValid() const { return handle != Invalid; }
120
122 void detach() { handle = Invalid; }
123
128 [[nodiscard]] CloseReturnType get(Handle& outHandle, CloseReturnType invalidReturnType) const
129 {
130 if (isValid())
131 {
132 outHandle = handle;
133 return CloseReturnType(true);
134 }
135 return invalidReturnType;
136 }
137
140 [[nodiscard]] CloseReturnType close()
141 {
142 if (isValid())
143 {
144 Handle handleCopy = handle;
145 detach();
146 return Definition::releaseHandle(handleCopy);
147 }
148 return CloseReturnType(true);
149 }
150
151 protected:
152 Handle handle = Invalid;
153};
154
156
157} // namespace SC
ReturnType extracts the return type from different forms of function types.
Definition: TypeTraits.h:50
Move only handle that has a special tag value flagging its invalid state.
Definition: UniqueHandle.h:67
CloseReturnType get(Handle &outHandle, CloseReturnType invalidReturnType) const
Extracts the native operating system handle out.
Definition: UniqueHandle.h:128
CloseReturnType assign(const Handle &externalHandle)
Copy assigns another UniqueHandle to this object, eventually closing existing handle.
Definition: UniqueHandle.h:99
CloseReturnType assign(UniqueHandle &&other)
Move assigns another UniqueHandle to this object, eventually closing existing handle.
Definition: UniqueHandle.h:83
CloseReturnType close()
Closes the handle by calling its OS specific close function.
Definition: UniqueHandle.h:140
void detach()
Detaches (sets to invalid) current handle, without closing it.
Definition: UniqueHandle.h:122
bool isValid() const
Check if current handle is valid.
Definition: UniqueHandle.h:119