00001 #ifndef UTILMM_AUTOFLAG_H 00002 #define UTILMM_AUTOFLAG_H 00003 00004 #include <boost/noncopyable.hpp> 00005 00006 namespace utilmm 00007 { 00010 template<typename T> 00011 class auto_flag 00012 : private boost::noncopyable 00013 { 00014 int& m_field; 00015 int m_mask; 00016 bool m_restore; 00017 00018 public: 00019 auto_flag(int& field, int mask, bool value = true, bool restore_old = true) 00020 : m_field(field), m_mask(mask) 00021 , m_restore(restore_old ? get() : !value) 00022 { 00023 set(value); 00024 } 00025 00026 ~auto_flag() { set(m_restore); } 00027 00028 bool get() { return (m_field & m_mask) == m_mask; } 00029 void set(bool value) 00030 { m_field = (m_field & ~m_mask) | (m_mask * static_cast<int>(value)); } 00031 00032 00033 }; 00034 00035 template<> 00036 class auto_flag<bool> 00037 : private boost::noncopyable 00038 { 00039 bool& m_flag; 00040 bool m_restore; 00041 00042 // Safe bool idiom 00043 struct safe_bool_struct 00044 { void method(); }; 00045 typedef void (safe_bool_struct::*safe_bool)(); 00046 00047 public: 00052 auto_flag(bool& flag, bool init = true, bool restore_old = true) 00053 : m_flag(flag), m_restore(restore_old ? flag : !init) 00054 { m_flag = init; } 00055 00059 ~auto_flag() { m_flag = m_restore; } 00060 00063 bool get() const { return m_flag; } 00064 00065 operator safe_bool() const { return m_flag ? &safe_bool_struct::method : 0; } 00066 }; 00067 00068 } 00069 00070 #endif 00071