formula.hpp

Go to the documentation of this file.
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