/
rollback_on_exception.hpp
103 lines (84 loc) · 2.08 KB
/
rollback_on_exception.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* SObjectizer-5
*/
/*!
* \since
* v.5.5.4
*
* \file
* \brief Helpers for do rollback actions in the case of exception.
*/
#pragma once
namespace so_5 {
namespace details {
namespace rollback_on_exception_details {
/*!
* \since
* v.5.5.4
*
* \brief Helper template class for do rollback actions automatically
* in the destructor.
*
* \tparam L type of lambda with rollback actions.
*/
template< typename L >
class rollbacker_t
{
L & m_action;
bool m_commited = false;
public :
inline rollbacker_t( L & action ) : m_action( action ) {}
inline ~rollbacker_t() { if( !m_commited ) m_action(); }
inline void commit() { m_commited = true; }
};
template< typename Result, typename Main_Action, typename Rollback_Action >
struct executor
{
static Result
exec(
Main_Action main_action,
rollbacker_t< Rollback_Action > & rollback )
{
auto r = main_action();
rollback.commit();
return r;
}
};
template< typename Main_Action, typename Rollback_Action >
struct executor< void, Main_Action, Rollback_Action >
{
static void
exec(
Main_Action main_action,
rollbacker_t< Rollback_Action > & rollback )
{
main_action();
rollback.commit();
}
};
} /* namespace rollback_on_exception_details */
/*!
* \since
* v.5.5.4
*
* \brief Helper function for do some action with rollback in the case of
* an exception.
*
* \tparam Main_Action type of lambda with main action.
* \tparam Rollback_Action type of lambda with rollback action.
*/
template< typename Main_Action, typename Rollback_Action >
auto
do_with_rollback_on_exception(
Main_Action main_action,
Rollback_Action rollback_action )
-> decltype(main_action())
{
using result_type = decltype(main_action());
using namespace rollback_on_exception_details;
rollbacker_t< Rollback_Action > rollbacker{ rollback_action };
return executor< result_type, Main_Action, Rollback_Action >::exec(
main_action, rollbacker );
}
} /* namespace details */
} /* namespace so_5 */