From: <tz...@us...> - 2006-05-28 23:41:35
|
Revision: 1833 Author: tzlaine Date: 2006-05-28 16:41:32 -0700 (Sun, 28 May 2006) ViewCVS: http://svn.sourceforge.net/freeorion?rev=1833&view=rev Log Message: ----------- Added a StaticCast subclass of ValueRef::Variable that allows the type of a Variable to be cast to another type. Also added logic to the ValueRefParser to introduce such a cast into the Variable<double> parser, allowing Variable<int>s to be used therein. Modified Paths: -------------- trunk/FreeOrion/universe/ValueRef.h trunk/FreeOrion/universe/ValueRefParser.cpp Modified: trunk/FreeOrion/universe/ValueRef.h =================================================================== --- trunk/FreeOrion/universe/ValueRef.h 2006-05-28 21:29:19 UTC (rev 1832) +++ trunk/FreeOrion/universe/ValueRef.h 2006-05-28 23:41:32 UTC (rev 1833) @@ -26,6 +26,7 @@ template <class T> struct ValueRefBase; template <class T> struct Constant; template <class T> struct Variable; + template <class FromType, class ToType> struct StaticCast; template <class T> struct Operation; enum OpType { PLUS, @@ -63,7 +64,7 @@ T m_value; }; -/** the variable value leaf ValueRef class. The value returned by this node is taken from either the \a source or \a target parameters to Eval. */ +/** the variable value ValueRef class. The value returned by this node is taken from either the \a source or \a target parameters to Eval. */ template <class T> struct ValueRef::Variable : public ValueRef::ValueRefBase<T> { @@ -78,11 +79,29 @@ virtual std::string Description() const; virtual std::string Dump() const; +protected: + Variable(bool source_ref, const std::vector<std::string>& property_name); + private: bool m_source_ref; std::vector<std::string> m_property_name; }; +/** the variable static_cast class. The value returned by this node is taken from the ctor \a value_ref parameter's FromType value, + static_cast to ToType. */ +template <class FromType, class ToType> +struct ValueRef::StaticCast : public ValueRef::Variable<ToType> +{ + StaticCast(const ValueRef::Variable<FromType>* value_ref); + + virtual double Eval(const UniverseObject* source, const UniverseObject* target) const; + virtual std::string Description() const; + virtual std::string Dump() const; + +private: + const ValueRefBase<FromType>* m_value_ref; +}; + /** an arithmetic operation node ValueRef class. One of addition, subtraction, mutiplication, division, or unary negation is performed on the child(ren) of this node, and the result is returned. */ template <class T> @@ -181,6 +200,12 @@ {} template <class T> +ValueRef::Variable<T>::Variable(bool source_ref, const std::vector<std::string>& property_name) : + m_source_ref(source_ref), + m_property_name(property_name) +{} + +template <class T> bool ValueRef::Variable<T>::SourceRef() const { return m_source_ref; @@ -243,6 +268,33 @@ } /////////////////////////////////////////////////////////// +// StaticCast // +/////////////////////////////////////////////////////////// +template <class FromType, class ToType> +ValueRef::StaticCast<FromType, ToType>::StaticCast(const ValueRef::Variable<FromType>* value_ref) : + ValueRef::Variable<ToType>(value_ref->SourceRef(), value_ref->PropertyName()), + m_value_ref(value_ref) +{} + +template <class FromType, class ToType> +double ValueRef::StaticCast<FromType, ToType>::Eval(const UniverseObject* source, const UniverseObject* target) const +{ + return static_cast<ToType>(m_value_ref->Eval(source, target)); +} + +template <class FromType, class ToType> +std::string ValueRef::StaticCast<FromType, ToType>::Description() const +{ + return m_value_ref->Description(); +} + +template <class FromType, class ToType> +std::string ValueRef::StaticCast<FromType, ToType>::Dump() const +{ + return m_value_ref->Dump(); +} + +/////////////////////////////////////////////////////////// // Operation // /////////////////////////////////////////////////////////// template <class T> Modified: trunk/FreeOrion/universe/ValueRefParser.cpp =================================================================== --- trunk/FreeOrion/universe/ValueRefParser.cpp 2006-05-28 21:29:19 UTC (rev 1832) +++ trunk/FreeOrion/universe/ValueRefParser.cpp 2006-05-28 23:41:32 UTC (rev 1833) @@ -24,6 +24,7 @@ typedef ValueRef::ValueRefBase<T> RefBase; typedef ValueRef::Constant<T> RefConst; typedef ValueRef::Variable<T> RefVar; + typedef ValueRef::Variable<int> IntRefVar; typedef ValueRef::Operation<T> RefOp; typedef typename ValueRefRule<T>::type Rule; @@ -32,10 +33,12 @@ private: void SpecializedInit(); + void SpecializedVarDefinition(); Rule constant; Rule variable_container; Rule variable_final; + Rule int_variable_final; Rule variable; Rule primary_expr; Rule negative_expr; @@ -57,19 +60,19 @@ template <class T> ValueRefParserDefinition<T>::ValueRefParserDefinition(Rule& expr) { + int_variable_final = + str_p("owner") + | "id" + | "creationturn" + | "age"; + SpecializedInit(); variable_container = str_p("planet") | "system"; - variable = - str_p("source") >> '.' >> (!(variable_container >> ".") >> variable_final) - [variable.this_ = new_<RefVar>(val(true), construct_<std::string>(arg1, arg2))] - | str_p("target") >> '.' >> (!(variable_container >> ".") >> variable_final) - [variable.this_ = new_<RefVar>(val(false), construct_<std::string>(arg1, arg2))] - | str_p("currentturn") - [variable.this_ = new_<RefVar>(val(false), construct_<std::string>(arg1, arg2))]; + SpecializedVarDefinition(); primary_expr = constant[primary_expr.this_ = arg1] @@ -106,11 +109,7 @@ real_p[constant.this_ = new_<RefConst>(static_cast_<int>(arg1))] | int_p[constant.this_ = new_<RefConst>(arg1)]; - variable_final = - str_p("owner") - | "id" - | "creationturn" - | "age"; + variable_final = int_variable_final; } template <> @@ -206,4 +205,43 @@ variable_final = str_p("primaryfocus") | "secondaryfocus"; } + + template <class T> + void ValueRefParserDefinition<T>::SpecializedVarDefinition() + { + variable = + str_p("source") >> '.' >> (!(variable_container >> ".") >> variable_final) + [variable.this_ = new_<RefVar>(val(true), construct_<std::string>(arg1, arg2))] + | str_p("target") >> '.' >> (!(variable_container >> ".") >> variable_final) + [variable.this_ = new_<RefVar>(val(false), construct_<std::string>(arg1, arg2))]; + } + + template <> + void ValueRefParserDefinition<int>::SpecializedVarDefinition() + { + variable = + str_p("source") >> '.' >> (!(variable_container >> ".") >> variable_final) + [variable.this_ = new_<RefVar>(val(true), construct_<std::string>(arg1, arg2))] + | str_p("target") >> '.' >> (!(variable_container >> ".") >> variable_final) + [variable.this_ = new_<RefVar>(val(false), construct_<std::string>(arg1, arg2))] + | str_p("currentturn") + [variable.this_ = new_<RefVar>(val(false), construct_<std::string>(arg1, arg2))]; + } + + template <> + void ValueRefParserDefinition<double>::SpecializedVarDefinition() + { + typedef ValueRef::StaticCast<int, double> CastRefVar; + variable = + str_p("source") >> '.' >> (!(variable_container >> ".") >> variable_final) + [variable.this_ = new_<RefVar>(val(true), construct_<std::string>(arg1, arg2))] + | str_p("source") >> '.' >> (!(variable_container >> ".") >> int_variable_final) + [variable.this_ = new_<CastRefVar>(new_<IntRefVar>(val(true), construct_<std::string>(arg1, arg2)))] + | str_p("target") >> '.' >> (!(variable_container >> ".") >> variable_final) + [variable.this_ = new_<RefVar>(val(false), construct_<std::string>(arg1, arg2))] + | str_p("target") >> '.' >> (!(variable_container >> ".") >> int_variable_final) + [variable.this_ = new_<CastRefVar>(new_<IntRefVar>(val(false), construct_<std::string>(arg1, arg2)))] + | str_p("currentturn") + [variable.this_ = new_<CastRefVar>(new_<IntRefVar>(val(false), construct_<std::string>(arg1, arg2)))]; + } } |