Coverage Report

Created: 2025-12-31 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/boost/multi_index/detail/scope_guard.hpp
Line
Count
Source
1
/* Copyright 2003-2020 Joaquin M Lopez Munoz.
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)
13
#pragma once
14
#endif
15
16
#include <boost/core/no_exceptions_support.hpp>
17
#include <boost/mpl/if.hpp>
18
19
namespace boost{
20
21
namespace multi_index{
22
23
namespace detail{
24
25
/* Until some official version of the ScopeGuard idiom makes it into Boost,
26
 * we locally define our own. This is a merely reformated version of
27
 * ScopeGuard.h as defined in:
28
 *   Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You
29
 *     Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000,
30
 *     http://www.drdobbs.com/184403758
31
 * with the following modifications:
32
 *   - General pretty formatting (pretty to my taste at least.)
33
 *   - Naming style changed to standard C++ library requirements.
34
 *   - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex
35
 *     needs them). A better design would provide guards for many more
36
 *     arguments through the Boost Preprocessor Library.
37
 *   - Added scope_guard_impl_base::touch (see below.)
38
 *   - Removed RefHolder and ByRef, whose functionality is provided
39
 *     already by Boost.Ref.
40
 *   - Removed static make_guard's and make_obj_guard's, so that the code
41
 *     will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces
42
 *     us to move some private ctors to public, though.
43
 *
44
 * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute
45
 * without an explicit qualification.
46
 * 
47
 * We also define the following variants of the idiom:
48
 * 
49
 *   - make_guard_if_c<bool>( ... )
50
 *   - make_guard_if<IntegralConstant>( ... )
51
 *   - make_obj_guard_if_c<bool>( ... )
52
 *   - make_obj_guard_if<IntegralConstant>( ... )
53
 * which may be used with a compile-time constant to yield
54
 * a "null_guard" if the boolean compile-time parameter is false,
55
 * or conversely, the guard is only constructed if the constant is true.
56
 * This is useful to avoid extra tagging, because the returned
57
 * null_guard can be optimzed comlpetely away by the compiler.
58
 */
59
60
class scope_guard_impl_base
61
{
62
public:
63
0
  scope_guard_impl_base():dismissed_(false){}
64
0
  void dismiss()const{dismissed_=true;}
65
66
  /* This helps prevent some "unused variable" warnings under, for instance,
67
   * GCC 3.2.
68
   */
69
0
  void touch()const{}
70
71
protected:
72
0
  ~scope_guard_impl_base(){}
73
74
  scope_guard_impl_base(const scope_guard_impl_base& other):
75
    dismissed_(other.dismissed_)
76
0
  {
77
0
    other.dismiss();
78
0
  }
79
80
  template<typename J>
81
  static void safe_execute(J& j){
82
    BOOST_TRY{
83
      if(!j.dismissed_)j.execute();
84
    }
85
    BOOST_CATCH(...){}
86
    BOOST_CATCH_END
87
  }
88
  
89
  mutable bool dismissed_;
90
91
private:
92
  scope_guard_impl_base& operator=(const scope_guard_impl_base&);
93
};
94
95
typedef const scope_guard_impl_base& scope_guard;
96
97
struct null_guard : public scope_guard_impl_base
98
{
99
    template< class T1 >
100
    null_guard( const T1& )
101
    { }
102
103
    template< class T1, class T2 >
104
    null_guard( const T1&, const T2& )
105
    { }
106
107
    template< class T1, class T2, class T3 >
108
    null_guard( const T1&, const T2&, const T3& )
109
    { }
110
111
    template< class T1, class T2, class T3, class T4 >
112
    null_guard( const T1&, const T2&, const T3&, const T4& )
113
    { }
114
115
    template< class T1, class T2, class T3, class T4, class T5 >
116
    null_guard( const T1&, const T2&, const T3&, const T4&, const T5& )
117
    { }
118
};
119
120
template< bool cond, class T >
121
struct null_guard_return
122
{
123
    typedef typename boost::mpl::if_c<cond,T,null_guard>::type type;
124
};
125
126
template<typename F>
127
class scope_guard_impl0:public scope_guard_impl_base
128
{
129
public:
130
  scope_guard_impl0(F fun):fun_(fun){}
131
  ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);}
132
  void execute(){fun_();}
133
134
protected:
135
136
  F fun_;
137
};
138
139
template<typename F> 
140
inline scope_guard_impl0<F> make_guard(F fun)
141
{
142
  return scope_guard_impl0<F>(fun);
143
}
144
145
template<bool cond, typename F> 
146
inline typename null_guard_return<cond,scope_guard_impl0<F> >::type  
147
make_guard_if_c(F fun)
148
{
149
  return typename null_guard_return<cond,scope_guard_impl0<F> >::type(fun);
150
}
151
152
template<typename C, typename F> 
153
inline typename null_guard_return<C::value,scope_guard_impl0<F> >::type  
154
make_guard_if(F fun)
155
{
156
  return make_guard_if<C::value>(fun);
157
}
158
159
template<typename F,typename P1>
160
class scope_guard_impl1:public scope_guard_impl_base
161
{
162
public:
163
  scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){}
164
  ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);}
165
  void execute(){fun_(p1_);}
166
167
protected:
168
  F        fun_;
169
  const P1 p1_;
170
};
171
172
template<typename F,typename P1> 
173
inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1)
174
{
175
  return scope_guard_impl1<F,P1>(fun,p1);
176
}
177
178
template<bool cond, typename F,typename P1> 
179
inline typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type 
180
make_guard_if_c(F fun,P1 p1)
181
{
182
  return typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type(fun,p1);
183
}
184
185
template<typename C, typename F,typename P1> 
186
inline typename null_guard_return<C::value,scope_guard_impl1<F,P1> >::type 
187
make_guard_if(F fun,P1 p1)
188
{
189
  return make_guard_if_c<C::value>(fun,p1);
190
}
191
192
template<typename F,typename P1,typename P2>
193
class scope_guard_impl2:public scope_guard_impl_base
194
{
195
public:
196
  scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){}
197
  ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
198
  void execute(){fun_(p1_,p2_);}
199
200
protected:
201
  F        fun_;
202
  const P1 p1_;
203
  const P2 p2_;
204
};
205
206
template<typename F,typename P1,typename P2>
207
inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2)
208
{
209
  return scope_guard_impl2<F,P1,P2>(fun,p1,p2);
210
}
211
212
template<bool cond, typename F,typename P1,typename P2>
213
inline typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type
214
make_guard_if_c(F fun,P1 p1,P2 p2)
215
{
216
  return typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type(fun,p1,p2);
217
}
218
219
template<typename C, typename F,typename P1,typename P2>
220
inline typename null_guard_return<C::value,scope_guard_impl2<F,P1,P2> >::type
221
make_guard_if(F fun,P1 p1,P2 p2)
222
{
223
  return make_guard_if_c<C::value>(fun,p1,p2);
224
}
225
226
template<typename F,typename P1,typename P2,typename P3>
227
class scope_guard_impl3:public scope_guard_impl_base
228
{
229
public:
230
  scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){}
231
  ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);}
232
  void execute(){fun_(p1_,p2_,p3_);}
233
234
protected:
235
  F        fun_;
236
  const P1 p1_;
237
  const P2 p2_;
238
  const P3 p3_;
239
};
240
241
template<typename F,typename P1,typename P2,typename P3>
242
inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3)
243
{
244
  return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3);
245
}
246
247
template<bool cond,typename F,typename P1,typename P2,typename P3>
248
inline typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type 
249
make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3)
250
{
251
  return typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type(fun,p1,p2,p3);
252
}
253
254
template<typename C,typename F,typename P1,typename P2,typename P3>
255
inline typename null_guard_return< C::value,scope_guard_impl3<F,P1,P2,P3> >::type 
256
make_guard_if(F fun,P1 p1,P2 p2,P3 p3)
257
{
258
  return make_guard_if_c<C::value>(fun,p1,p2,p3);
259
}
260
261
template<typename F,typename P1,typename P2,typename P3,typename P4>
262
class scope_guard_impl4:public scope_guard_impl_base
263
{
264
public:
265
  scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4):
266
    fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){}
267
  ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);}
268
  void execute(){fun_(p1_,p2_,p3_,p4_);}
269
270
protected:
271
  F        fun_;
272
  const P1 p1_;
273
  const P2 p2_;
274
  const P3 p3_;
275
  const P4 p4_;
276
};
277
278
template<typename F,typename P1,typename P2,typename P3,typename P4>
279
inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard(
280
  F fun,P1 p1,P2 p2,P3 p3,P4 p4)
281
{
282
  return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4);
283
}
284
285
template<bool cond, typename F,typename P1,typename P2,typename P3,typename P4>
286
inline typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type 
287
make_guard_if_c(
288
  F fun,P1 p1,P2 p2,P3 p3,P4 p4)
289
{
290
  return typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type(fun,p1,p2,p3,p4);
291
}
292
293
template<typename C, typename F,typename P1,typename P2,typename P3,typename P4>
294
inline typename null_guard_return<C::value,scope_guard_impl4<F,P1,P2,P3,P4> >::type 
295
make_guard_if(
296
  F fun,P1 p1,P2 p2,P3 p3,P4 p4)
297
{
298
  return make_guard_if_c<C::value>(fun,p1,p2,p3,p4);
299
}
300
301
template<class Obj,typename MemFun>
302
class obj_scope_guard_impl0:public scope_guard_impl_base
303
{
304
public:
305
  obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){}
306
  ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);}
307
  void execute(){(obj_.*mem_fun_)();}
308
309
protected:
310
  Obj&   obj_;
311
  MemFun mem_fun_;
312
};
313
314
template<class Obj,typename MemFun>
315
inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun)
316
{
317
  return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun);
318
}
319
320
template<bool cond, class Obj,typename MemFun>
321
inline typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type 
322
make_obj_guard_if_c(Obj& obj,MemFun mem_fun)
323
{
324
  return typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type(obj,mem_fun);
325
}
326
327
template<typename C, class Obj,typename MemFun>
328
inline typename null_guard_return<C::value,obj_scope_guard_impl0<Obj,MemFun> >::type 
329
make_obj_guard_if(Obj& obj,MemFun mem_fun)
330
{
331
  return make_obj_guard_if_c<C::value>(obj,mem_fun);
332
}
333
334
template<class Obj,typename MemFun,typename P1>
335
class obj_scope_guard_impl1:public scope_guard_impl_base
336
{
337
public:
338
  obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1):
339
    obj_(obj),mem_fun_(mem_fun),p1_(p1){}
340
  ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);}
341
  void execute(){(obj_.*mem_fun_)(p1_);}
342
343
protected:
344
  Obj&     obj_;
345
  MemFun   mem_fun_;
346
  const P1 p1_;
347
};
348
349
template<class Obj,typename MemFun,typename P1>
350
inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard(
351
  Obj& obj,MemFun mem_fun,P1 p1)
352
{
353
  return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1);
354
}
355
356
template<bool cond, class Obj,typename MemFun,typename P1>
357
inline typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type 
358
make_obj_guard_if_c(  Obj& obj,MemFun mem_fun,P1 p1)
359
{
360
  return typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type(obj,mem_fun,p1);
361
}
362
363
template<typename C, class Obj,typename MemFun,typename P1>
364
inline typename null_guard_return<C::value,obj_scope_guard_impl1<Obj,MemFun,P1> >::type 
365
make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1)
366
{
367
  return make_obj_guard_if_c<C::value>(obj,mem_fun,p1);
368
}
369
370
template<class Obj,typename MemFun,typename P1,typename P2>
371
class obj_scope_guard_impl2:public scope_guard_impl_base
372
{
373
public:
374
  obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2):
375
    obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2)
376
  {}
377
  ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
378
  void execute(){(obj_.*mem_fun_)(p1_,p2_);}
379
380
protected:
381
  Obj&     obj_;
382
  MemFun   mem_fun_;
383
  const P1 p1_;
384
  const P2 p2_;
385
};
386
387
template<class Obj,typename MemFun,typename P1,typename P2>
388
inline obj_scope_guard_impl2<Obj,MemFun,P1,P2>
389
make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
390
{
391
  return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2);
392
}
393
394
template<bool cond, class Obj,typename MemFun,typename P1,typename P2>
395
inline typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
396
make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
397
{
398
  return typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type(obj,mem_fun,p1,p2);
399
}
400
401
template<typename C, class Obj,typename MemFun,typename P1,typename P2>
402
inline typename null_guard_return<C::value,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
403
make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
404
{
405
  return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2);
406
}
407
408
template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
409
class obj_scope_guard_impl3:public scope_guard_impl_base
410
{
411
public:
412
  obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3):
413
    obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3)
414
  {}
415
  ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);}
416
  void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);}
417
418
protected:
419
  Obj&     obj_;
420
  MemFun   mem_fun_;
421
  const P1 p1_;
422
  const P2 p2_;
423
  const P3 p3_;
424
};
425
426
template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
427
inline obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>
428
make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
429
{
430
  return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3);
431
}
432
433
template<bool cond, class Obj,typename MemFun,typename P1,typename P2,typename P3>
434
inline typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
435
make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
436
{
437
  return typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type(obj,mem_fun,p1,p2,p3);
438
}
439
440
template<typename C, class Obj,typename MemFun,typename P1,typename P2,typename P3>
441
inline typename null_guard_return<C::value,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
442
make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
443
{
444
  return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2,p3);
445
}
446
447
} /* namespace multi_index::detail */
448
449
} /* namespace multi_index */
450
451
} /* namespace boost */
452
453
#endif