lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean Smart (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_SMART_SCOPE_GUARD 00006 #define LEAN_SMART_SCOPE_GUARD 00007 00008 #include "../lean.h" 00009 #include "../tags/noncopyable.h" 00010 #include "../functional/callable.h" 00011 00012 namespace lean 00013 { 00014 namespace smart 00015 { 00016 00018 class scope_annex_base : public nonassignable 00019 { 00020 private: 00021 mutable bool m_valid; 00022 00023 protected: 00025 LEAN_INLINE scope_annex_base() 00026 : m_valid(true) { } 00028 LEAN_INLINE scope_annex_base(const scope_annex_base &right) 00029 : m_valid(true) 00030 { 00031 right.m_valid = false; 00032 } 00033 LEAN_INLINE ~scope_annex_base() throw() { } 00034 00036 LEAN_INLINE bool valid() const { return m_valid; } 00037 }; 00038 00040 template <class Callable> 00041 class scope_annex_impl : public scope_annex_base 00042 { 00043 private: 00044 Callable m_callable; 00045 00046 public: 00048 LEAN_INLINE explicit scope_annex_impl(const Callable &callable) 00049 : m_callable(callable) { } 00051 LEAN_INLINE ~scope_annex_impl() 00052 { 00053 if (valid()) 00054 m_callable(); 00055 } 00056 }; 00057 00059 typedef const scope_annex_base& scope_annex; 00060 00062 template <class Callable> 00063 LEAN_INLINE scope_annex_impl<Callable> make_scope_annex(const Callable& callable) 00064 { 00065 return scope_annex_impl<Callable>(callable); 00066 } 00067 00069 template <class Signature> 00070 LEAN_INLINE scope_annex_impl< callable_fun<Signature> > make_scope_annex(Signature *fun) 00071 { 00072 return make_scope_annex( make_callable(fun) ); 00073 } 00074 00076 template <class Class, class Signature> 00077 LEAN_INLINE scope_annex_impl< callable_memfun<Class, Signature> > make_scope_annex(Class *obj, Signature Class::*fun) 00078 { 00079 return make_scope_annex( make_callable(obj, fun) ); 00080 } 00081 00083 class scope_guard_base : public nonassignable 00084 { 00085 private: 00086 mutable bool m_armed; 00087 00088 protected: 00090 LEAN_INLINE explicit scope_guard_base(bool arm = true) 00091 : m_armed(arm) { } 00093 LEAN_INLINE scope_guard_base(const scope_guard_base &right) 00094 : m_armed(right.m_armed) 00095 { 00096 right.disarm(); 00097 } 00098 LEAN_INLINE ~scope_guard_base() throw() { } 00099 00100 public: 00102 LEAN_INLINE void armed(bool arm) const { m_armed = arm; } 00104 LEAN_INLINE bool armed() const { return m_armed; } 00105 00107 LEAN_INLINE void disarm() const { armed(false); } 00109 LEAN_INLINE void arm() const { armed(true); } 00110 }; 00111 00113 typedef const scope_guard_base& scope_guard; 00114 00116 template <class Callable> 00117 class scope_guard_impl : public scope_guard_base 00118 { 00119 private: 00120 Callable m_callable; 00121 00122 public: 00124 LEAN_INLINE explicit scope_guard_impl(const Callable &callable, bool arm = true) 00125 : scope_guard_base(arm), 00126 m_callable(callable) { } 00128 LEAN_INLINE ~scope_guard_impl() 00129 { 00130 if (armed()) 00131 m_callable(); 00132 } 00133 }; 00134 00136 template <class Callable> 00137 LEAN_INLINE scope_guard_impl<Callable> make_scope_guard(const Callable& callable) 00138 { 00139 return scope_guard_impl<Callable>(callable); 00140 } 00141 00143 template <class Signature> 00144 LEAN_INLINE scope_guard_impl< callable_fun<Signature> > make_scope_guard(Signature *fun) 00145 { 00146 return make_scope_guard( make_callable(fun) ); 00147 } 00148 00150 template <class Class, class Signature> 00151 LEAN_INLINE scope_guard_impl< callable_memfun<Class, Signature> > make_scope_guard(Class *obj, Signature Class::*fun) 00152 { 00153 return make_scope_guard( make_callable(obj, fun) ); 00154 } 00155 00156 } // namespace 00157 00158 using smart::scope_annex; 00159 using smart::make_scope_annex; 00160 00161 using smart::scope_guard; 00162 using smart::make_scope_guard; 00163 00164 } // namespace 00165 00166 #endif