scope_guard.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #ifndef BOOST_SIGNALS2_DETAIL_SCOPE_GUARD_HPP
  11. #define BOOST_SIGNALS2_DETAIL_SCOPE_GUARD_HPP
  12. #if defined(_MSC_VER)
  13. #pragma once
  14. #endif
  15. #include <boost/core/no_exceptions_support.hpp>
  16. namespace boost{
  17. namespace signals2{
  18. namespace detail{
  19. /* This is a merely reformated version of
  20. * ScopeGuard.h as defined in:
  21. * Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You
  22. * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000,
  23. * http://www.drdobbs.com/184403758
  24. * with the following modifications:
  25. * - General pretty formatting (pretty to my taste at least.)
  26. * - Naming style changed to standard C++ library requirements.
  27. * - Removed RefHolder and ByRef, whose functionality is provided
  28. * already by Boost.Ref.
  29. * - Removed static make_guard's and make_obj_guard's, so that the code
  30. * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces
  31. * us to move some private ctors to public, though.
  32. *
  33. * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute
  34. * without an explicit qualification.
  35. *
  36. * TODO: Consider replacing with Boost.ScopeExit
  37. *
  38. */
  39. class scope_guard_impl_base
  40. {
  41. public:
  42. scope_guard_impl_base():dismissed_(false){}
  43. void dismiss()const{dismissed_=true;}
  44. protected:
  45. ~scope_guard_impl_base(){}
  46. scope_guard_impl_base(const scope_guard_impl_base& other):
  47. dismissed_(other.dismissed_)
  48. {
  49. other.dismiss();
  50. }
  51. template<typename J>
  52. static void safe_execute(J& j){
  53. BOOST_TRY{
  54. if(!j.dismissed_)j.execute();
  55. }
  56. BOOST_CATCH(...){}
  57. BOOST_CATCH_END
  58. }
  59. mutable bool dismissed_;
  60. private:
  61. scope_guard_impl_base& operator=(const scope_guard_impl_base&);
  62. };
  63. typedef const scope_guard_impl_base& scope_guard;
  64. template<class Obj,typename MemFun,typename P1,typename P2>
  65. class obj_scope_guard_impl2:public scope_guard_impl_base
  66. {
  67. public:
  68. obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2):
  69. obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2)
  70. {}
  71. ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
  72. void execute(){(obj_.*mem_fun_)(p1_,p2_);}
  73. protected:
  74. Obj& obj_;
  75. MemFun mem_fun_;
  76. const P1 p1_;
  77. const P2 p2_;
  78. };
  79. template<class Obj,typename MemFun,typename P1,typename P2>
  80. inline obj_scope_guard_impl2<Obj,MemFun,P1,P2>
  81. make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
  82. {
  83. return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2);
  84. }
  85. } /* namespace signals2::detail */
  86. } /* namespace signals2 */
  87. } /* namespace boost */
  88. #endif