MiKTeX 26.5-next
A scalable TeX distribution
Loading...
Searching...
No Matches
AutoResource.h
1/* miktex/Core/AutoResource.h: -*- C++ -*-
2
3 Copyright (C) 1996-2020 Christian Schenk
4
5 This file is part of the MiKTeX Core Library.
6
7 The MiKTeX Core Library is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2, or
10 (at your option) any later version.
11
12 The MiKTeX Core Library is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with the MiKTeX Core Library; if not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22#pragma once
23
24#if !defined(A089FEF06254514BA063DED44B70E66F)
25#define A089FEF06254514BA063DED44B70E66F
26
27#include <miktex/Core/config.h>
28
29#include <cstdio>
30#include <cstdlib>
31
32#include <exception>
33
34#include <miktex/Helpers>
35
36#include "Session.h"
37
38MIKTEX_CORE_BEGIN_NAMESPACE;
39
40template<class HandleType> HandleType InvalidHandleValue()
41{
42 return 0;
43}
44
45template<class HandleType, class Destroyer> class AutoResource
46{
47public:
48 AutoResource() = default;
49
50public:
51 AutoResource(const AutoResource& other) = delete;
52
53public:
54 AutoResource& operator=(const AutoResource& other) = delete;
55
56public:
57 AutoResource(AutoResource&& other) = delete;
58
59public:
60 AutoResource& operator=(AutoResource&& other) = delete;
61
62public:
63 virtual ~AutoResource() noexcept
64 {
65 try
66 {
67 Reset();
68 }
69 catch (const std::exception&)
70 {
71 }
72 }
73
74public:
75 AutoResource(HandleType handle) :
76 handle(handle)
77 {
78 }
79
80public:
81 HandleType Get() const
82 {
83 return handle;
84 }
85
86public:
87 void Attach(HandleType handle)
88 {
89 this->handle = handle;
90 }
91
92public:
93 HandleType Detach()
94 {
95 HandleType handle = Get();
96 Attach(InvalidHandleValue<HandleType>());
97 return handle;
98 }
99
100public:
101 void Reset(HandleType handle)
102 {
103 if (Get() != InvalidHandleValue<HandleType>())
104 {
105 Destroyer() (Detach());
106 }
107 Attach(handle);
108 }
109
110public:
111 void Reset()
112 {
113 Reset(InvalidHandleValue<HandleType>());
114 }
115
116public:
117 HandleType* operator&()
118 {
119 return &handle;
120 }
121
122private:
123 HandleType handle = InvalidHandleValue<HandleType>();
124};
125
126template<class HandleType1, class HandleType2, class Destroyer> class AutoResource2
127{
128public:
129 AutoResource2() = default;
130
131public:
132 AutoResource2(const AutoResource2& other) = delete;
133
134public:
135 AutoResource2& operator=(const AutoResource2& other) = delete;
136
137public:
138 AutoResource2(AutoResource2&& other) = delete;
139
140public:
141 AutoResource2& operator=(AutoResource2&& other) = delete;
142
143public:
144 virtual ~AutoResource2()
145 {
146 try
147 {
148 Reset();
149 }
150 catch (const std::exception&)
151 {
152 }
153 }
154
155public:
156 AutoResource2(HandleType1 handle1, HandleType2 handle2 = InvalidHandleValue<HandleType2>()) :
157 handle1(handle1),
158 handle2(handle2)
159 {
160 }
161
162public:
163 HandleType2 Get() const
164 {
165 return handle2;
166 }
167
168public:
169 void Attach(HandleType1 handle1, HandleType2 handle2)
170 {
171 this->handle1 = handle1;
172 this->handle2 = handle2;
173 }
174
175public:
176 HandleType2 Detach()
177 {
178 HandleType2 handle2 = Get();
179 Attach(InvalidHandleValue<HandleType1>(), InvalidHandleValue<HandleType2>());
180 return handle2;
181 }
182
183public:
184 void Reset()
185 {
186 if (Get() != InvalidHandleValue<HandleType2>())
187 {
188 HandleType1 handle1 = this->handle1;
189 HandleType2 handle2 = this->handle2;
190 this->handle1 = InvalidHandleValue<HandleType1>();
191 this->handle2 = InvalidHandleValue<HandleType2>();
192 Destroyer() (handle1, handle2);
193 }
194 }
195
196public:
197 HandleType2* operator&() const
198 {
199 return &handle2;
200 }
201
202private:
203 HandleType1 handle1 = InvalidHandleValue<HandleType1>();
204
205private:
206 HandleType2 handle2 = InvalidHandleValue<HandleType2>();
207};
208
210{
211public:
212 void operator()(FILE* file) const
213 {
214 if (fclose(file) != 0)
215 {
216 MIKTEX_FATAL_CRT_ERROR("fclose");
217 }
218 }
219};
220
221typedef AutoResource<FILE*, fclose_> AutoFILE;
222
223struct free_
224{
225public:
226 void operator()(void* ptr) const
227 {
228 free(ptr);
229 }
230};
231
232typedef AutoResource<void*, free_> AutoMemoryPointer;
233
234template<class Func> struct AutoFunc
235{
236public:
237 AutoFunc() = default;
238
239public:
240 AutoFunc(const AutoFunc& other) = default;
241
242public:
243 AutoFunc& operator=(const AutoFunc& other) = default;
244
245public:
246 AutoFunc(AutoFunc&& other) = default;
247
248public:
249 AutoFunc& operator=(AutoFunc&& other) = default;
250
251public:
252 AutoFunc(Func func) :
253 func(func)
254 {
255 }
256
257public:
258 ~AutoFunc()
259 {
260 try
261 {
262 func();
263 }
264 catch (const std::exception&)
265 {
266 }
267 }
268
269private:
270 Func func;
271};
272
273template<class Func> AutoFunc<Func> CreateAutoFunc(Func func)
274{
275 return AutoFunc<Func>(func);
276}
277
278#define MIKTEX_AUTO(x) auto MIKTEX_UNIQUE(bbf09dd97db04f579f1c386c16f7fd38) = MiKTeX::Core::CreateAutoFunc([&](){x;})
279
280MIKTEX_CORE_END_NAMESPACE;
281
282#endif
Definition AutoResource.h:46
Definition AutoResource.h:235
Definition AutoResource.h:210
Definition AutoResource.h:224