00001 /* $Id: formula.hpp 26650 2008-05-16 15:55:56Z mordante $ */ 00002 /* 00003 Copyright (C) 2008 by Mark de Wever <koraq@xs4all.nl> 00004 Part of the Battle for Wesnoth Project http://www.wesnoth.org/ 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License version 2 00008 or at your option any later version. 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY. 00011 00012 See the COPYING file for more details. 00013 */ 00014 00015 #ifndef __GUI_WIDGETS_FORMULA_HPP_INCLUDED__ 00016 #define __GUI_WIDGETS_FORMULA_HPP_INCLUDED__ 00017 00018 #include "formula_callable.hpp" 00019 #include "../../formula.hpp" 00020 #include "log.hpp" 00021 00022 #include <boost/static_assert.hpp> 00023 00024 #include <cassert> 00025 00026 namespace gui2{ 00027 00028 /** Template class can hold a value or a formula calculating the value. */ 00029 template <class T> 00030 class tformula 00031 { 00032 public: 00033 tformula<T>(const std::string& str); 00034 00035 /** 00036 * Returns the value, can only be used it the data is no formula. 00037 * 00038 * Another option would be to cache the output of the formula in value_ 00039 * and always allow this function. But for now decided that the caller 00040 * needs to do the caching. It might be changed later. 00041 */ 00042 T operator()() const 00043 { 00044 assert(!has_formula()); 00045 return value_; 00046 } 00047 00048 /** Returns the value, can always be used. */ 00049 T operator() (const game_logic::map_formula_callable& variables) const; 00050 00051 /** Determine whether the class contains a formula. */ 00052 bool has_formula() const { return !formula_.empty(); } 00053 00054 private: 00055 00056 /** Converts the string ot the template value. */ 00057 void convert(const std::string& str); 00058 00059 T execute(const game_logic::map_formula_callable& variables) const; 00060 00061 /** If there is a formula it's stored in this string, empty if no formula. */ 00062 std::string formula_; 00063 00064 /** If no formula it contains the value. */ 00065 T value_; 00066 00067 }; 00068 00069 template<class T> 00070 tformula<T>::tformula(const std::string& str) : 00071 formula_(), 00072 value_() 00073 { 00074 if(str.empty()) { 00075 return; 00076 } 00077 00078 if(str[0] == '(') { 00079 formula_ = str; 00080 } else { 00081 convert(str); 00082 } 00083 00084 } 00085 00086 template<class T> 00087 inline T tformula<T>::operator() (const game_logic::map_formula_callable& variables) const 00088 { 00089 if(has_formula()) { 00090 LOG_STREAM_INDENT(debug, gui_draw) << "Formula: execute '" << formula_ << "'.\n"; 00091 return execute(variables); 00092 } else { 00093 return value_; 00094 } 00095 } 00096 00097 template<> 00098 inline bool tformula<bool>::execute(const game_logic::map_formula_callable& variables) const 00099 { 00100 return game_logic::formula(formula_).execute(variables).as_bool(); 00101 } 00102 00103 template<> 00104 inline int tformula<int>::execute(const game_logic::map_formula_callable& variables) const 00105 { 00106 return game_logic::formula(formula_).execute(variables).as_int(); 00107 } 00108 00109 template<> 00110 inline unsigned tformula<unsigned>::execute(const game_logic::map_formula_callable& variables) const 00111 { 00112 return game_logic::formula(formula_).execute(variables).as_int(); 00113 } 00114 00115 template<> 00116 inline std::string tformula<std::string>::execute(const game_logic::map_formula_callable& variables) const 00117 { 00118 return game_logic::formula(formula_).execute(variables).as_string(); 00119 } 00120 00121 template<> 00122 inline t_string tformula<t_string>::execute(const game_logic::map_formula_callable& variables) const 00123 { 00124 return game_logic::formula(formula_).execute(variables).as_string(); 00125 } 00126 00127 template<class T> 00128 inline T tformula<T>::execute(const game_logic::map_formula_callable& variables) const 00129 { 00130 // Every type needs it's own execute function avoid instantiation of the 00131 // default execute. 00132 BOOST_STATIC_ASSERT(sizeof(T) == 0); 00133 return T(); 00134 } 00135 00136 template<> 00137 inline void tformula<bool>::convert(const std::string& str) 00138 { 00139 value_ = utils::string_bool(str); 00140 } 00141 00142 template<> 00143 inline void tformula<std::string>::convert(const std::string& str) 00144 { 00145 value_ = str; 00146 } 00147 00148 template<> 00149 inline void tformula<t_string>::convert(const std::string& str) 00150 { 00151 value_ = str; 00152 } 00153 00154 template<class T> 00155 inline void tformula<T>::convert(const std::string& str) 00156 { 00157 value_ = lexical_cast_default<T>(str); 00158 } 00159 00160 } // namespace gui2 00161 00162 #endif
Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |