backup_type.hpp

Go to the documentation of this file.
00001 /* $Id: backup_type.hpp 19931 2010-06-05 12:16:12Z frosch $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef BACKUP_TYPE_HPP
00013 #define BACKUP_TYPE_HPP
00014 
00015 #include "../debug.h"
00016 
00022 template <typename T>
00023 struct Backup {
00030   Backup(T &original, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) {}
00031 
00039   template <typename U>
00040   Backup(T &original, const U &new_value, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line)
00041   {
00042     /* Note: We use a separate typename U, so type conversions are handled by assignment operator. */
00043     original = new_value;
00044   }
00045 
00049   ~Backup()
00050   {
00051     /* Check whether restoration was done */
00052     if (this->valid)
00053     {
00054       /* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
00055        * Exceptions are especially used to abort world generation. */
00056       DEBUG(misc, 0, "%s:%d: Backupped value was not restored!", this->file, this->line);
00057       this->Restore();
00058     }
00059   }
00060 
00065   bool IsValid() const
00066   {
00067     return this->valid;
00068   }
00069 
00074   const T &GetOriginalValue() const
00075   {
00076     assert(this->valid);
00077     return original_value;
00078   }
00079 
00085   template <typename U>
00086   void Change(const U &new_value)
00087   {
00088     /* Note: We use a separate typename U, so type conversions are handled by assignment operator. */
00089     assert(this->valid);
00090     original = new_value;
00091   }
00092 
00096   void Revert()
00097   {
00098     assert(this->valid);
00099     this->original = this->original_value;
00100   }
00101 
00105   void Trash()
00106   {
00107     assert(this->valid);
00108     this->valid = false;
00109   }
00110 
00114   void Restore()
00115   {
00116     this->Revert();
00117     this->Trash();
00118   }
00119 
00124   void Update()
00125   {
00126     assert(this->valid);
00127     this->original_value = this->original;
00128   }
00129 
00134   bool Verify() const
00135   {
00136     assert(this->valid);
00137     return this->original_value == this->original;
00138   }
00139 
00140 private:
00141   T &original;
00142   bool valid;
00143   T original_value;
00144 
00145   const char * const file;
00146   const int line;
00147 };
00148 
00149 #endif /* BACKUP_TYPE_HPP */