acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
scoped_restore.h
1#pragma once
2
3
4template <class TYPE>
5struct scoped_restore_struct
6{
7
8
9 TYPE * m_pKept;
10 TYPE m_valueRestore;
11
12 scoped_restore_struct(TYPE * pKept);
13 scoped_restore_struct(TYPE * pKept,const TYPE & set);
14 ~scoped_restore_struct();
15
16 void Restore();
17
18};
19
20
21template <class TYPE>
22scoped_restore_struct<TYPE>::scoped_restore_struct(TYPE * pKept):
23 m_pKept(pKept),
24 m_valueRestore(*m_pKept)
25{
26
27}
28
29
30template <class TYPE>
31scoped_restore_struct<TYPE>::scoped_restore_struct(TYPE * pKept, const TYPE & set) :
32 m_pKept(pKept),
33 m_valueRestore(*m_pKept)
34{
35
36 *m_pKept = set;
37}
38
39
40
41template <class TYPE>
42scoped_restore_struct<TYPE>::~scoped_restore_struct()
43{
44
45 Restore();
46
47}
48
49
50template <class TYPE>
51void scoped_restore_struct<TYPE>::Restore()
52{
53
54 *m_pKept = m_valueRestore;
55
56}
57
58
59template < typename TYPE >
60inline ::scoped_restore_struct < TYPE > create_scoped_restore(TYPE & t)
61{
62
63 return {&t};
64
65}
66
67#define __counter_name__(name) TOKEN_CONCATENATE(name, TOKEN_CONCATENATE(__, __COUNTER__))
68
69
70
71
72#define scoped_restore(payload) auto __counter_name__(scoped_restore) = create_scoped_restore(payload)
73
74
75//#define __set_restore(payload, set) ::scoped_restore < decltype(payload) > TOKEN_CONCATENATE(scopedrestore, __COUNTER__) (&payload); ::payload = set
76
77
78
79
80
81template <class PREDICATE>
82struct run_at_destructor_struct
83{
84
85 PREDICATE m_predicate;
86
87 run_at_destructor_struct(PREDICATE predicate) : m_predicate(predicate) {}
88 ~run_at_destructor_struct() { m_predicate(); }
89
90};
91
92
93#define at_end_of_scope run_at_destructor_struct __counter_name__(run_at_destructor) = [&]()
94
95
96