YSTest: scope_guard.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

scope_guard.hpp
浏览该文件的文档.
1 /*
2 © 2015-2019 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 exclude_self_params_t, is_nothrow_constructible,
34 // decay_t, is_reference, ystdex::vswap, tagged_value, noncopyable,
35 // std::declval, is_nothrow_copyable;
36 #include "functional.hpp" // for one_shot, function;
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 yimpl(typename = exclude_self_params_t<guard, _tParams...>)>
54 guard(_tParams&&... args)
55 ynoexcept(is_nothrow_constructible<_func, _tParams...>::value)
56 : func(yforward(args)...)
57 {}
58 guard(guard&&) = default;
59 ~guard() ynoexcept_spec(!_bNoThrow)
60 {
61 func();
62 }
63
64 guard&
65 operator=(guard&&) = default;
66 };
67
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 }
82 template<bool _bNoThrow = true, typename _type>
83 guard<_type>
84 make_guard(_type f)
85 ynoexcept_spec(guard<_type, _bNoThrow>(guard<_type, _bNoThrow>(f)))
86 {
87 return guard<_type, _bNoThrow>(f);
88 }
90
92
93 template<typename _tState = bool, bool _bNoThrow = true, typename _func>
94 guard<one_shot<decay_t<_func>, void, decay_t<_tState>>, _bNoThrow>
95 unique_guard(_func&& f, _tState&& s = true) ynoexcept_spec(
96 guard<one_shot<decay_t<_func>, void, decay_t<_tState>>, _bNoThrow>(
97 guard<one_shot<decay_t<_func>, void, decay_t<_tState>>,
98 _bNoThrow>(yforward(f), yforward(s))))
99 {
100 return guard<one_shot<decay_t<_func>, void, decay_t<_tState>>, _bNoThrow>(
101 yforward(f), yforward(s));
102 }
103
104 template<typename _tRes, typename _tState = bool, bool _bNoThrow = true,
105 typename _func>
106 guard<one_shot<_func, _tRes, decay_t<_tState>>, _bNoThrow>
107 unique_state_guard(_func&& f, _tRes r = {}, _tState&& s = true) ynoexcept_spec(
108 guard<one_shot<decay_t<_func>, _tRes, decay_t<_tState>>, _bNoThrow>(
109 guard<one_shot<decay_t<_func>, _tRes, decay_t<_tState>>, _bNoThrow>(
110 yforward(f), r, s)))
111 {
112 return guard<one_shot<decay_t<_func>, _tRes, decay_t<_tState>>, _bNoThrow>(
113 yforward(f), r, yforward(s));
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, bool = is_reference<_tToken>::value>
164 struct state_guard_traits
165 {
167
168 static void
169 save(_tToken t, _type& val) ynoexcept_spec(t(true, val))
170 {
171 t(true, val);
172 }
173
174 static void
175 restore(_tToken t, _type& val) ynoexcept_spec(t(false, val))
176 {
177 t(false, val);
178 }
180 };
181
182 template<typename _type, typename _tToken>
183 struct state_guard_traits<_type, _tToken, true>
184 {
186
187 static void
188 save(_tToken t, _type& val) ynoexcept_spec(ystdex::vswap(val, t))
189 {
190 ystdex::vswap(val, t);
191 }
192
193 static void
194 restore(_tToken t, _type& val) ynoexcept_spec(ystdex::vswap(val, t))
195 {
196 ystdex::vswap(val, t);
197 }
199 };
200
201
202 template<typename _type, typename _tToken>
203 struct state_guard_impl : public tagged_value<_tToken, _type>,
204 private state_guard_traits<_type, _tToken>, private noncopyable
205 {
207
208 using base = tagged_value<_tToken, _type>;
209 using typename base::token_type;
210 using typename base::value_type;
211
212 using base::token;
213 using base::value;
215
216 state_guard_impl(token_type t)
217 : base(t)
218 {}
219
221 template<typename... _tParams>
222 void
223 construct_and_save(_tParams&&... args)
224 ynoexcept(noexcept(value_type(yforward(args)...))
225 && noexcept(std::declval<state_guard_impl&>().save()))
226 {
227 base::construct(yforward(args)...);
228 save();
229 }
230
232 using base::destroy;
233
234 void
235 save() ynoexcept(noexcept(state_guard_traits<value_type, token_type>
236 ::save(std::declval<token_type&>(), std::declval<value_type&>())))
237 {
238 state_guard_traits<value_type, token_type>::save(token, value);
239 }
240
241 void
242 restore()
243 ynoexcept_spec(state_guard_traits<value_type, token_type>::restore(
244 std::declval<token_type&>(), std::declval<value_type&>()))
245 {
246 state_guard_traits<value_type, token_type>::restore(token, value);
247 }
248
249 void
250 restore_and_destroy()
251 ynoexcept_spec(state_guard_traits<value_type, token_type>::restore(
252 std::declval<token_type&>(), std::declval<value_type&>()))
253 {
254 restore();
255 destroy();
256 }
257 };
259
260 } // namespace details;
261
270 template<typename _type, typename _tCond = bool,
271 typename _tToken = function<void(bool, _type&)>>
272 class state_guard : private details::state_guard_impl<_type, _tToken>
273 {
274 static_assert(is_nothrow_copy_constructible<_tCond>(),
275 "Invalid condition type found.");
276
277 private:
278 using base = details::state_guard_impl<_type, _tToken>;
279
280 public:
281 using typename base::value_type;
282 using typename base::token_type;
283 using condition_type = _tCond;
284
285 using base::token;
286 using base::value;
287
288 private:
290 condition_type enabled{};
291
292 public:
294
295 template<typename... _tParams>
296 state_guard(condition_type cond, token_type t, _tParams&&... args)
297 ynoexcept(and_<is_nothrow_constructible<base, token_type>,
298 is_nothrow_copy_constructible<condition_type>>()
299 && noexcept(std::declval<state_guard&>()
300 .base::construct_and_save(yforward(args)...)))
301 : base(t),
302 enabled(cond)
303 {
304 if(enabled)
305 base::construct_and_save(yforward(args)...);
306 }
307 ~state_guard() ynoexcept(is_nothrow_copy_constructible<condition_type>()
308 && noexcept(std::declval<state_guard&>().base::restore_and_destroy()))
309 {
310 if(enabled)
311 base::restore_and_destroy();
312 }
314
316 void
317 dismiss() ynoexcept(is_nothrow_copyable<condition_type>())
318 {
319 if(enabled)
320 base::destroy();
321 enabled = condition_type();
322 }
323
325 condition_type
326 has_value() const ynothrow
327 {
328 return base::engaged;
329 }
330 };
331
332 template<typename _type, typename _tToken>
333 class state_guard<_type, void, _tToken>
334 : private details::state_guard_impl<_type, _tToken>
335 {
336 private:
337 using base = details::state_guard_impl<_type, _tToken>;
338
339 public:
340 using typename base::value_type;
341 using typename base::token_type;
342 using condition_type = void;
343
344 using base::token;
345 using base::value;
346
347 template<typename... _tParams>
348 state_guard(token_type t, _tParams&&... args) ynoexcept(
349 is_nothrow_constructible<base, token_type>() && noexcept(std::declval<
350 state_guard&>().base::construct_and_save(yforward(args)...)))
351 : base(t)
352 {
353 base::construct_and_save(yforward(args)...);
354 }
356 ~state_guard()
357 ynoexcept_spec(std::declval<state_guard&>().base::restore_and_destroy())
358 {
359 base::restore_and_destroy();
360 }
361 };
363
364
371 template<typename _type, typename _tCond = bool, typename _tReference = _type&>
372 using swap_guard = state_guard<_type, _tCond, _tReference>;
373
374 } // namespace ystdex;
375
376 #endif
377
ystdex::guard::operator=
guard & operator=(guard &&)=default
ystdex::tagged_value::token
token_type token
Definition: placement.hpp:788
ystdex::cond
conditional< _tCond::value, _tThen, _tElse > cond
条件判断。
Definition: meta.hpp:787
ystdex::details::state_guard_traits::save
static void save(_tToken t, _type &val)
Definition: scope_guard.hpp:169
ystdex::make_guard
guard< _type > make_guard(_type f)
Definition: scope_guard.hpp:84
ystdex::guard::guard
guard(_tParams &&... args)
Definition: scope_guard.hpp:54
ystdex::state_guard::token_type
_tToken token_type
Definition: placement.hpp:785
ystdex::tagged_value::value
_type value
Definition: placement.hpp:792
ystdex::details::state_guard_impl::state_guard_impl
state_guard_impl(token_type t)
Definition: scope_guard.hpp:216
ystdex::guard::~guard
~guard()
Definition: scope_guard.hpp:59
ystdex::state_guard::condition_type
_tCond condition_type
Definition: scope_guard.hpp:283
ystdex::state_guard< _type, void, _tToken >::state_guard
state_guard(token_type t, _tParams &&... args)
Definition: scope_guard.hpp:348
ystdex::details::state_guard_impl::save
void save()
Definition: scope_guard.hpp:235
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::unique_state_guard
guard< one_shot< _func, _tRes, decay_t< _tState > >, _bNoThrow > unique_state_guard(_func &&f, _tRes r={}, _tState &&s=true)
Definition: scope_guard.hpp:107
ystdex::share_raw
std::shared_ptr< _type > share_raw(_type *p, _tParams &&... args)
Definition: memory.hpp:692
ystdex::function_base
函数包装类模板。
Definition: function.hpp:578
ystdex::tagged_value::value_type
_type value_type
Definition: placement.hpp:786
ystdex::exclude_self_params_t
enable_if_t< not_< cond_or_t< bool_< sizeof...(_tParams)==1 >, false_, is_same_param, _tSelected, _tParams... > >::value, void > exclude_self_params_t
排除选择类型的特定参数类型的重载。
Definition: type_op.hpp:295
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:1181
ystdex::state_guard::dismiss
void dismiss()
Definition: scope_guard.hpp:317
ystdex::state_guard::enabled
condition_type enabled
Definition: scope_guard.hpp:290
CHRLib::f
f(d, s)
ystdex::guard::func
_func func
Definition: scope_guard.hpp:49
ystdex::is_nothrow_copyable
Definition: meta.hpp:628
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
ystdex::cpp2014::decay_t
typename decay< _type >::type decay_t
Definition: meta.hpp:196
ystdex::state_guard
使用临时状态暂存对象的作用域守卫。
Definition: scope_guard.hpp:273
ystdex::share_guard
std::shared_ptr< _type > share_guard(_func f, _type *p={})
创建共享作用域守卫。
Definition: scope_guard.hpp:124
ystdex::details::state_guard_traits< _type, _tToken, true >::restore
static void restore(_tToken t, _type &val)
Definition: scope_guard.hpp:194
ystdex::state_guard::~state_guard
~state_guard()
Definition: scope_guard.hpp:307
ystdex::state_guard< _type, void, _tToken >::condition_type
void condition_type
Definition: scope_guard.hpp:342
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::tagged_value
带记号标记的可选值。
Definition: placement.hpp:784
ystdex::vswap
void vswap(_type &&x, _type2 &&y)
交换可能是 volatile 的左值或右值。
Definition: swap.hpp:463
ystdex::details::state_guard_traits
Definition: scope_guard.hpp:165
ystdex::guard::guard
guard(guard &&)=default
std
Definition: optional.h:982
functional.hpp
函数和可调用对象。
ystdex::details::state_guard_impl::restore
void restore()
Definition: scope_guard.hpp:242
utility.hpp
实用设施。
ystdex::one_shot::fresh
_tState fresh
Definition: functional.hpp:257
ystdex::one_shot
调用一次的函数包装模板。
Definition: functional.hpp:247
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
ystdex::tagged_value::destroy
void destroy()
Definition: placement.hpp:834
ystdex::state_guard< _type, void, _tToken >::~state_guard
~state_guard()
Definition: scope_guard.hpp:356
ystdex::unique_guard
guard< one_shot< decay_t< _func >, void, decay_t< _tState > >, _bNoThrow > unique_guard(_func &&f, _tState &&s=true)
Definition: scope_guard.hpp:95
ystdex::state_guard::has_value
condition_type has_value() const
Definition: scope_guard.hpp:326
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::state_guard::state_guard
state_guard(condition_type cond, token_type t, _tParams &&... args)
Definition: scope_guard.hpp:296
platform::p
return p p
Definition: YCLib/FileSystem.h:209
ystdex::tagged_value::token_type
_tToken token_type
Definition: placement.hpp:785
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
platform::bool
YB_ATTR_nodiscard std::FILE *fp bool
Definition: FileIO.h:1271
ystdex::details::state_guard_impl::construct_and_save
void construct_and_save(_tParams &&... args)
Definition: scope_guard.hpp:223
ystdex::details::state_guard_impl
Definition: scope_guard.hpp:205
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
ystdex::guard::make_guard
guard< _type > make_guard(_tParams &&... args)
创建作用域守卫。
Definition: scope_guard.hpp:76
ystdex::details::state_guard_traits::restore
static void restore(_tToken t, _type &val)
Definition: scope_guard.hpp:175
ystdex::bases::noncopyable
不可复制对象：禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
Definition: base.h:50
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:1151
ystdex::details::state_guard_impl::restore_and_destroy
void restore_and_destroy()
Definition: scope_guard.hpp:250
ystdex::dismiss
auto dismiss(_type &gd) -> decltype(gd.dismiss())
解除操作。
Definition: scope_guard.hpp:138
ystdex::tagged_value::construct
void construct(_tParams &&... args)
Definition: placement.hpp:828
ystdex::details::state_guard_traits< _type, _tToken, true >::save
static void save(_tToken t, _type &val)
Definition: scope_guard.hpp:188
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::guard
作用域守卫：析构时调用保存的函数对象或引用。
Definition: scope_guard.hpp:48
ystdex::and_
逻辑操作元函数。
Definition: integral_constant.hpp:151