Line data Source code
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:
51 0 : scope_guard_impl_base():dismissed_(false){}
52 0 : void dismiss()const{dismissed_=true;}
53 :
54 : protected:
55 0 : ~scope_guard_impl_base(){}
56 :
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>
64 0 : static void safe_execute(J& j){
65 : BOOST_TRY{
66 0 : if(!j.dismissed_)j.execute();
67 0 : }
68 0 : BOOST_CATCH(...){}
69 : BOOST_CATCH_END
70 0 : }
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:
84 0 : obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2):
85 0 : obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2)
86 0 : {}
87 0 : ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
88 0 : 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>
99 0 : make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
100 : {
101 0 : 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
|