00001 //---------------------------------------------------------------------------- 00002 /** @file HexModState.h */ 00003 //---------------------------------------------------------------------------- 00004 00005 #ifndef HEXMODBOARD_HPP 00006 #define HEXMODBOARD_HPP 00007 00008 #include "HexStateAssertRestored.hpp" 00009 00010 _BEGIN_BENZENE_NAMESPACE_ 00011 00012 //---------------------------------------------------------------------------- 00013 00014 /** Make a const board temporarily modifiable. 00015 Allows functions to use a const state for performing temporary 00016 operations (e.g. searches), as long as the state is the same state 00017 after the function is finished. This class facilitates 00018 const-correctness and encapsulation, because it allows the owner 00019 of a state, which is the only one who is allowed to do persistent 00020 changes on the board, to hand out only a const reference to other 00021 code. The other code can still use the board for temporary 00022 operations without needing a copy of the board. HexModState does 00023 a const_cast from the const reference to a non-const reference in 00024 its constructor and checks with HexStateAssertRestored in its 00025 destructor that the board is returned in the same state. 00026 00027 Example: 00028 @code 00029 // myFunction is not supposed to do persistent changes on the board 00030 // and therefore gets a const-reference. However it wants to use 00031 // the board temporarily 00032 void myFunction(const HexState& constState) 00033 { 00034 HexModState modState(constState); 00035 HexState& state = modState.State(); // get a nonconst-reference 00036 00037 // ... play some moves and undo them 00038 00039 // end of lifetime for modState, HexStateAssertRestored is 00040 // automatically called in the destructor of modBoard 00041 } 00042 @endcode 00043 00044 There are also functions that allow to lock and unlock the board 00045 explicitly, for cases in which the period of temporary modifications 00046 cannot be mapped to the lifetime of a HexModState instance (e.g. because 00047 the period starts end ends in different functions). 00048 */ 00049 class HexModState 00050 { 00051 public: 00052 /** Constructor. 00053 Remembers the current board state. 00054 @param state The state 00055 @param locked Whether to start in locked mode (for explicit usage 00056 of Lock() and Unlock()) 00057 */ 00058 HexModState(const HexState& state, bool locked = false); 00059 00060 /** Destructor. 00061 Checks with assertions that the board state is restored. 00062 */ 00063 ~HexModState(); 00064 00065 /** Explicit conversion to non-const reference. 00066 This function triggers an assertion, if the board is currently in 00067 locked mode. 00068 */ 00069 HexState& State() const; 00070 00071 /** Automatic conversion to non-const reference. 00072 Allows to pass HexModState to functions that expect a non-const GoBoard 00073 reference without explicitely calling HexModState.Board(). 00074 See State() 00075 */ 00076 operator HexState&() const; 00077 00078 /** Explicitly unlock the board. */ 00079 void Unlock(); 00080 00081 /** Explicitly lock the board. 00082 Checks with assertions that the board state is restored. 00083 See Lock() 00084 */ 00085 void Lock(); 00086 00087 private: 00088 bool m_locked; 00089 00090 HexState& m_state; 00091 00092 HexStateAssertRestored m_assertRestored; 00093 }; 00094 00095 inline HexModState::HexModState(const HexState& state, bool locked) 00096 : m_locked(locked), 00097 m_state(const_cast<HexState&>(state)), 00098 m_assertRestored(state) 00099 { 00100 } 00101 00102 inline HexModState::~HexModState() 00103 { 00104 // Destructor of m_assertRestored calls AssertRestored() 00105 } 00106 00107 inline HexModState::operator HexState&() const 00108 { 00109 return State(); 00110 } 00111 00112 inline HexState& HexModState::State() const 00113 { 00114 SG_ASSERT(! m_locked); 00115 return m_state; 00116 } 00117 00118 inline void HexModState::Unlock() 00119 { 00120 m_assertRestored.Init(m_state); 00121 m_locked = false; 00122 } 00123 00124 inline void HexModState::Lock() 00125 { 00126 m_assertRestored.AssertRestored(); 00127 m_assertRestored.Clear(); 00128 m_locked = true; 00129 } 00130 00131 //---------------------------------------------------------------------------- 00132 00133 _END_BENZENE_NAMESPACE_ 00134 00135 #endif // HEXMODBOARD_HPP