YSTest: scope_guard.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

scope_guard.hpp
浏览该文件的文档.
1 /*
2 © 2015-2017 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
30 #ifndef YB_INC_ystdex_scope_guard_hpp_
31 #define YB_INC_ystdex_scope_guard_hpp_ 1
32
33 #include "utility.hpp" // for is_constructible, is_reference,
34 // is_nothrow_swappable, ystdex::vswap, std::declval, is_nothrow_copyable;
35 #include "base.h" // for noncopyable;
36 #include "placement.hpp" // for tagged_value;
37
38 namespace ystdex
39 {
40
46 template<typename _func, bool _bNoThrow = true>
47 struct guard
48 {
49 _func func;
50
52 template<typename... _tParams>
53 guard(_tParams&&... args)
54 ynoexcept(is_constructible<_func, _tParams&&...>::value)
55 : func(yforward(args)...)
56 {}
57 guard(guard&&) = default;
58 ~guard() ynoexcept_spec(!_bNoThrow)
59 {
60 func();
61 }
62
63 guard&
64 operator=(guard&&) = default;
65 };
66
73 template<typename _type, bool _bNoThrow = true, typename... _tParams>
75 guard<_type>
76 make_guard(_tParams&&... args) ynoexcept_spec(guard<_type, _bNoThrow>(
77 guard<_type, _bNoThrow>(yforward(args)...)))
78 {
79 return guard<_type, _bNoThrow>(yforward(args)...);
80 }
81 template<bool _bNoThrow = true, typename _type>
82 guard<_type>
83 make_guard(_type f)
84 ynoexcept_spec(guard<_type, _bNoThrow>(guard<_type, _bNoThrow>(f)))
85 {
86 return guard<_type, _bNoThrow>(f);
87 }
89
91
92 template<typename _tState = bool, bool _bNoThrow = true, typename _func>
93 guard<one_shot<_func, void, _tState>>
94 unique_guard(_func f, _tState s = {}) ynoexcept_spec(
95 guard<one_shot<_func, void, _tState>, _bNoThrow>(
96 guard<one_shot<_func, void, _tState>, _bNoThrow>(f)))
97 {
98 using guarded_type = one_shot<_func, void, _tState>;
99
100 return guard<guarded_type, _bNoThrow>(f, s);
101 }
102
103 template<typename _tRes, typename _tState = bool, bool _bNoThrow = true,
104 typename _func>
105 guard<one_shot<_func, _tRes, _tState>>
106 unique_state_guard(_func f, _tRes r = {}, _tState s = {}) ynoexcept_spec(
107 guard<one_shot<_func, _tRes, _tState>, _bNoThrow>(
108 guard<one_shot<_func, _tRes, _tState>, _bNoThrow>(f)))
109 {
110 using guarded_type = one_shot<_func, _tRes, _tState>;
111
112 return guard<guarded_type, _bNoThrow>(f, r, s);
113 }
114
116
117
122 template<typename _func, typename _type = void>
123 inline std::shared_ptr<_type>
124 share_guard(_func f, _type* p = {})
125 {
126 return ystdex::share_raw(p, f);
127 }
128
129
135 template<class _type>
137 yconstfn auto
138 dismiss(_type& gd) -> decltype(gd.dismiss())
139 {
140 return gd.dismiss();
141 }
142 template<typename _func, typename _tRes, typename _tState>
143 inline void
144 dismiss(const one_shot<_func, _tRes, _tState>& gd)
145 {
146 gd.fresh = {};
147 }
149 template<typename _func, bool _bNoThrow>
150 yconstfn auto
151 dismiss(guard<_func, _bNoThrow>& gd) -> decltype(dismiss(gd.func))
152 {
153 return dismiss(gd.func);
154 }
156
157
158 namespace details
159 {
160
162
163 template<typename _type, typename _tToken,
164 bool _bRef = is_reference<_tToken>::value>
165 struct state_guard_traits
166 {
168
169 static void
170 save(_tToken t, _type& val) ynoexcept_spec(t(true, val))
171 {
172 t(true, val);
173 }
174
175 static void
176 restore(_tToken t, _type& val) ynoexcept_spec(t(false, val))
177 {
178 t(false, val);
179 }
181 };
182
183 template<typename _type, typename _tToken>
184 struct state_guard_traits<_type, _tToken, true>
185 {
187
188 static void
189 save(_tToken t, _type& val) ynoexcept_spec(ystdex::vswap(val, t))
190 {
191 ystdex::vswap(val, t);
192 }
193
194 static void
195 restore(_tToken t, _type& val) ynoexcept_spec(ystdex::vswap(val, t))
196 {
197 ystdex::vswap(val, t);
198 }
200 };
201
202
203 template<typename _type, typename _tToken>
204 struct state_guard_impl : public tagged_value<_tToken, _type>,
205 private state_guard_traits<_type, _tToken>, private noncopyable
206 {
208
209 using base = tagged_value<_tToken, _type>;
210 using typename base::token_type;
211 using typename base::value_type;
212
213 using base::token;
214 using base::value;
216
217 state_guard_impl(token_type t)
218 : base(t)
219 {}
220
222 template<typename... _tParams>
223 void
224 construct_and_save(_tParams&&... args)
225 ynoexcept(noexcept(value_type(yforward(args)...))
226 && noexcept(std::declval<state_guard_impl&>().save()))
227 {
228 base::construct(yforward(args)...);
229 save();
230 }
231
233 using base::destroy;
234
235 void
236 save() ynoexcept(noexcept(state_guard_traits<value_type, token_type>
237 ::save(std::declval<token_type&>(), std::declval<value_type&>())))
238 {
239 state_guard_traits<value_type, token_type>::save(token, value);
240 }
241
242 void
243 restore()
244 ynoexcept_spec(state_guard_traits<value_type, token_type>::restore(
245 std::declval<token_type&>(), std::declval<value_type&>()))
246 {
247 state_guard_traits<value_type, token_type>::restore(token, value);
248 }
249
250 void
251 restore_and_destroy()
252 ynoexcept_spec(state_guard_traits<value_type, token_type>::restore(
253 std::declval<token_type&>(), std::declval<value_type&>()))
254 {
255 restore();
256 destroy();
257 }
258 };
260
261 } // namespace details;
262
271 template<typename _type, typename _tCond = bool,
272 typename _tToken = std::function<void(bool, _type&)>>
273 class state_guard : private details::state_guard_impl<_type, _tToken>
274 {
275 static_assert(is_nothrow_copy_constructible<_tCond>(),
276 "Invalid condition type found.");
277
278 private:
279 using base = details::state_guard_impl<_type, _tToken>;
280
281 public:
282 using typename base::value_type;
283 using typename base::token_type;
284 using condition_type = _tCond;
285
286 using base::token;
287 using base::value;
288
289 private:
291 condition_type enabled{};
292
293 public:
295
296 template<typename... _tParams>
297 state_guard(condition_type cond, token_type t, _tParams&&... args)
298 ynoexcept(and_<is_nothrow_constructible<base, token_type>,
299 is_nothrow_copy_constructible<condition_type>>()
300 && noexcept(std::declval<state_guard&>()
301 .base::construct_and_save(yforward(args)...)))
302 : base(t),
303 enabled(cond)
304 {
305 if(enabled)
306 base::construct_and_save(yforward(args)...);
307 }
308 ~state_guard() ynoexcept(is_nothrow_copy_constructible<condition_type>()
309 && noexcept(std::declval<state_guard&>().base::restore_and_destroy()))
310 {
311 if(enabled)
312 base::restore_and_destroy();
313 }
315
317 void
318 dismiss() ynoexcept(is_nothrow_copyable<condition_type>())
319 {
320 if(enabled)
321 base::destroy();
322 enabled = condition_type();
323 }
324
326 condition_type
327 has_value() const ynothrow
328 {
329 return base::engaged;
330 }
331 };
332
333 template<typename _type, typename _tToken>
334 class state_guard<_type, void, _tToken>
335 : private details::state_guard_impl<_type, _tToken>
336 {
337 private:
338 using base = details::state_guard_impl<_type, _tToken>;
339
340 public:
341 using typename base::value_type;
342 using typename base::token_type;
343 using condition_type = void;
344
345 using base::token;
346 using base::value;
347
348 template<typename... _tParams>
349 state_guard(token_type t, _tParams&&... args) ynoexcept(
350 is_nothrow_constructible<base, token_type>() && noexcept(std::declval<
351 state_guard&>().base::construct_and_save(yforward(args)...)))
352 : base(t)
353 {
354 base::construct_and_save(yforward(args)...);
355 }
357 ~state_guard()
358 ynoexcept_spec(std::declval<state_guard&>().base::restore_and_destroy())
359 {
360 base::restore_and_destroy();
361 }
362 };
364
365
372 template<typename _type, typename _tCond = bool, typename _tReference = _type&>
373 using swap_guard = state_guard<_type, _tCond, _tReference>;
374
375 } // namespace ystdex;
376
377 #endif
378
ystdex::details::state_guard_impl::restore_and_destroy
void restore_and_destroy()
Definition: scope_guard.hpp:251
ystdex::state_guard::~state_guard
~state_guard()
Definition: scope_guard.hpp:308
ystdex::guard
作用域守护：析构时调用保存的函数对象或引用。
Definition: scope_guard.hpp:47
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::details::state_guard_traits::save
static void save(_tToken t, _type &val)
Definition: scope_guard.hpp:170
ystdex::tagged_value::value_type
_type value_type
Definition: placement.hpp:526
ystdex::guard::make_guard
guard< _type > make_guard(_tParams &&...args)
创建作用域守护。
Definition: scope_guard.hpp:76
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
ystdex::one_shot< _func, void, _tState >
Definition: functional.hpp:837
CHRLib::f
f(d, s)
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:794
ystdex::guard::share_guard
std::shared_ptr< _type > share_guard(_func f, _type *p={})
创建共享作用域守护。
Definition: scope_guard.hpp:124
platform::bool
std::FILE *fp bool
Definition: FileIO.h:1280
ystdex::dismiss
auto dismiss(_type &gd) -> decltype(gd.dismiss())
解除操作。
Definition: scope_guard.hpp:138
ystdex::guard::~guard
~guard()
Definition: scope_guard.hpp:58
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::one_shot
调用一次的函数包装模板。
Definition: functional.hpp:797
ystdex::details::state_guard_impl
Definition: scope_guard.hpp:204
ystdex::tagged_value
带记号标记的可选值。
Definition: placement.hpp:523
ystdex::state_guard::has_value
condition_type has_value() const
Definition: scope_guard.hpp:327
ystdex::one_shot::fresh
_tState fresh
Definition: functional.hpp:808
ystdex::details::state_guard_traits< _type, _tToken, true >::restore
static void restore(_tToken t, _type &val)
Definition: scope_guard.hpp:195
ystdex::tagged_value::construct
void construct(_tParams &&...args)
Definition: placement.hpp:562
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
ystdex
特性测试宏。
Definition: ydef.h:822
ystdex::guard::func
_func func
Definition: scope_guard.hpp:49
ystdex::state_guard::condition_type
_tCond condition_type
Definition: scope_guard.hpp:284
ystdex::guard::operator=
guard & operator=(guard &&)=default
ystdex::state_guard::dismiss
void dismiss()
Definition: scope_guard.hpp:318
ystdex::state_guard< _type, void, _tToken >::condition_type
void condition_type
Definition: scope_guard.hpp:343
ystdex::vswap
void vswap(_type &&x, _type2 &&y)
交换可能是 volatile 的左值或右值。
Definition: utility.hpp:142
base.h
基类实用设施。
ystdex::tagged_value::destroy
void destroy()
Definition: placement.hpp:568
ystdex::guard::unique_guard
guard< one_shot< _func, void, _tState > > unique_guard(_func f, _tState s={})
Definition: scope_guard.hpp:94
ystdex::state_guard
使用临时状态暂存对象的作用域守护。
Definition: scope_guard.hpp:273
ystdex::details::state_guard_impl::construct_and_save
void construct_and_save(_tParams &&...args)
Definition: scope_guard.hpp:224
std
Definition: memory.hpp:1183
ystdex::state_guard::enabled
condition_type enabled
Definition: scope_guard.hpp:291
placement.hpp
放置对象管理操作。
ystdex::guard::guard
guard(_tParams &&...args)
Definition: scope_guard.hpp:53
ystdex::is_nothrow_copyable
Definition: type_traits.hpp:929
ystdex::state_guard< _type, void, _tToken >::~state_guard
~state_guard()
Definition: scope_guard.hpp:357
ystdex::tagged_value::token_type
_tToken token_type
Definition: placement.hpp:525
utility.hpp
实用设施。
ystdex::state_guard< _type, void, _tToken >::state_guard
state_guard(token_type t, _tParams &&...args)
Definition: scope_guard.hpp:349
ystdex::noncopyable
不可复制对象：禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
Definition: base.h:41
ystdex::tagged_value::token
token_type token
Definition: placement.hpp:528
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:995
ystdex::share_raw
std::shared_ptr< _type > share_raw(_type *p, _tParams &&...args)
Definition: memory.hpp:787
ystdex::details::state_guard_traits< _type, _tToken, true >::save
static void save(_tToken t, _type &val)
Definition: scope_guard.hpp:189
ystdex::details::state_guard_impl::state_guard_impl
state_guard_impl(token_type t)
Definition: scope_guard.hpp:217
ystdex::details::state_guard_traits
Definition: scope_guard.hpp:165
ystdex::state_guard::state_guard
state_guard(condition_type cond, token_type t, _tParams &&...args)
Definition: scope_guard.hpp:297
ystdex::and_
逻辑操作元函数。
Definition: type_traits.hpp:420
ystdex::details::state_guard_impl::restore
void restore()
Definition: scope_guard.hpp:243
ystdex::details::state_guard_impl::save
void save()
Definition: scope_guard.hpp:236
ystdex::tagged_value::value
_type value
Definition: placement.hpp:532
ystdex::details::state_guard_traits::restore
static void restore(_tToken t, _type &val)
Definition: scope_guard.hpp:176
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:746
CHRLib::p
const auto p(d)