|
libpsynth 0.2.1
|
00001 00018 /* 00019 * Copyright (C) 2011 Juan Pedro BolĂvar Puente 00020 * 00021 * This file is part of Psychosynth. 00022 * 00023 * Psychosynth is free software: you can redistribute it and/or modify 00024 * it under the terms of the GNU General Public License as published by 00025 * the Free Software Foundation, either version 3 of the License, or 00026 * (at your option) any later version. 00027 * 00028 * Psychosynth is distributed in the hope that it will be useful, 00029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00031 * GNU General Public License for more details. 00032 * 00033 * You should have received a copy of the GNU General Public License 00034 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00035 * 00036 */ 00037 00038 #ifndef PSYNTH_BASE_SCOPE_GUARD_H_ 00039 #define PSYNTH_BASE_SCOPE_GUARD_H_ 00040 00041 #include <boost/utility.hpp> 00042 #include <psynth/base/util.hpp> 00043 00044 namespace psynth 00045 { 00046 namespace base 00047 { 00048 00049 class scope_guard_impl_base : public boost::noncopyable 00050 { 00051 public: 00052 void dismiss () const throw() 00053 { _dismissed = true; } 00054 00055 protected: 00056 scope_guard_impl_base () 00057 : _dismissed (false) {} 00058 00059 scope_guard_impl_base (scope_guard_impl_base&& other) 00060 : _dismissed (other._dismissed) 00061 { other.dismiss (); } 00062 00063 ~scope_guard_impl_base () {} // nonvirtual to allow polymorphic 00064 // behaviour. read the alexandrescu 00065 // article for details. 00066 00067 mutable bool _dismissed; 00068 }; 00069 00070 template <typename Fun> 00071 class scope_guard_impl : public scope_guard_impl_base 00072 { 00073 typedef scope_guard_impl_base base; 00074 public: 00075 scope_guard_impl (const Fun& fun) 00076 : _fun (fun) {} 00077 00078 scope_guard_impl (scope_guard_impl&& other) 00079 : base (std::move (other)) // TODO: Why is this needed? 00080 , _fun (other._fun) 00081 {} 00082 00083 ~scope_guard_impl () 00084 { 00085 if (!_dismissed) 00086 try { _fun (); } catch (...) { /* TODO: Handle error? */ } 00087 } 00088 00089 private: 00090 Fun _fun; 00091 }; 00092 00093 template <typename Fun> 00094 scope_guard_impl<Fun> make_guard (const Fun& fun) 00095 { 00096 return scope_guard_impl<Fun> (fun); 00097 } 00098 00099 typedef const scope_guard_impl_base& scope_guard; 00100 00101 #define PSYNTH_CONCATENATE_DIRECT(s1, s2) s1##s2 00102 #define PSYNTH_CONCATENATE(s1, s2) PSYNTH_CONCATENATE_DIRECT(s1, s2) 00103 #define PSYNTH_ANONYMOUS_VARIABLE(str) PSYNTH_CONCATENATE(str, __LINE__) 00104 00105 #define PSYNTH_ON_BLOCK_EXIT(f) \ 00106 ::psynth::base::scope_guard PSYNTH_ANONYMOUS_VARIABLE(scope_guard) = ::psynth::base::make_guard(f); ::psynth::base::ignore_unused_variable_warning (PSYNTH_ANONYMOUS_VARIABLE(scope_guard)) 00107 00108 } /* namespace base */ 00109 } /* namespace psynth */ 00110 00111 #endif /* PSYNTH_BASE_SCOPE_GUARD_H_ */
1.7.4