@@ -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}
0 commit comments