Skip to content

Commit ddd49af

Browse files
committed
updated magical ExpressionBuilder (compile-time codegen)
1 parent 2df9216 commit ddd49af

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

dlls/weapons/ExpressionBuilder.hpp

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,26 @@ namespace ExpressionBuilder
2929
const UnderlyingType c;
3030
constexpr explicit ConstantType(UnderlyingType a) : c(a) {}
3131
template<class T>
32-
constexpr UnderlyingType operator()(T x) const
32+
constexpr ConstantType<UnderlyingType> operator()(T x) const
3333
{
34-
return c;
34+
return ConstantType<UnderlyingType>(c); // *this
3535
}
3636
constexpr operator UnderlyingType() const { return c; }
3737
};
3838

39+
template<class T>
40+
constexpr auto varcon(T x) -> typename std::enable_if<!IsExpression<T>::value, ConstantType<T>>::type
41+
{
42+
return ConstantType<T>(x);
43+
}
44+
template<class T>
45+
constexpr auto varcon(T x) -> typename std::enable_if<IsExpression<T>::value, T>::type
46+
{
47+
return x;
48+
}
49+
3950
template<class Varible, class Constant>
40-
struct BindedType
51+
struct BindedType : Expression
4152
{
4253
const Varible var;
4354
const Constant con;
@@ -46,29 +57,29 @@ namespace ExpressionBuilder
4657
template<class T>
4758
constexpr auto operator()(T x) const -> BindedType<Varible, Constant>
4859
{
49-
return BindedType<Varible, Constant>(var, con);
60+
return BindedType<Varible, Constant>(var.template operator()(x), con.template operator()(x));
5061
}
5162
};
5263

53-
template<char Name>
64+
template<class IdentifierName>
5465
struct VaribleType : Expression
5566
{
56-
template<class UnderlyingType>
57-
constexpr auto operator=(UnderlyingType c) const -> BindedType<VaribleType<Name>, ConstantType<UnderlyingType>>
67+
template<class T>
68+
constexpr auto operator=(T c) const -> BindedType<VaribleType<IdentifierName>, decltype(varcon(c))>
5869
{
59-
return BindedType<VaribleType<Name>, ConstantType<UnderlyingType>>(VaribleType<Name>(), ConstantType<UnderlyingType>(c));
70+
return BindedType<VaribleType<IdentifierName>, decltype(varcon(c))>(VaribleType<IdentifierName>(), varcon(c));
6071
}
6172

62-
template<class UnderlyingType>
63-
constexpr auto operator()(BindedType<VaribleType<Name>, ConstantType<UnderlyingType>> x) const -> UnderlyingType
73+
template<class T>
74+
constexpr auto operator()(BindedType<VaribleType<IdentifierName>, T> x) const -> decltype(x.con(x))
6475
{
65-
return x.con.c;
76+
return x.con(x);
6677
}
6778

6879
template<class T>
69-
constexpr auto operator()(T x) const -> VaribleType<Name>
80+
constexpr auto operator()(T x) const -> VaribleType<IdentifierName>
7081
{
71-
return VaribleType<Name>();
82+
return VaribleType<IdentifierName>(); // *this
7283
}
7384
};
7485

@@ -80,17 +91,6 @@ namespace ExpressionBuilder
8091
constexpr BinaryOperator(Exp1 a, Exp2 b) : _1(a), _2(b) {}
8192
};
8293

83-
template<class T>
84-
constexpr auto varcon(T x) -> typename std::enable_if<!IsExpression<T>::value, ConstantType<T>>::type
85-
{
86-
return ConstantType<T>(x);
87-
}
88-
template<class T>
89-
constexpr auto varcon(T x) -> typename std::enable_if<IsExpression<T>::value, T>::type
90-
{
91-
return x;
92-
}
93-
9494
template<class Exp1, class Exp2>
9595
struct OperatorPlus_t : BinaryOperator<Exp1, Exp2>
9696
{
@@ -134,25 +134,48 @@ namespace ExpressionBuilder
134134
{
135135
return OperatorPlus_t<decltype(varcon(_1)), decltype(varcon(_2))>(varcon(_1), varcon(_2));
136136
}
137+
template<class T1, class T2>
138+
constexpr auto operator+(ConstantType<T1> _1, ConstantType<T2> _2) -> ConstantType<decltype(_1.c + _2.c)>
139+
{
140+
return ConstantType<decltype(_1.c + _2.c)>(_1.c + _2.c);
141+
}
137142
template<class Exp1, class Exp2, class = typename std::enable_if<IsExpression<Exp1>::value || IsExpression<Exp2>::value>::type>
138143
constexpr auto operator-(Exp1 _1, Exp2 _2) -> OperatorMinus_t<decltype(varcon(_1)), decltype(varcon(_2))>
139144
{
140145
return OperatorMinus_t<decltype(varcon(_1)), decltype(varcon(_2))>(varcon(_1), varcon(_2));
141146
}
147+
template<class T1, class T2>
148+
constexpr auto operator-(ConstantType<T1> _1, ConstantType<T2> _2) -> ConstantType<decltype(_1.c - _2.c)>
149+
{
150+
return ConstantType<decltype(_1.c - _2.c)>(_1.c - _2.c);
151+
}
142152
template<class Exp1, class Exp2, class = typename std::enable_if<IsExpression<Exp1>::value || IsExpression<Exp2>::value>::type>
143153
constexpr auto operator*(Exp1 _1, Exp2 _2) -> OperatorMul_t<decltype(varcon(_1)), decltype(varcon(_2))>
144154
{
145155
return OperatorMul_t<decltype(varcon(_1)), decltype(varcon(_2))>(varcon(_1), varcon(_2));
146156
}
157+
template<class T1, class T2>
158+
constexpr auto operator*(ConstantType<T1> _1, ConstantType<T2> _2) -> ConstantType<decltype(_1.c * _2.c)>
159+
{
160+
return ConstantType<decltype(_1.c * _2.c)>(_1.c * _2.c);
161+
}
147162
template<class Exp1, class Exp2, class = typename std::enable_if<IsExpression<Exp1>::value || IsExpression<Exp2>::value>::type>
148163
constexpr auto operator/(Exp1 _1, Exp2 _2) -> OperatorDiv_t<decltype(varcon(_1)), decltype(varcon(_2))>
149164
{
150165
return OperatorDiv_t<decltype(varcon(_1)), decltype(varcon(_2))>(varcon(_1), varcon(_2));
151166
}
167+
template<class T1, class T2>
168+
constexpr auto operator/(ConstantType<T1> _1, ConstantType<T2> _2) -> ConstantType<decltype(_1.c / _2.c)>
169+
{
170+
return ConstantType<decltype(_1.c / _2.c)>(_1.c / _2.c);
171+
}
172+
class x_id;
173+
class y_id;
174+
class z_id;
152175
}
153176

154177
using detail::VaribleType;
155-
constexpr const detail::VaribleType<'x'> x{};
156-
constexpr const detail::VaribleType<'y'> y{};
157-
constexpr const detail::VaribleType<'z'> z{};
178+
constexpr const detail::VaribleType<detail::x_id> x{};
179+
constexpr const detail::VaribleType<detail::y_id> y{};
180+
constexpr const detail::VaribleType<detail::z_id> z{};
158181
}

dlls/weapons/WeaponDataVaribles.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,14 @@ GNU General Public License for more details.
1818
namespace WeaponTemplate {
1919
namespace Varibles
2020
{
21-
constexpr auto A = ExpressionBuilder::VaribleType<'A'>{};
22-
constexpr auto T = ExpressionBuilder::VaribleType<'T'>{};
23-
constexpr auto N = ExpressionBuilder::VaribleType<'N'>{};
21+
namespace detail
22+
{
23+
class id_A;
24+
class id_T;
25+
class id_N;
26+
}
27+
constexpr auto A = ExpressionBuilder::VaribleType<detail::id_A>{};
28+
constexpr auto T = ExpressionBuilder::VaribleType<detail::id_T>{};
29+
constexpr auto N = ExpressionBuilder::VaribleType<detail::id_N>{};
2430
}
2531
}

0 commit comments

Comments
 (0)