Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoModBoard.h

Go to the documentation of this file.
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


Sun Mar 13 2011 Doxygen 1.7.1