]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/ScopeGuard.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / ScopeGuard.h
1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2000 Andrei Alexandrescu
4 // Copyright (c) 2000 Petru Marginean
5 // Copyright (c) 2005 Joshua Lehrer
6 //
7 // Permission to use, copy, modify, distribute and sell this software for any
8 //     purpose is hereby granted without fee, provided that the above copyright
9 //     notice appear in all copies and that both that copyright notice and this
10 //     permission notice appear in supporting documentation.
11 // The author makes no representations about the
12 //     suitability of this software for any purpose. It is provided "as is"
13 //     without express or implied warranty.
14 ////////////////////////////////////////////////////////////////////////////////
15 #ifndef LOKI_SCOPEGUARD_INC_
16 #define LOKI_SCOPEGUARD_INC_
17
18 // $Id: ScopeGuard.h 799 2006-12-20 00:37:13Z rich_sposato $
19
20
21 #include <loki/RefToValue.h>
22
23 /// \defgroup ExceptionGroup Exception-safe code
24
25 namespace Loki
26 {
27
28 ////////////////////////////////////////////////////////////////
29 ///
30 /// \class ScopeGuardImplBase
31 /// \ingroup ExceptionGroup
32 ///
33 /// Base class used by all ScopeGuard implementations.  All commonly used
34 /// functions are in this class (e.g. - Dismiss and SafeExecute).
35 ///
36 /// See Andrei's and Petru Marginean's CUJ article
37 /// http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm
38 ///
39 /// Changes to the original code by Joshua Lehrer:
40 /// http://www.lehrerfamily.com/scopeguard.html
41 ////////////////////////////////////////////////////////////////
42
43 class ScopeGuardImplBase
44 {
45         /// Copy-assignment operator is not implemented and private.
46         ScopeGuardImplBase &operator =(const ScopeGuardImplBase &);
47
48 protected:
49
50         ~ScopeGuardImplBase()
51         {}
52
53         /// Copy-constructor takes over responsibility from other ScopeGuard.
54         ScopeGuardImplBase(const ScopeGuardImplBase &other) throw()
55                 : dismissed_(other.dismissed_)
56         {
57                 other.Dismiss();
58         }
59
60         template <typename J>
61         static void SafeExecute(J &j) throw()
62         {
63                 if (!j.dismissed_)
64                         try
65                         {
66                                 j.Execute();
67                         }
68                         catch(...)
69                                 {}
70         }
71
72         mutable bool dismissed_;
73
74 public:
75         ScopeGuardImplBase() throw() : dismissed_(false)
76         {}
77
78         void Dismiss() const throw()
79         {
80                 dismissed_ = true;
81         }
82 };
83
84 ////////////////////////////////////////////////////////////////
85 ///
86 /// \typedef typedef const ScopeGuardImplBase& ScopeGuard
87 /// \ingroup ExceptionGroup
88 ///
89 ////////////////////////////////////////////////////////////////
90
91 typedef const ScopeGuardImplBase &ScopeGuard;
92
93 ////////////////////////////////////////////////////////////////
94 ///
95 /// \class ScopeGuardImpl0
96 /// \ingroup ExceptionGroup
97 ///
98 /// Implementation class for a standalone function or class static function
99 /// with no parameters.  ScopeGuard ignores any value returned from the
100 /// call within the Execute function.
101 ///
102 /// This class has a single standalone helper function, MakeGuard which
103 /// creates and returns a ScopeGuard.
104 ///
105 ////////////////////////////////////////////////////////////////
106
107 template <typename F>
108 class ScopeGuardImpl0 : public ScopeGuardImplBase
109 {
110 public:
111         static ScopeGuardImpl0<F> MakeGuard(F fun)
112         {
113                 return ScopeGuardImpl0<F>(fun);
114         }
115
116         ~ScopeGuardImpl0() throw()
117         {
118                 SafeExecute(*this);
119         }
120
121         void Execute()
122         {
123                 fun_();
124         }
125
126 protected:
127         ScopeGuardImpl0(F fun) : fun_(fun)
128         {}
129
130         F fun_;
131 };
132
133 template <typename F>
134 inline ScopeGuardImpl0<F> MakeGuard(F fun)
135 {
136         return ScopeGuardImpl0<F>::MakeGuard(fun);
137 }
138
139 ////////////////////////////////////////////////////////////////
140 ///
141 /// \class ScopeGuardImpl1
142 /// \ingroup ExceptionGroup
143 ///
144 /// Implementation class for a standalone function or class static function
145 /// with one parameter.  Each parameter is copied by value - use
146 /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
147 /// any value returned from the call within the Execute function.
148 ///
149 /// This class has a single standalone helper function, MakeGuard which
150 /// creates and returns a ScopeGuard.
151 ///
152 ////////////////////////////////////////////////////////////////
153
154 template <typename F, typename P1>
155 class ScopeGuardImpl1 : public ScopeGuardImplBase
156 {
157 public:
158         static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
159         {
160                 return ScopeGuardImpl1<F, P1>(fun, p1);
161         }
162
163         ~ScopeGuardImpl1() throw()
164         {
165                 SafeExecute(*this);
166         }
167
168         void Execute()
169         {
170                 fun_(p1_);
171         }
172
173 protected:
174         ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
175         {}
176
177         F fun_;
178         const P1 p1_;
179 };
180
181 template <typename F, typename P1>
182 inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
183 {
184         return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
185 }
186
187 ////////////////////////////////////////////////////////////////
188 ///
189 /// \class ScopeGuardImpl2
190 /// \ingroup ExceptionGroup
191 ///
192 /// Implementation class for a standalone function or class static function
193 /// with two parameters.  Each parameter is copied by value - use
194 /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
195 /// any value returned from the call within the Execute function.
196 ///
197 /// This class has a single standalone helper function, MakeGuard which
198 /// creates and returns a ScopeGuard.
199 ///
200 ////////////////////////////////////////////////////////////////
201
202 template <typename F, typename P1, typename P2>
203 class ScopeGuardImpl2: public ScopeGuardImplBase
204 {
205 public:
206         static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
207         {
208                 return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
209         }
210
211         ~ScopeGuardImpl2() throw()
212         {
213                 SafeExecute(*this);
214         }
215
216         void Execute()
217         {
218                 fun_(p1_, p2_);
219         }
220
221 protected:
222         ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
223         {}
224
225         F fun_;
226         const P1 p1_;
227         const P2 p2_;
228 };
229
230 template <typename F, typename P1, typename P2>
231 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
232 {
233         return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
234 }
235
236 ////////////////////////////////////////////////////////////////
237 ///
238 /// \class ScopeGuardImpl3
239 /// \ingroup ExceptionGroup
240 ///
241 /// Implementation class for a standalone function or class static function
242 /// with three parameters.  Each parameter is copied by value - use
243 /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
244 /// any value returned from the call within the Execute function.
245 ///
246 /// This class has a single standalone helper function, MakeGuard which
247 /// creates and returns a ScopeGuard.
248 ///
249 ////////////////////////////////////////////////////////////////
250
251 template <typename F, typename P1, typename P2, typename P3>
252 class ScopeGuardImpl3 : public ScopeGuardImplBase
253 {
254 public:
255         static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
256         {
257                 return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
258         }
259
260         ~ScopeGuardImpl3() throw()
261         {
262                 SafeExecute(*this);
263         }
264
265         void Execute()
266         {
267                 fun_(p1_, p2_, p3_);
268         }
269
270 protected:
271         ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
272         {}
273
274         F fun_;
275         const P1 p1_;
276         const P2 p2_;
277         const P3 p3_;
278 };
279
280 template <typename F, typename P1, typename P2, typename P3>
281 inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
282 {
283         return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
284 }
285
286 ////////////////////////////////////////////////////////////////
287 ///
288 /// \class ScopeGuardImpl4
289 /// \ingroup ExceptionGroup
290 ///
291 /// Implementation class for a standalone function or class static function
292 /// with four parameters.  Each parameter is copied by value - use
293 /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
294 /// any value returned from the call within the Execute function.
295 ///
296 /// This class has a single standalone helper function, MakeGuard which
297 /// creates and returns a ScopeGuard.
298 ///
299 ////////////////////////////////////////////////////////////////
300
301 template < typename F, typename P1, typename P2, typename P3, typename P4 >
302 class ScopeGuardImpl4 : public ScopeGuardImplBase
303 {
304 public:
305         static ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard(
306             F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
307         {
308                 return ScopeGuardImpl4< F, P1, P2, P3, P4 >( fun, p1, p2, p3, p4 );
309         }
310
311         ~ScopeGuardImpl4() throw()
312         {
313                 SafeExecute( *this );
314         }
315
316         void Execute()
317         {
318                 fun_( p1_, p2_, p3_, p4_ );
319         }
320
321 protected:
322         ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) :
323                 fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 )
324         {}
325
326         F fun_;
327         const P1 p1_;
328         const P2 p2_;
329         const P3 p3_;
330         const P4 p4_;
331 };
332
333 template < typename F, typename P1, typename P2, typename P3, typename P4 >
334 inline ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
335 {
336         return ScopeGuardImpl4< F, P1, P2, P3, P4 >::MakeGuard( fun, p1, p2, p3, p4 );
337 }
338
339 ////////////////////////////////////////////////////////////////
340 ///
341 /// \class ScopeGuardImpl5
342 /// \ingroup ExceptionGroup
343 ///
344 /// Implementation class for a standalone function or class static function
345 /// with five parameters.  Each parameter is copied by value - use
346 /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
347 /// any value returned from the call within the Execute function.
348 ///
349 /// This class has a single standalone helper function, MakeGuard which
350 /// creates and returns a ScopeGuard.
351 ///
352 ////////////////////////////////////////////////////////////////
353
354 template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
355 class ScopeGuardImpl5 : public ScopeGuardImplBase
356 {
357 public:
358         static ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard(
359             F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
360         {
361                 return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >( fun, p1, p2, p3, p4, p5 );
362         }
363
364         ~ScopeGuardImpl5() throw()
365         {
366                 SafeExecute( *this );
367         }
368
369         void Execute()
370         {
371                 fun_( p1_, p2_, p3_, p4_, p5_ );
372         }
373
374 protected:
375         ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) :
376                 fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 )
377         {}
378
379         F fun_;
380         const P1 p1_;
381         const P2 p2_;
382         const P3 p3_;
383         const P4 p4_;
384         const P5 p5_;
385 };
386
387 template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
388 inline ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
389 {
390         return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >::MakeGuard( fun, p1, p2, p3, p4, p5 );
391 }
392
393 ////////////////////////////////////////////////////////////////
394 ///
395 /// \class ObjScopeGuardImpl0
396 /// \ingroup ExceptionGroup
397 ///
398 /// Implementation class for a class per-instance member function with no
399 /// parameters.  ScopeGuard ignores any value returned from the call within
400 /// the Execute function.
401 ///
402 /// This class has 3 standalone helper functions which create a ScopeGuard.
403 /// One is MakeObjGuard, which is deprecated but provided for older code.
404 /// The other two are MakeGuard overloads, one which takes a pointer to an
405 /// object, and the other which takes a reference.
406 ///
407 ////////////////////////////////////////////////////////////////
408
409 template <class Obj, typename MemFun>
410 class ObjScopeGuardImpl0 : public ScopeGuardImplBase
411 {
412 public:
413         static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun)
414         {
415                 return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
416         }
417
418         ~ObjScopeGuardImpl0() throw()
419         {
420                 SafeExecute(*this);
421         }
422
423         void Execute()
424         {
425                 (obj_.*memFun_)();
426         }
427
428 protected:
429         ObjScopeGuardImpl0(Obj &obj, MemFun memFun) : obj_(obj), memFun_(memFun)
430         {}
431
432         Obj &obj_;
433         MemFun memFun_;
434 };
435
436 template <class Obj, typename MemFun>
437 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun)
438 {
439         return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
440 }
441
442 template <typename Ret, class Obj1, class Obj2>
443 inline ObjScopeGuardImpl0<Obj1,Ret(Obj2:: *)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj)
444 {
445         return ObjScopeGuardImpl0<Obj1,Ret(Obj2:: *)()>::MakeObjGuard(obj,memFun);
446 }
447
448 template <typename Ret, class Obj1, class Obj2>
449 inline ObjScopeGuardImpl0<Obj1,Ret(Obj2:: *)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj)
450 {
451         return ObjScopeGuardImpl0<Obj1,Ret(Obj2:: *)()>::MakeObjGuard(*obj,memFun);
452 }
453
454 ////////////////////////////////////////////////////////////////
455 ///
456 /// \class ObjScopeGuardImpl1
457 /// \ingroup ExceptionGroup
458 ///
459 /// Implementation class for a class per-instance member function with one
460 /// parameter.  The parameter is copied by value - use ::Loki::ByRef if you
461 /// must use a reference instead.  ScopeGuard ignores any value returned
462 /// from the call within the Execute function.
463 ///
464 /// This class has 3 standalone helper functions which create a ScopeGuard.
465 /// One is MakeObjGuard, which is deprecated but provided for older code.
466 /// The other two are MakeGuard overloads, one which takes a pointer to an
467 /// object, and the other which takes a reference.
468 ///
469 ////////////////////////////////////////////////////////////////
470
471 template <class Obj, typename MemFun, typename P1>
472 class ObjScopeGuardImpl1 : public ScopeGuardImplBase
473 {
474 public:
475         static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
476         {
477                 return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
478         }
479
480         ~ObjScopeGuardImpl1() throw()
481         {
482                 SafeExecute(*this);
483         }
484
485         void Execute()
486         {
487                 (obj_.*memFun_)(p1_);
488         }
489
490 protected:
491         ObjScopeGuardImpl1(Obj &obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
492         {}
493
494         Obj &obj_;
495         MemFun memFun_;
496         const P1 p1_;
497 };
498
499 template <class Obj, typename MemFun, typename P1>
500 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
501 {
502         return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
503 }
504
505 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
506 inline ObjScopeGuardImpl1<Obj1,Ret(Obj2:: *)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 &obj, P1b p1)
507 {
508         return ObjScopeGuardImpl1<Obj1,Ret(Obj2:: *)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
509 }
510
511 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
512 inline ObjScopeGuardImpl1<Obj1,Ret(Obj2:: *)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 *obj, P1b p1)
513 {
514         return ObjScopeGuardImpl1<Obj1,Ret(Obj2:: *)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
515 }
516
517 ////////////////////////////////////////////////////////////////
518 ///
519 /// \class ObjScopeGuardImpl2
520 /// \ingroup ExceptionGroup
521 ///
522 /// Implementation class for a class per-instance member function with two
523 /// parameters.  Each parameter is copied by value - use ::Loki::ByRef if you
524 /// must use a reference instead.  ScopeGuard ignores any value returned
525 /// from the call within the Execute function.
526 ///
527 /// This class has 3 standalone helper functions which create a ScopeGuard.
528 /// One is MakeObjGuard, which is deprecated but provided for older code.
529 /// The other two are MakeGuard overloads, one which takes a pointer to an
530 /// object, and the other which takes a reference.
531 ///
532 ////////////////////////////////////////////////////////////////
533
534 template <class Obj, typename MemFun, typename P1, typename P2>
535 class ObjScopeGuardImpl2 : public ScopeGuardImplBase
536 {
537 public:
538         static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
539         {
540                 return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
541         }
542
543         ~ObjScopeGuardImpl2() throw()
544         {
545                 SafeExecute(*this);
546         }
547
548         void Execute()
549         {
550                 (obj_.*memFun_)(p1_, p2_);
551         }
552
553 protected:
554         ObjScopeGuardImpl2(Obj &obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
555         {}
556
557         Obj &obj_;
558         MemFun memFun_;
559         const P1 p1_;
560         const P2 p2_;
561 };
562
563 template <class Obj, typename MemFun, typename P1, typename P2>
564 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
565 {
566         return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
567 }
568
569 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
570 inline ObjScopeGuardImpl2<Obj1,Ret(Obj2:: *)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 &obj, P1b p1, P2b p2)
571 {
572         return ObjScopeGuardImpl2<Obj1,Ret(Obj2:: *)(P1a,P2a),P1b,P2b>::MakeObjGuard(obj,memFun,p1,p2);
573 }
574
575 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
576 inline ObjScopeGuardImpl2<Obj1,Ret(Obj2:: *)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 *obj, P1b p1, P2b p2)
577 {
578         return ObjScopeGuardImpl2<Obj1,Ret(Obj2:: *)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
579 }
580
581 ////////////////////////////////////////////////////////////////
582 ///
583 /// \class ObjScopeGuardImpl3
584 /// \ingroup ExceptionGroup
585 ///
586 /// Implementation class for a class per-instance member function with three
587 /// parameters.  Each parameter is copied by value - use ::Loki::ByRef if you
588 /// must use a reference instead.  ScopeGuard ignores any value returned
589 /// from the call within the Execute function.
590 ///
591 /// This class has 3 standalone helper functions which create a ScopeGuard.
592 /// One is MakeObjGuard, which is deprecated but provided for older code.
593 /// The other two are MakeGuard overloads, one which takes a pointer to an
594 /// object, and the other which takes a reference.
595 ///
596 ////////////////////////////////////////////////////////////////
597
598 template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
599 class ObjScopeGuardImpl3 : public ScopeGuardImplBase
600 {
601 public:
602         static ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
603             Obj &obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
604         {
605                 return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >( obj, memFun, p1, p2, p3 );
606         }
607
608         ~ObjScopeGuardImpl3() throw()
609         {
610                 SafeExecute( *this );
611         }
612
613         void Execute()
614         {
615                 ( obj_.*memFun_ )( p1_, p2_, p3_ );
616         }
617
618 protected:
619         ObjScopeGuardImpl3( Obj &obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) :
620                 obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 )
621         {}
622
623         Obj &obj_;
624         MemFun memFun_;
625         const P1 p1_;
626         const P2 p2_;
627         const P3 p3_;
628 };
629
630 template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
631 inline ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
632     Obj &obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
633 {
634         return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >::MakeObjGuard(
635                    obj, memFun, p1, p2, p3 );
636 }
637
638 template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
639          typename P2a, typename P2b, typename P3a, typename P3b >
640 inline ObjScopeGuardImpl3< Obj1, Ret( Obj2:: * )( P1a, P2a, P3a ), P1b, P2b, P3b >
641 MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1 &obj, P1b p1, P2b p2, P3b p3 )
642 {
643         return ObjScopeGuardImpl3< Obj1, Ret( Obj2:: * )( P1a, P2a, P3a ), P1b, P2b, P3b >
644                ::MakeObjGuard( obj, memFun, p1, p2, p3 );
645 }
646
647 template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
648          typename P2a, typename P2b, typename P3a, typename P3b >
649 inline ObjScopeGuardImpl3< Obj1, Ret( Obj2:: * )( P1a, P2a, P3a ), P1b, P2b, P3b >
650 MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1 *obj, P1b p1, P2b p2, P3b p3 )
651 {
652         return ObjScopeGuardImpl3< Obj1, Ret( Obj2:: * )( P1a, P2a, P3a ), P1b, P2b, P3b >
653                ::MakeObjGuard( *obj, memFun, p1, p2, p3 );
654 }
655
656 } // namespace Loki
657
658 #define LOKI_CONCATENATE_DIRECT(s1, s2)  s1##s2
659 #define LOKI_CONCATENATE(s1, s2)         LOKI_CONCATENATE_DIRECT(s1, s2)
660 #define LOKI_ANONYMOUS_VARIABLE(str)     LOKI_CONCATENATE(str, __LINE__)
661
662 #define LOKI_ON_BLOCK_EXIT      ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeGuard
663 #define LOKI_ON_BLOCK_EXIT_OBJ  ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeObjGuard
664
665 #endif // end file guardian
666