Skip to content

Commit d65b530

Browse files
Fea, 添加YY::Handle智能句柄包装器
1 parent f320462 commit d65b530

File tree

3 files changed

+304
-0
lines changed

3 files changed

+304
-0
lines changed

include/YY/Base/Utils/Handle.h

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
#pragma once
2+
#include <YY/Base/YY.h>
3+
#include <type_traits>
4+
5+
#pragma pack(push, __YY_PACKING)
6+
7+
namespace YY
8+
{
9+
namespace Base
10+
{
11+
namespace Utils
12+
{
13+
#if defined(_WIN32)
14+
struct Win32HandleTraits
15+
{
16+
using HandleType = HANDLE;
17+
18+
static constexpr HandleType khInvalidHandle = NULL;
19+
20+
static inline HRESULT __YYAPI CloseHandle(HandleType _hHandle)
21+
{
22+
if(!::CloseHandle(_hHandle))
23+
return __HRESULT_FROM_WIN32(GetLastError());
24+
25+
return S_OK;
26+
}
27+
28+
// 可选实现 DuplicateHandle 方法以支持复制句柄功能
29+
static inline HRESULT __YYAPI DuplicateHandle(HandleType _hHandle, HandleType* _phNewHandle)
30+
{
31+
if(!::DuplicateHandle(GetCurrentProcess(), _hHandle, GetCurrentProcess(), _phNewHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
32+
return __HRESULT_FROM_WIN32(GetLastError());
33+
34+
return S_OK;
35+
}
36+
};
37+
#endif
38+
39+
/// <summary>
40+
/// 原始句柄的简易包装类。注意此类不可拷贝,如果需要拷贝请确保 HandleTraits 定义了 DuplicateHandle 方法。
41+
/// </summary>
42+
/// <typeparam name="HandleTraits">需要定义HandleType等信息,可参考 Win32HandleTraits 实现。</typeparam>
43+
template<typename HandleTraits, typename = void>
44+
class Handle
45+
{
46+
public:
47+
using HandleType = typename HandleTraits::HandleType;
48+
49+
static constexpr HandleType khInvalidHandle = HandleTraits::khInvalidHandle;
50+
51+
private:
52+
HandleType hHandle = khInvalidHandle;
53+
54+
public:
55+
constexpr Handle() noexcept = default;
56+
57+
constexpr explicit Handle(HandleType _hHandle) noexcept
58+
: hHandle(_hHandle)
59+
{
60+
}
61+
62+
Handle(const Handle& _hHandle) = delete;
63+
Handle& __YYAPI operator=(const Handle& _hOther) = delete;
64+
65+
constexpr Handle(Handle&& _hHandle) noexcept
66+
: hHandle(_hHandle.Detach())
67+
{
68+
}
69+
70+
~Handle()
71+
{
72+
Release();
73+
}
74+
75+
constexpr bool __YYAPI IsValid() const noexcept
76+
{
77+
return hHandle != khInvalidHandle;
78+
}
79+
80+
constexpr bool __YYAPI IsInvalid() const noexcept
81+
{
82+
return hHandle == khInvalidHandle;
83+
}
84+
85+
constexpr HandleType __YYAPI Get() const noexcept
86+
{
87+
return hHandle;
88+
}
89+
90+
_Ret_notnull_ HandleType* __YYAPI ReleaseAndGetAddressOf()
91+
{
92+
Release();
93+
return &hHandle;
94+
}
95+
96+
void __YYAPI Attach(HandleType _hHandle) noexcept
97+
{
98+
if (hHandle == _hHandle)
99+
return;
100+
101+
Release();
102+
hHandle = _hHandle;
103+
}
104+
105+
constexpr HandleType __YYAPI Detach() noexcept
106+
{
107+
HandleType _hHandle = hHandle;
108+
hHandle = khInvalidHandle;
109+
return _hHandle;
110+
}
111+
112+
void __YYAPI Release()
113+
{
114+
if (!IsValid())
115+
return;
116+
117+
HandleTraits::CloseHandle(hHandle);
118+
hHandle = khInvalidHandle;
119+
}
120+
121+
Handle& __YYAPI operator=(HandleType _hOther)
122+
{
123+
Attach(_hOther);
124+
return *this;
125+
}
126+
127+
Handle& __YYAPI operator=(Handle&& _hOther) noexcept
128+
{
129+
Attach(_hOther.Detach());
130+
return *this;
131+
}
132+
133+
constexpr bool __YYAPI operator==(const Handle& _hOther) const noexcept
134+
{
135+
return hHandle == _hOther.hHandle;
136+
}
137+
138+
constexpr bool __YYAPI operator==(HandleType _hOther) const noexcept
139+
{
140+
return hHandle == _hOther;
141+
}
142+
143+
constexpr bool __YYAPI operator!=(const Handle& _hOther) const noexcept
144+
{
145+
return hHandle != _hOther.hHandle;
146+
}
147+
148+
constexpr bool __YYAPI operator!=(HandleType _hOther) const noexcept
149+
{
150+
return hHandle != _hOther;
151+
}
152+
};
153+
154+
/// <summary>
155+
/// 原始句柄的简易包装类。并且允许复制句柄。
156+
/// </summary>
157+
/// <typeparam name="HandleTraits">需要定义HandleType等信息,可参考 Win32HandleTraits 实现。</typeparam>
158+
template<typename HandleTraits>
159+
class Handle<HandleTraits, std::void_t<decltype(&HandleTraits::DuplicateHandle)>>
160+
{
161+
public:
162+
using HandleType = typename HandleTraits::HandleType;
163+
164+
static constexpr HandleType khInvalidHandle = HandleTraits::khInvalidHandle;
165+
166+
private:
167+
HandleType hHandle = khInvalidHandle;
168+
169+
public:
170+
constexpr Handle() noexcept = default;
171+
172+
constexpr explicit Handle(HandleType _hHandle) noexcept
173+
: hHandle(_hHandle)
174+
{
175+
}
176+
177+
Handle(const Handle& _hHandle)
178+
: hHandle(_hHandle.Clone())
179+
{
180+
}
181+
182+
constexpr Handle(Handle&& _hHandle) noexcept
183+
: hHandle(_hHandle.Detach())
184+
{
185+
}
186+
187+
~Handle()
188+
{
189+
Release();
190+
}
191+
192+
constexpr bool __YYAPI IsValid() const noexcept
193+
{
194+
return hHandle != khInvalidHandle;
195+
}
196+
197+
constexpr bool __YYAPI IsInvalid() const noexcept
198+
{
199+
return hHandle == khInvalidHandle;
200+
}
201+
202+
constexpr HandleType __YYAPI Get() const noexcept
203+
{
204+
return hHandle;
205+
}
206+
207+
_Ret_notnull_ HandleType* __YYAPI GetAddressOf()
208+
{
209+
return &hHandle;
210+
}
211+
212+
_Ret_notnull_ HandleType* __YYAPI ReleaseAndGetAddressOf()
213+
{
214+
Release();
215+
return &hHandle;
216+
}
217+
218+
void __YYAPI Attach(HandleType _hHandle) noexcept
219+
{
220+
if(hHandle == _hHandle)
221+
return;
222+
223+
Release();
224+
hHandle = _hHandle;
225+
}
226+
227+
constexpr HandleType __YYAPI Detach() noexcept
228+
{
229+
HandleType _hHandle = hHandle;
230+
hHandle = khInvalidHandle;
231+
return _hHandle;
232+
}
233+
234+
HandleType __YYAPI Clone() const
235+
{
236+
if(!IsValid())
237+
return khInvalidHandle;
238+
239+
HandleType _hNewHandle = khInvalidHandle;
240+
if (SUCCEEDED(HandleTraits::DuplicateHandle(hHandle, &_hNewHandle)))
241+
return _hNewHandle;
242+
243+
return khInvalidHandle;
244+
}
245+
246+
void __YYAPI Release()
247+
{
248+
if (!IsValid())
249+
return;
250+
251+
HandleTraits::CloseHandle(hHandle);
252+
hHandle = khInvalidHandle;
253+
}
254+
255+
Handle& __YYAPI operator=(const Handle& _hOther)
256+
{
257+
Attach(_hOther.Clone());
258+
return *this;
259+
}
260+
261+
Handle& __YYAPI operator=(HandleType _hOther)
262+
{
263+
Attach(_hOther);
264+
return *this;
265+
}
266+
267+
Handle& __YYAPI operator=(Handle&& _hOther) noexcept
268+
{
269+
Attach(_hOther.Detach());
270+
return *this;
271+
}
272+
273+
constexpr bool __YYAPI operator==(const Handle& _hOther) const noexcept
274+
{
275+
return hHandle == _hOther.hHandle;
276+
}
277+
278+
constexpr bool __YYAPI operator==(HandleType _hOther) const noexcept
279+
{
280+
return hHandle == _hOther;
281+
}
282+
283+
constexpr bool __YYAPI operator!=(const Handle& _hOther) const noexcept
284+
{
285+
return hHandle != _hOther.hHandle;
286+
}
287+
288+
constexpr bool __YYAPI operator!=(HandleType _hOther) const noexcept
289+
{
290+
return hHandle != _hOther;
291+
}
292+
};
293+
}
294+
}
295+
296+
using namespace YY::Base::Utils;
297+
298+
} // namespace YY
299+
300+
#pragma pack(pop)

src/YY.Base.vcxitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<ItemGroup>
6464
<ClInclude Include="$(MSBuildThisFileDirectory)..\include\YY\Base\Time\TimeZone.h" />
6565
<ClInclude Include="$(MSBuildThisFileDirectory)..\include\YY\Base\Utils\AutoCleanup.h" />
66+
<ClInclude Include="$(MSBuildThisFileDirectory)..\include\YY\Base\Utils\Handle.h" />
6667
<ClInclude Include="$(MSBuildThisFileDirectory)\..\include\YY\Base\Containers\Array.h" />
6768
<ClInclude Include="$(MSBuildThisFileDirectory)\..\include\YY\Base\Containers\Span.h" />
6869
<ClInclude Include="$(MSBuildThisFileDirectory)\..\include\YY\Base\Containers\BitMap.h" />

src/YY.Base.vcxitems.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@
302302
<ClInclude Include="$(MSBuildThisFileDirectory)..\include\YY\Base\Time\TimeZone.h">
303303
<Filter>头文件\YY\Base\Time</Filter>
304304
</ClInclude>
305+
<ClInclude Include="$(MSBuildThisFileDirectory)..\include\YY\Base\Utils\Handle.h">
306+
<Filter>头文件\YY\Base\Utils</Filter>
307+
</ClInclude>
305308
</ItemGroup>
306309
<ItemGroup>
307310
<Natvis Include="$(MSBuildThisFileDirectory)\YY.Base.natvis">

0 commit comments

Comments
 (0)