Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:09

0001 /* Copyright 2003-2020 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See http://www.boost.org/libs/multi_index for library home page.
0007  */
0008 
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/core/no_exceptions_support.hpp>
0017 #include <boost/mpl/if.hpp>
0018 
0019 namespace boost{
0020 
0021 namespace multi_index{
0022 
0023 namespace detail{
0024 
0025 /* Until some official version of the ScopeGuard idiom makes it into Boost,
0026  * we locally define our own. This is a merely reformated version of
0027  * ScopeGuard.h as defined in:
0028  *   Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You
0029  *     Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000,
0030  *     http://www.drdobbs.com/184403758
0031  * with the following modifications:
0032  *   - General pretty formatting (pretty to my taste at least.)
0033  *   - Naming style changed to standard C++ library requirements.
0034  *   - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex
0035  *     needs them). A better design would provide guards for many more
0036  *     arguments through the Boost Preprocessor Library.
0037  *   - Added scope_guard_impl_base::touch (see below.)
0038  *   - Removed RefHolder and ByRef, whose functionality is provided
0039  *     already by Boost.Ref.
0040  *   - Removed static make_guard's and make_obj_guard's, so that the code
0041  *     will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces
0042  *     us to move some private ctors to public, though.
0043  *
0044  * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute
0045  * without an explicit qualification.
0046  * 
0047  * We also define the following variants of the idiom:
0048  * 
0049  *   - make_guard_if_c<bool>( ... )
0050  *   - make_guard_if<IntegralConstant>( ... )
0051  *   - make_obj_guard_if_c<bool>( ... )
0052  *   - make_obj_guard_if<IntegralConstant>( ... )
0053  * which may be used with a compile-time constant to yield
0054  * a "null_guard" if the boolean compile-time parameter is false,
0055  * or conversely, the guard is only constructed if the constant is true.
0056  * This is useful to avoid extra tagging, because the returned
0057  * null_guard can be optimzed comlpetely away by the compiler.
0058  */
0059 
0060 class scope_guard_impl_base
0061 {
0062 public:
0063   scope_guard_impl_base():dismissed_(false){}
0064   void dismiss()const{dismissed_=true;}
0065 
0066   /* This helps prevent some "unused variable" warnings under, for instance,
0067    * GCC 3.2.
0068    */
0069   void touch()const{}
0070 
0071 protected:
0072   ~scope_guard_impl_base(){}
0073 
0074   scope_guard_impl_base(const scope_guard_impl_base& other):
0075     dismissed_(other.dismissed_)
0076   {
0077     other.dismiss();
0078   }
0079 
0080   template<typename J>
0081   static void safe_execute(J& j){
0082     BOOST_TRY{
0083       if(!j.dismissed_)j.execute();
0084     }
0085     BOOST_CATCH(...){}
0086     BOOST_CATCH_END
0087   }
0088   
0089   mutable bool dismissed_;
0090 
0091 private:
0092   scope_guard_impl_base& operator=(const scope_guard_impl_base&);
0093 };
0094 
0095 typedef const scope_guard_impl_base& scope_guard;
0096 
0097 struct null_guard : public scope_guard_impl_base
0098 {
0099     template< class T1 >
0100     null_guard( const T1& )
0101     { }
0102 
0103     template< class T1, class T2 >
0104     null_guard( const T1&, const T2& )
0105     { }
0106 
0107     template< class T1, class T2, class T3 >
0108     null_guard( const T1&, const T2&, const T3& )
0109     { }
0110 
0111     template< class T1, class T2, class T3, class T4 >
0112     null_guard( const T1&, const T2&, const T3&, const T4& )
0113     { }
0114 
0115     template< class T1, class T2, class T3, class T4, class T5 >
0116     null_guard( const T1&, const T2&, const T3&, const T4&, const T5& )
0117     { }
0118 };
0119 
0120 template< bool cond, class T >
0121 struct null_guard_return
0122 {
0123     typedef typename boost::mpl::if_c<cond,T,null_guard>::type type;
0124 };
0125 
0126 template<typename F>
0127 class scope_guard_impl0:public scope_guard_impl_base
0128 {
0129 public:
0130   scope_guard_impl0(F fun):fun_(fun){}
0131   ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);}
0132   void execute(){fun_();}
0133 
0134 protected:
0135 
0136   F fun_;
0137 };
0138 
0139 template<typename F> 
0140 inline scope_guard_impl0<F> make_guard(F fun)
0141 {
0142   return scope_guard_impl0<F>(fun);
0143 }
0144 
0145 template<bool cond, typename F> 
0146 inline typename null_guard_return<cond,scope_guard_impl0<F> >::type  
0147 make_guard_if_c(F fun)
0148 {
0149   return typename null_guard_return<cond,scope_guard_impl0<F> >::type(fun);
0150 }
0151 
0152 template<typename C, typename F> 
0153 inline typename null_guard_return<C::value,scope_guard_impl0<F> >::type  
0154 make_guard_if(F fun)
0155 {
0156   return make_guard_if<C::value>(fun);
0157 }
0158 
0159 template<typename F,typename P1>
0160 class scope_guard_impl1:public scope_guard_impl_base
0161 {
0162 public:
0163   scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){}
0164   ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);}
0165   void execute(){fun_(p1_);}
0166 
0167 protected:
0168   F        fun_;
0169   const P1 p1_;
0170 };
0171 
0172 template<typename F,typename P1> 
0173 inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1)
0174 {
0175   return scope_guard_impl1<F,P1>(fun,p1);
0176 }
0177 
0178 template<bool cond, typename F,typename P1> 
0179 inline typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type 
0180 make_guard_if_c(F fun,P1 p1)
0181 {
0182   return typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type(fun,p1);
0183 }
0184 
0185 template<typename C, typename F,typename P1> 
0186 inline typename null_guard_return<C::value,scope_guard_impl1<F,P1> >::type 
0187 make_guard_if(F fun,P1 p1)
0188 {
0189   return make_guard_if_c<C::value>(fun,p1);
0190 }
0191 
0192 template<typename F,typename P1,typename P2>
0193 class scope_guard_impl2:public scope_guard_impl_base
0194 {
0195 public:
0196   scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){}
0197   ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
0198   void execute(){fun_(p1_,p2_);}
0199 
0200 protected:
0201   F        fun_;
0202   const P1 p1_;
0203   const P2 p2_;
0204 };
0205 
0206 template<typename F,typename P1,typename P2>
0207 inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2)
0208 {
0209   return scope_guard_impl2<F,P1,P2>(fun,p1,p2);
0210 }
0211 
0212 template<bool cond, typename F,typename P1,typename P2>
0213 inline typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type
0214 make_guard_if_c(F fun,P1 p1,P2 p2)
0215 {
0216   return typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type(fun,p1,p2);
0217 }
0218 
0219 template<typename C, typename F,typename P1,typename P2>
0220 inline typename null_guard_return<C::value,scope_guard_impl2<F,P1,P2> >::type
0221 make_guard_if(F fun,P1 p1,P2 p2)
0222 {
0223   return make_guard_if_c<C::value>(fun,p1,p2);
0224 }
0225 
0226 template<typename F,typename P1,typename P2,typename P3>
0227 class scope_guard_impl3:public scope_guard_impl_base
0228 {
0229 public:
0230   scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){}
0231   ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);}
0232   void execute(){fun_(p1_,p2_,p3_);}
0233 
0234 protected:
0235   F        fun_;
0236   const P1 p1_;
0237   const P2 p2_;
0238   const P3 p3_;
0239 };
0240 
0241 template<typename F,typename P1,typename P2,typename P3>
0242 inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3)
0243 {
0244   return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3);
0245 }
0246 
0247 template<bool cond,typename F,typename P1,typename P2,typename P3>
0248 inline typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type 
0249 make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3)
0250 {
0251   return typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type(fun,p1,p2,p3);
0252 }
0253 
0254 template<typename C,typename F,typename P1,typename P2,typename P3>
0255 inline typename null_guard_return< C::value,scope_guard_impl3<F,P1,P2,P3> >::type 
0256 make_guard_if(F fun,P1 p1,P2 p2,P3 p3)
0257 {
0258   return make_guard_if_c<C::value>(fun,p1,p2,p3);
0259 }
0260 
0261 template<typename F,typename P1,typename P2,typename P3,typename P4>
0262 class scope_guard_impl4:public scope_guard_impl_base
0263 {
0264 public:
0265   scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4):
0266     fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){}
0267   ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);}
0268   void execute(){fun_(p1_,p2_,p3_,p4_);}
0269 
0270 protected:
0271   F        fun_;
0272   const P1 p1_;
0273   const P2 p2_;
0274   const P3 p3_;
0275   const P4 p4_;
0276 };
0277 
0278 template<typename F,typename P1,typename P2,typename P3,typename P4>
0279 inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard(
0280   F fun,P1 p1,P2 p2,P3 p3,P4 p4)
0281 {
0282   return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4);
0283 }
0284 
0285 template<bool cond, typename F,typename P1,typename P2,typename P3,typename P4>
0286 inline typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type 
0287 make_guard_if_c(
0288   F fun,P1 p1,P2 p2,P3 p3,P4 p4)
0289 {
0290   return typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type(fun,p1,p2,p3,p4);
0291 }
0292 
0293 template<typename C, typename F,typename P1,typename P2,typename P3,typename P4>
0294 inline typename null_guard_return<C::value,scope_guard_impl4<F,P1,P2,P3,P4> >::type 
0295 make_guard_if(
0296   F fun,P1 p1,P2 p2,P3 p3,P4 p4)
0297 {
0298   return make_guard_if_c<C::value>(fun,p1,p2,p3,p4);
0299 }
0300 
0301 template<class Obj,typename MemFun>
0302 class obj_scope_guard_impl0:public scope_guard_impl_base
0303 {
0304 public:
0305   obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){}
0306   ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);}
0307   void execute(){(obj_.*mem_fun_)();}
0308 
0309 protected:
0310   Obj&   obj_;
0311   MemFun mem_fun_;
0312 };
0313 
0314 template<class Obj,typename MemFun>
0315 inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun)
0316 {
0317   return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun);
0318 }
0319 
0320 template<bool cond, class Obj,typename MemFun>
0321 inline typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type 
0322 make_obj_guard_if_c(Obj& obj,MemFun mem_fun)
0323 {
0324   return typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type(obj,mem_fun);
0325 }
0326 
0327 template<typename C, class Obj,typename MemFun>
0328 inline typename null_guard_return<C::value,obj_scope_guard_impl0<Obj,MemFun> >::type 
0329 make_obj_guard_if(Obj& obj,MemFun mem_fun)
0330 {
0331   return make_obj_guard_if_c<C::value>(obj,mem_fun);
0332 }
0333 
0334 template<class Obj,typename MemFun,typename P1>
0335 class obj_scope_guard_impl1:public scope_guard_impl_base
0336 {
0337 public:
0338   obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1):
0339     obj_(obj),mem_fun_(mem_fun),p1_(p1){}
0340   ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);}
0341   void execute(){(obj_.*mem_fun_)(p1_);}
0342 
0343 protected:
0344   Obj&     obj_;
0345   MemFun   mem_fun_;
0346   const P1 p1_;
0347 };
0348 
0349 template<class Obj,typename MemFun,typename P1>
0350 inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard(
0351   Obj& obj,MemFun mem_fun,P1 p1)
0352 {
0353   return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1);
0354 }
0355 
0356 template<bool cond, class Obj,typename MemFun,typename P1>
0357 inline typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type 
0358 make_obj_guard_if_c(  Obj& obj,MemFun mem_fun,P1 p1)
0359 {
0360   return typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type(obj,mem_fun,p1);
0361 }
0362 
0363 template<typename C, class Obj,typename MemFun,typename P1>
0364 inline typename null_guard_return<C::value,obj_scope_guard_impl1<Obj,MemFun,P1> >::type 
0365 make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1)
0366 {
0367   return make_obj_guard_if_c<C::value>(obj,mem_fun,p1);
0368 }
0369 
0370 template<class Obj,typename MemFun,typename P1,typename P2>
0371 class obj_scope_guard_impl2:public scope_guard_impl_base
0372 {
0373 public:
0374   obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2):
0375     obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2)
0376   {}
0377   ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
0378   void execute(){(obj_.*mem_fun_)(p1_,p2_);}
0379 
0380 protected:
0381   Obj&     obj_;
0382   MemFun   mem_fun_;
0383   const P1 p1_;
0384   const P2 p2_;
0385 };
0386 
0387 template<class Obj,typename MemFun,typename P1,typename P2>
0388 inline obj_scope_guard_impl2<Obj,MemFun,P1,P2>
0389 make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
0390 {
0391   return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2);
0392 }
0393 
0394 template<bool cond, class Obj,typename MemFun,typename P1,typename P2>
0395 inline typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
0396 make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
0397 {
0398   return typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type(obj,mem_fun,p1,p2);
0399 }
0400 
0401 template<typename C, class Obj,typename MemFun,typename P1,typename P2>
0402 inline typename null_guard_return<C::value,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
0403 make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
0404 {
0405   return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2);
0406 }
0407 
0408 template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
0409 class obj_scope_guard_impl3:public scope_guard_impl_base
0410 {
0411 public:
0412   obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3):
0413     obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3)
0414   {}
0415   ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);}
0416   void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);}
0417 
0418 protected:
0419   Obj&     obj_;
0420   MemFun   mem_fun_;
0421   const P1 p1_;
0422   const P2 p2_;
0423   const P3 p3_;
0424 };
0425 
0426 template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
0427 inline obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>
0428 make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
0429 {
0430   return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3);
0431 }
0432 
0433 template<bool cond, class Obj,typename MemFun,typename P1,typename P2,typename P3>
0434 inline typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
0435 make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
0436 {
0437   return typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type(obj,mem_fun,p1,p2,p3);
0438 }
0439 
0440 template<typename C, class Obj,typename MemFun,typename P1,typename P2,typename P3>
0441 inline typename null_guard_return<C::value,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
0442 make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
0443 {
0444   return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2,p3);
0445 }
0446 
0447 } /* namespace multi_index::detail */
0448 
0449 } /* namespace multi_index */
0450 
0451 } /* namespace boost */
0452 
0453 #endif