0
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
| #include <exception>
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
class transaction
{
public:
transaction()
: incomplete(true)
{
}
~transaction()
{
if(incomplete)
{
revert();
}
}
template <class T>
void begin(T& t)
{
params.push_back(param_ptr(new param_impl<T>(t)));
};
void commit()
{
incomplete = false;
}
private:
class param
{
public:
virtual ~param() {};
virtual void revert() const = 0;
};
template <class T>
class param_impl : public param
{
public:
param_impl(T& t)
: reference(t)
, original (t)
{
}
virtual void revert() const
{
reference = original;
}
private:
T& reference;
T original;
};
typedef boost::shared_ptr<param> param_ptr;
typedef std::vector<param_ptr> param_container;
bool incomplete;
param_container params;
void revert()
{
for
(
param_container::const_reverse_iterator i = params.rbegin();
i != params.rend();
++i
)
{
(*i)->revert();
}
}
};
int main()
{
std::string name = "Angelina";
float bosom = 85.3f;
float waist = 68.5f;
float pelvis = 88.8f;
try
{
transaction trn;
trn.begin(name);
trn.begin(bosom);
trn.begin(waist);
trn.begin(pelvis);
name = "Olga";
bosom = 102.4f;
waist = 59.3f;
pelvis = 92.3f;
throw std::runtime_error("Wife is coming!");
trn.commit();
}
catch(std::exception const&)
{
std::cout << "Hi, dear!" << std::endl;
}
return 0;
} | |