1 | /* Copyright 2003-2005 Joaquín M López Muñoz. |
---|
2 | * Distributed under the Boost Software License, Version 1.0. |
---|
3 | * (See accompanying file LICENSE_1_0.txt or copy at |
---|
4 | * http://www.boost.org/LICENSE_1_0.txt) |
---|
5 | * |
---|
6 | * See http://www.boost.org/libs/multi_index for library home page. |
---|
7 | */ |
---|
8 | |
---|
9 | #ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP |
---|
10 | #define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP |
---|
11 | |
---|
12 | #if defined(_MSC_VER)&&(_MSC_VER>=1200) |
---|
13 | #pragma once |
---|
14 | #endif |
---|
15 | |
---|
16 | namespace boost{ |
---|
17 | |
---|
18 | namespace multi_index{ |
---|
19 | |
---|
20 | namespace detail{ |
---|
21 | |
---|
22 | /* Until some official version of the ScopeGuard idiom makes it into Boost, |
---|
23 | * we locally define our own. This is a merely reformated version of |
---|
24 | * ScopeGuard.h as defined in: |
---|
25 | * Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You |
---|
26 | * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, |
---|
27 | * http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/ |
---|
28 | * with the following modifications: |
---|
29 | * - General pretty formatting (pretty to my taste at least.) |
---|
30 | * - Naming style changed to standard C++ library requirements. |
---|
31 | * - safe_execute does not feature a try-catch protection, so we can |
---|
32 | * use this even if BOOST_NO_EXCEPTIONS is defined. |
---|
33 | * - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex |
---|
34 | * needs them). A better design would provide guards for many more |
---|
35 | * arguments through the Boost Preprocessor Library. |
---|
36 | * - Added scope_guard_impl_base::touch (see below.) |
---|
37 | * - Removed RefHolder and ByRef, whose functionality is provided |
---|
38 | * already by Boost.Ref. |
---|
39 | * - Removed static make_guard's and make_obj_guard's, so that the code |
---|
40 | * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces |
---|
41 | * us to move some private ctors to public, though. |
---|
42 | * |
---|
43 | * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute |
---|
44 | * without an explicit qualification. |
---|
45 | */ |
---|
46 | |
---|
47 | class scope_guard_impl_base |
---|
48 | { |
---|
49 | public: |
---|
50 | scope_guard_impl_base():dismissed_(false){} |
---|
51 | void dismiss()const{dismissed_=true;} |
---|
52 | |
---|
53 | /* This helps prevent some "unused variable" warnings under, for instance, |
---|
54 | * GCC 3.2. |
---|
55 | */ |
---|
56 | void touch()const{} |
---|
57 | |
---|
58 | protected: |
---|
59 | ~scope_guard_impl_base(){} |
---|
60 | |
---|
61 | scope_guard_impl_base(const scope_guard_impl_base& other): |
---|
62 | dismissed_(other.dismissed_) |
---|
63 | { |
---|
64 | other.dismiss(); |
---|
65 | } |
---|
66 | |
---|
67 | template<typename J> |
---|
68 | static void safe_execute(J& j){if(!j.dismissed_)j.execute();} |
---|
69 | |
---|
70 | mutable bool dismissed_; |
---|
71 | |
---|
72 | private: |
---|
73 | scope_guard_impl_base& operator=(const scope_guard_impl_base&); |
---|
74 | }; |
---|
75 | |
---|
76 | typedef const scope_guard_impl_base& scope_guard; |
---|
77 | |
---|
78 | template<typename F> |
---|
79 | class scope_guard_impl0:public scope_guard_impl_base |
---|
80 | { |
---|
81 | public: |
---|
82 | scope_guard_impl0(F fun):fun_(fun){} |
---|
83 | ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} |
---|
84 | void execute(){fun_();} |
---|
85 | |
---|
86 | protected: |
---|
87 | |
---|
88 | F fun_; |
---|
89 | }; |
---|
90 | |
---|
91 | template<typename F> |
---|
92 | inline scope_guard_impl0<F> make_guard(F fun) |
---|
93 | { |
---|
94 | return scope_guard_impl0<F>(fun); |
---|
95 | } |
---|
96 | |
---|
97 | template<typename F,typename P1> |
---|
98 | class scope_guard_impl1:public scope_guard_impl_base |
---|
99 | { |
---|
100 | public: |
---|
101 | scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){} |
---|
102 | ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} |
---|
103 | void execute(){fun_(p1_);} |
---|
104 | |
---|
105 | protected: |
---|
106 | F fun_; |
---|
107 | const P1 p1_; |
---|
108 | }; |
---|
109 | |
---|
110 | template<typename F,typename P1> |
---|
111 | inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1) |
---|
112 | { |
---|
113 | return scope_guard_impl1<F,P1>(fun,p1); |
---|
114 | } |
---|
115 | |
---|
116 | template<typename F,typename P1,typename P2> |
---|
117 | class scope_guard_impl2:public scope_guard_impl_base |
---|
118 | { |
---|
119 | public: |
---|
120 | scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){} |
---|
121 | ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} |
---|
122 | void execute(){fun_(p1_,p2_);} |
---|
123 | |
---|
124 | protected: |
---|
125 | F fun_; |
---|
126 | const P1 p1_; |
---|
127 | const P2 p2_; |
---|
128 | }; |
---|
129 | |
---|
130 | template<typename F,typename P1,typename P2> |
---|
131 | inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2) |
---|
132 | { |
---|
133 | return scope_guard_impl2<F,P1,P2>(fun,p1,p2); |
---|
134 | } |
---|
135 | |
---|
136 | template<typename F,typename P1,typename P2,typename P3> |
---|
137 | class scope_guard_impl3:public scope_guard_impl_base |
---|
138 | { |
---|
139 | public: |
---|
140 | scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){} |
---|
141 | ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} |
---|
142 | void execute(){fun_(p1_,p2_,p3_);} |
---|
143 | |
---|
144 | protected: |
---|
145 | F fun_; |
---|
146 | const P1 p1_; |
---|
147 | const P2 p2_; |
---|
148 | const P3 p3_; |
---|
149 | }; |
---|
150 | |
---|
151 | template<typename F,typename P1,typename P2,typename P3> |
---|
152 | inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3) |
---|
153 | { |
---|
154 | return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3); |
---|
155 | } |
---|
156 | |
---|
157 | template<typename F,typename P1,typename P2,typename P3,typename P4> |
---|
158 | class scope_guard_impl4:public scope_guard_impl_base |
---|
159 | { |
---|
160 | public: |
---|
161 | scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4): |
---|
162 | fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){} |
---|
163 | ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);} |
---|
164 | void execute(){fun_(p1_,p2_,p3_,p4_);} |
---|
165 | |
---|
166 | protected: |
---|
167 | F fun_; |
---|
168 | const P1 p1_; |
---|
169 | const P2 p2_; |
---|
170 | const P3 p3_; |
---|
171 | const P4 p4_; |
---|
172 | }; |
---|
173 | |
---|
174 | template<typename F,typename P1,typename P2,typename P3,typename P4> |
---|
175 | inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard( |
---|
176 | F fun,P1 p1,P2 p2,P3 p3,P4 p4) |
---|
177 | { |
---|
178 | return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4); |
---|
179 | } |
---|
180 | |
---|
181 | template<class Obj,typename MemFun> |
---|
182 | class obj_scope_guard_impl0:public scope_guard_impl_base |
---|
183 | { |
---|
184 | public: |
---|
185 | obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){} |
---|
186 | ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} |
---|
187 | void execute(){(obj_.*mem_fun_)();} |
---|
188 | |
---|
189 | protected: |
---|
190 | Obj& obj_; |
---|
191 | MemFun mem_fun_; |
---|
192 | }; |
---|
193 | |
---|
194 | template<class Obj,typename MemFun> |
---|
195 | inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun) |
---|
196 | { |
---|
197 | return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun); |
---|
198 | } |
---|
199 | |
---|
200 | template<class Obj,typename MemFun,typename P1> |
---|
201 | class obj_scope_guard_impl1:public scope_guard_impl_base |
---|
202 | { |
---|
203 | public: |
---|
204 | obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1): |
---|
205 | obj_(obj),mem_fun_(mem_fun),p1_(p1){} |
---|
206 | ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} |
---|
207 | void execute(){(obj_.*mem_fun_)(p1_);} |
---|
208 | |
---|
209 | protected: |
---|
210 | Obj& obj_; |
---|
211 | MemFun mem_fun_; |
---|
212 | const P1 p1_; |
---|
213 | }; |
---|
214 | |
---|
215 | template<class Obj,typename MemFun,typename P1> |
---|
216 | inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard( |
---|
217 | Obj& obj,MemFun mem_fun,P1 p1) |
---|
218 | { |
---|
219 | return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1); |
---|
220 | } |
---|
221 | |
---|
222 | template<class Obj,typename MemFun,typename P1,typename P2> |
---|
223 | class obj_scope_guard_impl2:public scope_guard_impl_base |
---|
224 | { |
---|
225 | public: |
---|
226 | obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2): |
---|
227 | obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2) |
---|
228 | {} |
---|
229 | ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} |
---|
230 | void execute(){(obj_.*mem_fun_)(p1_,p2_);} |
---|
231 | |
---|
232 | protected: |
---|
233 | Obj& obj_; |
---|
234 | MemFun mem_fun_; |
---|
235 | const P1 p1_; |
---|
236 | const P2 p2_; |
---|
237 | }; |
---|
238 | |
---|
239 | template<class Obj,typename MemFun,typename P1,typename P2> |
---|
240 | inline obj_scope_guard_impl2<Obj,MemFun,P1,P2> |
---|
241 | make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) |
---|
242 | { |
---|
243 | return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2); |
---|
244 | } |
---|
245 | |
---|
246 | template<class Obj,typename MemFun,typename P1,typename P2,typename P3> |
---|
247 | class obj_scope_guard_impl3:public scope_guard_impl_base |
---|
248 | { |
---|
249 | public: |
---|
250 | obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3): |
---|
251 | obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3) |
---|
252 | {} |
---|
253 | ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} |
---|
254 | void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);} |
---|
255 | |
---|
256 | protected: |
---|
257 | Obj& obj_; |
---|
258 | MemFun mem_fun_; |
---|
259 | const P1 p1_; |
---|
260 | const P2 p2_; |
---|
261 | const P3 p3_; |
---|
262 | }; |
---|
263 | |
---|
264 | template<class Obj,typename MemFun,typename P1,typename P2,typename P3> |
---|
265 | inline obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> |
---|
266 | make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) |
---|
267 | { |
---|
268 | return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3); |
---|
269 | } |
---|
270 | |
---|
271 | } /* namespace multi_index::detail */ |
---|
272 | |
---|
273 | } /* namespace multi_index */ |
---|
274 | |
---|
275 | } /* namespace boost */ |
---|
276 | |
---|
277 | #endif |
---|