Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

ChangeLog.hpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef CHANGELOG_HPP
00007 #define CHANGELOG_HPP
00008 
00009 #include <list>
00010 #include <vector>
00011 #include <string>
00012 #include <sstream>
00013 #include "Benzene.hpp"
00014 
00015 _BEGIN_BENZENE_NAMESPACE_
00016 
00017 //----------------------------------------------------------------------------
00018 
00019 /** General purpose changelog; allows incremental changes made to a
00020     datastructure to be undone quickly.
00021     
00022     A changelog is a stack that tracks the changes to some data
00023     structure with data type T.  There are three actions: ADD, REMOVE,
00024     and MARKER.  And ADD action means the data was recently added to the
00025     datastructure, and REMOVE means it was recently removed.  MARKER is
00026     used to mark how far back to go when you want to undo the changes
00027     made.
00028 */
00029 template<typename T>
00030 class ChangeLog
00031 {
00032 public:
00033 
00034     /** Constructor. */
00035     ChangeLog();
00036 
00037     /** Available actions. */
00038     typedef enum {ADD, REMOVE, PROCESSED, MARKER} Action;
00039 
00040     /** Returns true if changelog is empty. */
00041     bool empty() const;
00042 
00043     /** Returns size of changelog. */
00044     int size() const;
00045 
00046     /** Adds an entry onto the changelog. */
00047     void push(Action action, const T& data);
00048 
00049     /** Pops the top entry off of the changelog. Asserts log is not
00050     empty.
00051     */
00052     void pop();
00053 
00054     /** Returns the action on top of the changelog. Asserts log is not
00055     empty.
00056         
00057         @todo how to write this method using the 'inline' syntax?  I
00058         keep getting compile errors.
00059     */
00060     Action topAction() const { assert(!empty()); return m_action.back(); }
00061 
00062     /** Returns a copy of the data on top of the changelog. Asserts log is
00063     not empty.
00064     */
00065     T topData() const;
00066 
00067     /** Clears the log. */
00068     void clear();
00069 
00070     /** Dump the contents of the log to a string. */
00071     std::string dump() const;
00072 
00073 private:
00074     std::vector<T> m_data;
00075     std::vector<Action> m_action;
00076 };
00077 
00078 template<typename T>
00079 inline ChangeLog<T>::ChangeLog()
00080 {
00081 }
00082 
00083 template<typename T> 
00084 inline bool ChangeLog<T>::empty() const
00085 {
00086     return m_action.empty();
00087 }
00088 
00089 template<typename T> 
00090 inline int ChangeLog<T>::size() const
00091 {
00092     return m_action.size();
00093 }
00094 
00095 template<typename T> 
00096 inline void ChangeLog<T>::push(Action action, const T& data)
00097 {
00098     m_action.push_back(action);
00099     m_data.push_back(data);
00100 }
00101 
00102 template<typename T>
00103 inline void ChangeLog<T>::pop()
00104 {
00105     assert(!empty());
00106     m_action.pop_back();
00107     m_data.pop_back();
00108 }
00109 
00110 template<typename T>
00111 inline T ChangeLog<T>::topData() const
00112 {
00113     assert(!empty());
00114     return m_data.back();
00115 }
00116 
00117 /// @todo vector::clear() takes linear time.  Is this a problem?
00118 template<typename T>
00119 inline void ChangeLog<T>::clear()
00120 {
00121     m_action.clear();
00122     m_data.clear();
00123 }
00124 
00125 template<typename T>
00126 std::string ChangeLog<T>::dump() const
00127 {
00128     std::ostringstream os;
00129 
00130     for (int i=0; i<(int)m_action.size(); ++i) {
00131         os << i << ": ";
00132         if (m_action[i] == MARKER)
00133             os << "MARKER";
00134         else {
00135             if (m_action[i] == ADD)
00136                 os << "   ADD: ";
00137             else if (m_action[i] == REMOVE)
00138                 os << "REMOVE: ";
00139             else if (m_action[i] == PROCESSED)
00140                 os << "PROCESSED: ";
00141             os << m_data[i];
00142         }
00143         os << std::endl;
00144     }
00145     return os.str();
00146 }
00147 
00148 //----------------------------------------------------------------------------
00149 
00150 _END_BENZENE_NAMESPACE_
00151 
00152 #endif // CHANGELOG_HPP


6 Jan 2011 Doxygen 1.6.3