Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/util/ScopeGuard.h @ 3235

Last change on this file since 3235 was 3235, checked in by rgrieder, 15 years ago

Added ScopeGuard from the Loki library. It provides a very simple mechanism to write exception-safe code. Have a look at the article:
http://www.ddj.com/cpp/184403758
The basic idea is to make a scope guard and pass it a function to be called in case you don't call the guard's dismiss() function. And you always do this in the linear code order exception if it was interrupted by an exception. This way you can make sure that resources are being freed in any case.

  • Property svn:eol-style set to native
File size: 21.9 KB
Line 
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
25namespace 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
Note: See TracBrowser for help on using the repository browser.