• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
2  *           2019 Mike Dev <mike.dev@gmx.de>
3  * Distributed under the Boost Software License, Version 1.0.
4  * (See accompanying file LICENSE_1_0.txt or copy at
5  * https://www.boost.org/LICENSE_1_0.txt)
6  *
7  * NOTE: internalized from Boost.MultiIndex
8  *
9  */
10 
11 
12 #ifndef BOOST_SIGNALS2_DETAIL_SCOPE_GUARD_HPP
13 #define BOOST_SIGNALS2_DETAIL_SCOPE_GUARD_HPP
14 
15 #if defined(_MSC_VER)
16 #pragma once
17 #endif
18 
19 #include <boost/core/no_exceptions_support.hpp>
20 
21 namespace boost{
22 
23 namespace signals2{
24 
25 namespace detail{
26 
27 /* This is a merely reformated version of
28  * ScopeGuard.h as defined in:
29  *   Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You
30  *     Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000,
31  *     http://www.drdobbs.com/184403758
32  * with the following modifications:
33  *   - General pretty formatting (pretty to my taste at least.)
34  *   - Naming style changed to standard C++ library requirements.
35  *   - Removed RefHolder and ByRef, whose functionality is provided
36  *     already by Boost.Ref.
37  *   - Removed static make_guard's and make_obj_guard's, so that the code
38  *     will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces
39  *     us to move some private ctors to public, though.
40  *
41  * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute
42  * without an explicit qualification.
43  *
44  *  TODO: Consider replacing with Boost.ScopeExit
45  *
46  */
47 
48 class scope_guard_impl_base
49 {
50 public:
scope_guard_impl_base()51   scope_guard_impl_base():dismissed_(false){}
dismiss() const52   void dismiss()const{dismissed_=true;}
53 
54 protected:
~scope_guard_impl_base()55   ~scope_guard_impl_base(){}
56 
scope_guard_impl_base(const scope_guard_impl_base & other)57   scope_guard_impl_base(const scope_guard_impl_base& other):
58     dismissed_(other.dismissed_)
59   {
60     other.dismiss();
61   }
62 
63   template<typename J>
safe_execute(J & j)64   static void safe_execute(J& j){
65     BOOST_TRY{
66       if(!j.dismissed_)j.execute();
67     }
68     BOOST_CATCH(...){}
69     BOOST_CATCH_END
70   }
71 
72   mutable bool dismissed_;
73 
74 private:
75   scope_guard_impl_base& operator=(const scope_guard_impl_base&);
76 };
77 
78 typedef const scope_guard_impl_base& scope_guard;
79 
80 template<class Obj,typename MemFun,typename P1,typename P2>
81 class obj_scope_guard_impl2:public scope_guard_impl_base
82 {
83 public:
obj_scope_guard_impl2(Obj & obj,MemFun mem_fun,P1 p1,P2 p2)84   obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2):
85     obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2)
86   {}
~obj_scope_guard_impl2()87   ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
execute()88   void execute(){(obj_.*mem_fun_)(p1_,p2_);}
89 
90 protected:
91   Obj&     obj_;
92   MemFun   mem_fun_;
93   const P1 p1_;
94   const P2 p2_;
95 };
96 
97 template<class Obj,typename MemFun,typename P1,typename P2>
98 inline obj_scope_guard_impl2<Obj,MemFun,P1,P2>
make_obj_guard(Obj & obj,MemFun mem_fun,P1 p1,P2 p2)99 make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
100 {
101   return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2);
102 }
103 
104 } /* namespace signals2::detail */
105 
106 } /* namespace signals2 */
107 
108 } /* namespace boost */
109 
110 #endif
111