| [3235] | 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 |  | 
|---|
| [3237] | 21 | #include "RefToValue.h" | 
|---|
| [3235] | 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 |         ScopeGuardImpl0(F fun) : fun_(fun)  | 
|---|
 | 127 |         {} | 
|---|
 | 128 |  | 
|---|
| [3370] | 129 |     protected: | 
|---|
| [3235] | 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 |         ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)  | 
|---|
 | 174 |         {} | 
|---|
 | 175 |  | 
|---|
| [3370] | 176 |     protected: | 
|---|
| [3235] | 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 |         ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)  | 
|---|
 | 222 |         {} | 
|---|
 | 223 |  | 
|---|
| [3370] | 224 |     protected: | 
|---|
| [3235] | 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 |         ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)  | 
|---|
 | 271 |         {} | 
|---|
 | 272 |  | 
|---|
| [3370] | 273 |     protected: | 
|---|
| [3235] | 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 |         ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) : | 
|---|
 | 322 |              fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ) | 
|---|
 | 323 |         {} | 
|---|
 | 324 |  | 
|---|
| [3370] | 325 |     protected: | 
|---|
| [3235] | 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 |         ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) : | 
|---|
 | 375 |              fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 ) | 
|---|
 | 376 |         {} | 
|---|
 | 377 |  | 
|---|
| [3370] | 378 |     protected: | 
|---|
| [3235] | 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 |         ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)  | 
|---|
 | 429 |         {} | 
|---|
 | 430 |  | 
|---|
| [3370] | 431 |     protected: | 
|---|
| [3235] | 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 |         ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)  | 
|---|
 | 491 |         {} | 
|---|
 | 492 |          | 
|---|
| [3370] | 493 |     protected: | 
|---|
| [3235] | 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 |         ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)  | 
|---|
 | 554 |         {} | 
|---|
 | 555 |  | 
|---|
| [3370] | 556 |     protected: | 
|---|
| [3235] | 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 |         ObjScopeGuardImpl3( Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) : | 
|---|
 | 619 |              obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 ) | 
|---|
 | 620 |         {} | 
|---|
 | 621 |  | 
|---|
| [3370] | 622 |     protected: | 
|---|
| [3235] | 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 |  | 
|---|