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