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
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