Functorized Undo/Redo

One day, I was looking for the Undo/Redo algorithm to be used in my future project. Among different resources, I found DDJ, [1], where Al Stevens presented the template-based algorithm of Undo/Redo actions.

As far I got (unfortunately, on the Net there is no article available, just the source code at, its implementation addresses mostly document editors. Typical actions are: Insert, Delete, & Replace. The code seemed interesting, but its using was not obvious.

The idea to marry the algorithm with the functor was encouraging. So, this article presents what I eventually got.

Tested Software

The code was tested with MS Visual C++ 2003 and Windows 2000. Generally, you may run the code in any environment: Win32, Unix, ... Your compiler should be good with templates.

Source Code

undo.h: (modified Al Stevens code)

  • class UndoItem: a unit of the Undo/Redo action
  • class UndoData: encapsulates the containers of UndoItems (undos & redos)


  1. class UndoPar: Is for Undo/Redo parameters (Data)
  2. class UndoPar (
       UndoPar(const UndoPar& par);
       UndoPar& operator=(const UndPar& par);
       // rewind current parameter position
       void Rewind() {it_ = buffer_.begin(); }
       template <typename T> void AddPar( T par );
       template <typename T> T    GetPar();
       std::vector<char> buf_;               // parameters buffer
       std::vector<char>::iterator it_;      // current parameter
                                             // position
       static const size_t chunk_sz = 128;   // buffer reallocation
                                             // chunk

    Data are stored in the buf_ dynamic container. You may vary the size of the reallocation chunk. By default, I set it to 128 bytes.

    To store the data:

    UndoPar par;

    To get data back:

    UndoPar par;
    double d = par.GetPar<double>();
    int n    = par.GetPar<int>();
    short s  = par.GetPar<short>();

    In fact, you may use more complex structure data types instead of ordinary types.

  3. class UndoTarget: Is a base class for the classes supporting Undo/Redo functionality.
  4. class UndoTarget
       virtual ~UndoTarget() {}
       void fn(bool, UndoPar&);
    typedef (UndoTarget::* pfnType)(bool, UndoPar&);
  5. class Ftor: Functor.While applying operator(), the method that performs Undo/Redo is activated.
  6. class Ftor
       Ftor(UndoTarget* pobj, pfnType pfn) : pobj_(pobj),
           pfn_(pfn) {}
       void operator()(bool b, UndoPar& par)
          (pobj_->*pfn_)(b, par);
       UndoTarget* pobj_;
       pfnType     pfn_;
  7. class UndoRedo: Encapsulates functor to be activated while doing Undo/Redo, and the data to be applied.
  8. class UndoRedo
       UndoRedo(Ftor& ftor, UndoPar& par) :
                ftor_(ftor), undopar_(par) {}
       void Undo() {ftor_( false, undopar_ );}
       void Redo() {ftor_( true, undopar_ );}
       Ftor ftor_;
       UndoPar undopar_;    // undo/redo data
  9. class AppUndos: This class is in charge of Undo/Redo at the application level.
  10. class AppUndos : public UndoData<UndoRedo>
       explicit AppUndos(size_t nMaxUndos = MAX_UNDOS) :
          UndoData<UndoRedo>(nMaxUndos) {}
       void AddUndoItem(UndoRedo& f)
          UndoData<UndoRedo>::AddUndoItem( UndoAction(f) );

    Note that MAX_UNDOS may be any reasonable value.

  11. The files AppData.[h,cpp] are the example of the usage of the foregoing classes. They implement the Data class.
  12. class Data : public UndoTarget
       ~Data() {};
       void f1();
       void f2();
       void Dump( const char* ) const;
       void Undo() { m_undo.UndoLastAction(); }
       void Redo() { m_undo.RedoLastUndo(); }
       // signature of f1_ & f2_ must comply pfnType
       void f1_( bool, UndoPar& );    // false: undo, true: redo
       void f2_( bool, UndoPar& );
       std::vector<double> m_x;
       AppUndos                  m_undo;

Suppose our application can execute f1() on the array of the double data, m_x, X = a*(b*X+c)

void Data::f1()
   UndoPar par;
   par.AddPar<double>(5.);    // b
   par.AddPar<int>(2);        // a
   par.AddPar<short>(2);      // c

   f1_(true, par);

   UndoRedo ur( Ftor(this, (pfnType)f1_), par );
   m_undo.AddUndoItem( ur ); 

f1_() is called:

  1. Directly to make caculations.
  2. Indirectly (functor is activated) when doing Undo() or Redo().


Project MyUndo0

Unzip the source code that is supplied. The EXE file is already in the Release folder.

Project MyUndo

This uses Alexandrescu's generalized functors, [2]. You should have the Loki library ([3]) installed. Project Directories Properties assumes that the MyUndo folder is at the same level with Loki Level. SmallObj.cpp is already in the MyUndo folder and includes the "stdafx.h" header.

The test is the Win32 console application. Initially, an array of double values is: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

Function f1 makes X = 2*(5.*X + 2)
Function f2 makes X = 2.45*x + 1

The following sequence is applied:


Each data modification is followed by dumping the current values on the console. Logically, with such a sequence applied, we should end up with values equal to those before the calculations.


The presented functorized Undo/Redo classes are really helpful because:

  1. They are portable because they're made on pure C++.
  2. Their application may vary: data processing, text editors ... (due to a dynamic undo-data buffer allocation that is able to store information of any kind).


  1. Dr. Dobb's Journal, November 1998
  2. Alexandrescu, Andrei. Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley, 2001
  3. Loki's library source code:



  • That Is The Best Herbal Male Augmentation or Erectile Dysfunction Product?

    Posted by apeeffifielm on 06/21/2013 06:31am

    Do Home Erectile Dysfunction Pills Bring About Stronger And Rock Hard Erection? a condition in which an erection lasts for longer than 4 hours [url= ] viagra women depression [/url] see additional Erectile Dysfunction: - Signs And Symptoms, Causes and Treatment

  • yutewa

    Posted by Mandyoiq on 03/29/2013 05:44am

    ghd hair straightener,Shanghai is bounded by the northern markets for Huasheng, the South by respect for arrived sheep. Huasheng Textile Factory with a cotton textile mills are arrived sheep provided, although this is Li Hongzhang had to dredge Tan Zhonglin made concessions, but also Sheng Xuanhuai want to focus Exhibition weaving industry due. Reduce the cost of reconstruction wasted. Cotton yarn and market allocation. Although the two failed to reach agreements for what on paper, but they act in harmony designated as the boundary interfere with each other, because of the soaring price of cotton yarn to. Arrived in sheep to Huasheng production also lower than the market price. Two has thousands of silk Wan hunchback contact Sheng Xuanhuai, and Tan Yankai the two terms of ghd hair straightener has as landlord to invite each other and to accept each other as guests invited places obligations. The Sheng Xuanhuai home is in the outskirts of a yard, outside the Park within the luxury country house, and Li, Sheng prefer Westernization - unless ghd To see Li and other identity is much higher than the ghd straightener , or ghd sale wearing suits and ties.

  • vejqvr

    Posted by Suttonykw on 03/28/2013 02:27pm Ning Caihua this time already Pie Zhuozui his eyes looked with envy still Su drizzle arms hematemesis stay silly, beautiful girls so concerned with the ray ban clubmaster, I am afraid that is also willing to spit oakley sunglasses a blood test. Xiao Feng heard the drizzle words Su and did not say anything, just the blood ejected by the left hand facing the ground Wei Dabao trick, that the blood have blown oakley sunglasses discount in the hands of the formation of a blood cell. Then cheap oakley sunglasses used his right hand whither point in the blood cells, and then even try with their tongues that blood. ray ban glasses the strange performance let ray ban aviators people face to face and peep ray ban aviators do not know in the end want to do. No wonder ... but a little pity. Looked at of Xiao Feng shook his head and looked at that group of their own hands, Wei Dabao just spit blood, and this time everyone even if do not know ray ban aviators specifically just what, but also be able to guess ray ban aviators necessarily Wei Dabao blood in is something, perhaps the thing that makes the big treasure Wei as odd habit.

  • cheap ugg boots xLoa wAub

    Posted by Suttongpc on 03/09/2013 11:44am

    cheap nike air max 90 gjwfvnjm cheap nike air max esznmlxu nike air max 1 qkaqpebt nike air max 90 kjtmsxnp nike air max 95 rprirdlg nike air max pusbemnp nike free run ryialojg nike store uk saohctbz nike uk anuqwljt

  • ghd australia dlisnk

    Posted by Mandygxn on 02/07/2013 10:45am

    0tNly ugg jWul xErn nike shox sko 4dEgk toms outlet 4lZah hollister 4tGol ugg 2sGwh longchamps 9rKkv louis vuitton outlet 5uYfw michael kors outlet 9zXvz christian louboutin 4rNna Anthony Davis Jersey 9iCag 4vUcx 2oVzz ghd 4lMit cheap uggs

  • mfzqor odrwuh

    Posted by PambInabe on 11/18/2012 10:15am

    mephz vseiw bottes genre ugg ugg paris bottes ugg soldes avis tynsw rcfqle Functorized Undo/Redo jcepzih bottes ugg new york bottes ugg bottes ugg plumdale rjycryl jpjdw ダウンジャケット モンクレール レディース モンクレール 2012 レディースモンクレール raabbksn モンクレールのダウンジャケット モンクレール 2012 モンクレール レディース ikbkiubt

  • vyqsntin rimjcqyy tymhe

    Posted by felmfeelpbaxy on 11/17/2012 01:14pm

    hhpkb yxeqj abercrombie sdupp aadoni Functorized Undo/Redo lgrbxnp abercrombie paris dzvrjrh eksxk sac louis vuitton pas cher pxamtuwb sac louis vuitton pas cher vcuggsdk louboutin jxbqnvzf

  • cggtdojq nwoukvys ujpnjcpa bhlsrr

    Posted by rootlyJerie on 11/16/2012 11:32pm

    qanmio jzcocf moncler doudoune dvylgfqh doudoune moncler hxakvxm furfqnd sxshi Functorized Undo/Redo hpbsgle timberland sale bpngjmjo ghd outlet uk ivlbikat moncler paris zzcipxdt

  • christian louboutin shoes burlesque

    Posted by boowiffRodial on 11/14/2012 04:53am

    Functorized Undo/Redo psgjrh eqxoonh vdqgmf coach outlet williamsburg coach purses coach handbags ebay fake rfzwmna zehztkap christian louboutin shoes online cheap christian louboutin okhvfhu moxna オーストラリア ugg ugg ブーツ ugg 正規品 xquwvjnw moncler japan モンクレール ダウン moncler beams zvxurhrd

  • christian louboutin shoes uk online

    Posted by Ralclabycer on 11/12/2012 09:26pm

    Functorized Undo/Redo ltvfck zvbzzaw btlkej christian louboutin shoes edinburgh christian louboutin cheap christian louboutin outlet vegas kkgxqzf iohnkcbf ugg outlet vaughan mills ugg boots ugg boots ebay size 10 fkyzohf xghxh louis vuitton handbags vintage louis vuitton bags louis vuitton outlet locations in new jersey etxljdxr beats by dre yelawolf cheap beats cheap beats by dre monster yrvtykqb

  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

  • As the mobile enterprise marketplace expands and customer needs grow more diverse, Samsung recognizes that solution partners and developers play an essential role by continually innovating to meet their customers' needs. Samsung works to provide these developers and partners with the latest tools and resources needed to create these solutions. Read this program guide to learn how the Samsung Enterprise Alliance Program provides partners and developers with Samsung enterprise software development kits (SDKs) …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date