//
Purpose.  Memento design pattern
//
1. Assign the roles of "caretaker" and "originator"
//
2. Create a "memento" class and declare the originator a friend
//
3. Caretaker knows when to "check point" the originator
// 4.
Originator creates a memento and copies its state to the memento
// 5.
Caretaker holds on to (but cannot peek in to) the memento
// 6. Caretaker
knows when to "roll back" the originator
// 7. Originator
reinstates itself using the saved state in the memento
#include
<iostream>   #include
<string>   using namespace
std;
class Memento {                   // 2. Create a "memento" class
and
   friend class Stack;            //    declare the originator a friend
   int *items, num;
  
Memento( int* arr, int n ) {
     
items = new int[num = n];
     
for (int i=0; i < num; i++) items[i] = arr[i]; }
public:
   ~Memento() { delete items; }
};
class
Stack {                     // 1. Stack
is the "originator"
  
int  items[10], sp;
public:
   Stack()                 { sp = -1; }
   void     push( int in ) {
items[++sp] = in; }
   int      pop()          { return items[sp--]; }
   bool     isEmpty()      { return sp == -1; }
   // 4. Originator creates a memento and
copies its state to the memento
  
Memento* checkPoint() {
     
return new Memento( items, sp+1 );
   }
   // 7.
Originator reinstates itself using the saved state in the memento
   void rollBack( Memento* m ) {
      sp = m->num-1;
      for (int i=0; i < m->num; i++)
items[i] = m->items[i];
  
}
   friend ostream&
operator<< ( ostream& os, 
const Stack& s ) {
     
string buf( "[ " );
     
for (int i=0; i < s.sp+1; i++) { buf += s.items[i]+48;  buf += ' '; }
      buf += ']';
      return os << buf;                   // stack is [ 0 1 2 3 4
]
}  };                                     // stack is [ 0 1 2 3 4 5 6 7
8 9 ]
                                          // popping stack: 9 8 7 6
5 4 3 2 1 0
// 1. main() is the "caretaker"           // stack is [ ]
void main(
void ) {                       // second
is [ 0 1 2 3 4 5 6 7 8 9 ]    
  
Stack s;                              
// first is [ 0 1 2 3 4 ]
  
for (int i=0; i < 5; i++) s.push( i ); // popping stack: 4 3 2 1
0
   cout << "stack is
" << s << endl;     
   Memento* first =
s.checkPoint();       // 3. Caretaker
knows when to save
   for (i=5; i
< 10; i++) s.push( i );    // 5.
Caretaker holds on to memento
  
cout << "stack is " << s << endl;      
  
Memento* second = s.checkPoint();     
// 3. Caretaker knows when to save
   cout << "popping stack: ";             // 5. Caretaker holds on to
memento
   while ( ! s.isEmpty())
cout << s.pop() << ' '; 
cout << endl;
   cout
<< "stack is " << s << endl;
   s.rollBack( second );                  // 6. Caretaker knows when
to undo
   cout <<
"second is " << s << endl;
   s.rollBack( first );                   // 6. Caretaker knows when
to undo
   cout <<
"first is " << s << endl;
   cout << "popping stack: ";
   while ( ! s.isEmpty()) cout <<
s.pop() << ' ';  cout <<
endl;
   delete first;  delete second;
}
//
Purpose.  Memento design pattern
//
// Discussion.  A memento is an
object that stores a snapshot of the
// internal state of another
object.  It can be leveraged to
support
// multi-level undo of the Command pattern.  In this example, before a
// command is
run against the Number object, Number's current state is
// saved in
Command's static memento history list, and the command itself
// is saved
in the static command history list. 
Undo() simply "pops" the
// memento history list and
reinstates Number's state from the memento.
// Redo() "pops" the
command history list.  Note that
Number's encapsula-
// tion is preserved, and Memento is wide open to
Number.
#include <iostream.h>
class Number;
class
Memento {
public:
   Memento(
int val ) { _state = val; }
private:
   friend class Number;  //
not essential, but p287 suggests this
  
int  _state;
};
class
Number {
public:
   Number(
int value )                    { _value
= value; }
   void dubble()                          { _value = 2 *
_value; }
   void half()                            { _value = _value / 2; }
   int getValue()                         { return _value; }
   Memento* createMemento()               { return new Memento( _value );
}
   void  reinstateMemento( Memento* mem ) { _value = mem->_state ;
}
private:
   int
_value;
};
class Command {
public:
   typedef void (Number::* Action)();
   Command( Number* receiver, Action action )
{
      _receiver = receiver;
      _action = action; }
   virtual void execute() {
      _mementoList[_numCommands] =
_receiver->createMemento();
     
_commandList[_numCommands] = this;
      if (_numCommands > _highWater) _highWater =
_numCommands;
     
_numCommands++;
     
(_receiver->*_action)(); }
  
static void undo() {
     
if (_numCommands == 0) {
        
cout << "*** Attempt to run off the end!! ***" <<
endl;
         return; }
     
_commandList[_numCommands-1]->_receiver->
         reinstateMemento(
_mementoList[_numCommands-1] );
     
_numCommands--; }
   void
static redo() {
      if
(_numCommands > _highWater) {
         cout << "*** Attempt to run
off the end!! ***" << endl;
         return; }
     
(_commandList[_numCommands]->_receiver->
        
*(_commandList[_numCommands]->_action))();
      _numCommands++; }
protected:
    Number*         _receiver;
  
Action          _action;
   static Command* _commandList[20];
   static Memento* _mementoList[20];
   static int      _numCommands;
  
static int      _highWater;
};
Command*
Command::_commandList[];
Memento* Command::_mementoList[];
int      Command::_numCommands = 0;
int      Command::_highWater   = 0;
void main() {
   int i;
   cout << "Integer: ";
   cin >> i;
   Number*  
object = new Number(i);
  
Command*  commands[3];
   commands[1] = new Command( object,
&Number::dubble );
  
commands[2] = new Command( object, &Number::half );
   cout << "Exit[0], Double[1],
Half[2], Undo[3], Redo[4]: ";
  
cin >> i;
  
while (i)
   {
      if (i == 3)
         Command::undo();
      else if (i == 4)
         Command::redo();
      else
         commands[i]->execute();
      cout << "  
" << object->getValue() << endl;
      cout << "Exit[0], Double[1],
Half[2], Undo[3], Redo[4]: ";
     
cin >> i;
   }
}
//
Integer: 11
// Exit[0], Double[1], Half[2], Undo[3], Redo[4]: 2
//    5
// Exit[0], Double[1], Half[2],
Undo[3], Redo[4]: 1
//    10
//
Exit[0], Double[1], Half[2], Undo[3], Redo[4]: 2
//    5
// Exit[0], Double[1], Half[2],
Undo[3], Redo[4]: 3
//    10
//
Exit[0], Double[1], Half[2], Undo[3], Redo[4]: 3
//    5
// Exit[0], Double[1], Half[2],
Undo[3], Redo[4]: 3
//    11
//
Exit[0], Double[1], Half[2], Undo[3], Redo[4]: 3
// *** Attempt to run off
the end!! ***
//    11
//
Exit[0], Double[1], Half[2], Undo[3], Redo[4]: 4
//    5
// Exit[0], Double[1], Half[2],
Undo[3], Redo[4]: 4
//    10
//
Exit[0], Double[1], Half[2], Undo[3], Redo[4]: 4
//    5
// Exit[0], Double[1], Half[2],
Undo[3], Redo[4]: 4
// *** Attempt to run off the end!! ***
//    5