From ddd49af722a6d3dc7661c1ced6e0ee124c8b28f0 Mon Sep 17 00:00:00 2001 From: Xiaobaibai <824395314@qq.com> Date: Fri, 14 Jun 2019 02:43:02 +0800 Subject: [PATCH] updated magical ExpressionBuilder (compile-time codegen) --- dlls/weapons/ExpressionBuilder.hpp | 77 +++++++++++++++++++---------- dlls/weapons/WeaponDataVaribles.hpp | 12 +++-- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/dlls/weapons/ExpressionBuilder.hpp b/dlls/weapons/ExpressionBuilder.hpp index ec9c3d15d..6a093760d 100644 --- a/dlls/weapons/ExpressionBuilder.hpp +++ b/dlls/weapons/ExpressionBuilder.hpp @@ -29,15 +29,26 @@ namespace ExpressionBuilder const UnderlyingType c; constexpr explicit ConstantType(UnderlyingType a) : c(a) {} template - constexpr UnderlyingType operator()(T x) const + constexpr ConstantType operator()(T x) const { - return c; + return ConstantType(c); // *this } constexpr operator UnderlyingType() const { return c; } }; + template + constexpr auto varcon(T x) -> typename std::enable_if::value, ConstantType>::type + { + return ConstantType(x); + } + template + constexpr auto varcon(T x) -> typename std::enable_if::value, T>::type + { + return x; + } + template - struct BindedType + struct BindedType : Expression { const Varible var; const Constant con; @@ -46,29 +57,29 @@ namespace ExpressionBuilder template constexpr auto operator()(T x) const -> BindedType { - return BindedType(var, con); + return BindedType(var.template operator()(x), con.template operator()(x)); } }; - template + template struct VaribleType : Expression { - template - constexpr auto operator=(UnderlyingType c) const -> BindedType, ConstantType> + template + constexpr auto operator=(T c) const -> BindedType, decltype(varcon(c))> { - return BindedType, ConstantType>(VaribleType(), ConstantType(c)); + return BindedType, decltype(varcon(c))>(VaribleType(), varcon(c)); } - template - constexpr auto operator()(BindedType, ConstantType> x) const -> UnderlyingType + template + constexpr auto operator()(BindedType, T> x) const -> decltype(x.con(x)) { - return x.con.c; + return x.con(x); } template - constexpr auto operator()(T x) const -> VaribleType + constexpr auto operator()(T x) const -> VaribleType { - return VaribleType(); + return VaribleType(); // *this } }; @@ -80,17 +91,6 @@ namespace ExpressionBuilder constexpr BinaryOperator(Exp1 a, Exp2 b) : _1(a), _2(b) {} }; - template - constexpr auto varcon(T x) -> typename std::enable_if::value, ConstantType>::type - { - return ConstantType(x); - } - template - constexpr auto varcon(T x) -> typename std::enable_if::value, T>::type - { - return x; - } - template struct OperatorPlus_t : BinaryOperator { @@ -134,25 +134,48 @@ namespace ExpressionBuilder { return OperatorPlus_t(varcon(_1), varcon(_2)); } + template + constexpr auto operator+(ConstantType _1, ConstantType _2) -> ConstantType + { + return ConstantType(_1.c + _2.c); + } template::value || IsExpression::value>::type> constexpr auto operator-(Exp1 _1, Exp2 _2) -> OperatorMinus_t { return OperatorMinus_t(varcon(_1), varcon(_2)); } + template + constexpr auto operator-(ConstantType _1, ConstantType _2) -> ConstantType + { + return ConstantType(_1.c - _2.c); + } template::value || IsExpression::value>::type> constexpr auto operator*(Exp1 _1, Exp2 _2) -> OperatorMul_t { return OperatorMul_t(varcon(_1), varcon(_2)); } + template + constexpr auto operator*(ConstantType _1, ConstantType _2) -> ConstantType + { + return ConstantType(_1.c * _2.c); + } template::value || IsExpression::value>::type> constexpr auto operator/(Exp1 _1, Exp2 _2) -> OperatorDiv_t { return OperatorDiv_t(varcon(_1), varcon(_2)); } + template + constexpr auto operator/(ConstantType _1, ConstantType _2) -> ConstantType + { + return ConstantType(_1.c / _2.c); + } + class x_id; + class y_id; + class z_id; } using detail::VaribleType; - constexpr const detail::VaribleType<'x'> x{}; - constexpr const detail::VaribleType<'y'> y{}; - constexpr const detail::VaribleType<'z'> z{}; + constexpr const detail::VaribleType x{}; + constexpr const detail::VaribleType y{}; + constexpr const detail::VaribleType z{}; } diff --git a/dlls/weapons/WeaponDataVaribles.hpp b/dlls/weapons/WeaponDataVaribles.hpp index a3d32e20e..c14d0aa8b 100644 --- a/dlls/weapons/WeaponDataVaribles.hpp +++ b/dlls/weapons/WeaponDataVaribles.hpp @@ -18,8 +18,14 @@ GNU General Public License for more details. namespace WeaponTemplate { namespace Varibles { - constexpr auto A = ExpressionBuilder::VaribleType<'A'>{}; - constexpr auto T = ExpressionBuilder::VaribleType<'T'>{}; - constexpr auto N = ExpressionBuilder::VaribleType<'N'>{}; + namespace detail + { + class id_A; + class id_T; + class id_N; + } + constexpr auto A = ExpressionBuilder::VaribleType{}; + constexpr auto T = ExpressionBuilder::VaribleType{}; + constexpr auto N = ExpressionBuilder::VaribleType{}; } }