[et] dsl
This commit is contained in:
parent
dc4622d7a3
commit
6861215065
87
examples/et/3_dsl.cpp
Normal file
87
examples/et/3_dsl.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
/* unchanged from et/2_generic_arity.cpp */
|
||||||
|
struct Add {
|
||||||
|
template<typename T>
|
||||||
|
static auto eval(T lhs, T rhs) {
|
||||||
|
return lhs + rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mul {
|
||||||
|
template<typename T>
|
||||||
|
static auto eval(T lhs, T rhs) {
|
||||||
|
return lhs * rhs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Value {
|
||||||
|
T _value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Value(T value): _value(value) {}
|
||||||
|
|
||||||
|
auto eval() const { return _value; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Op, typename... Operands>
|
||||||
|
class Expr {
|
||||||
|
std::tuple<Operands...> _operands;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Expr(Operands... operands): _operands{operands...} {}
|
||||||
|
|
||||||
|
auto eval() const {
|
||||||
|
return eval(std::make_index_sequence<sizeof...(Operands)>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<std::size_t... Is>
|
||||||
|
auto eval(std::index_sequence<Is...>) const {
|
||||||
|
return Op::eval(std::get<Is>(_operands).eval()...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* end of unchanged */
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
template<typename T> struct IsExpr: std::false_type {};
|
||||||
|
|
||||||
|
template<typename Op, typename... Operands>
|
||||||
|
struct IsExpr<Expr<Op, Operands...>>: std::true_type {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct IsExpr<Value<T>>: std::true_type {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr bool IsExpr = impl::IsExpr<T>::value;
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename LHS, typename RHS,
|
||||||
|
std::enable_if_t<IsExpr<LHS> && IsExpr<RHS>>* = nullptr
|
||||||
|
>
|
||||||
|
auto operator+(LHS lhs, RHS rhs) {
|
||||||
|
return Expr<Add, LHS, RHS>{lhs, rhs};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename LHS, typename RHS,
|
||||||
|
std::enable_if_t<IsExpr<LHS> && IsExpr<RHS>>* = nullptr
|
||||||
|
>
|
||||||
|
auto operator*(LHS lhs, RHS rhs) {
|
||||||
|
return Expr<Mul, LHS, RHS>{lhs, rhs};
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int volatile v[]{3, 5, 7};
|
||||||
|
int result;
|
||||||
|
|
||||||
|
Value<int> v0{v[0]}, v1{v[1]}, v2{v[2]};
|
||||||
|
|
||||||
|
auto expr = v0 + v1 * v2;
|
||||||
|
result = expr.eval();
|
||||||
|
|
||||||
|
std::printf("%d\n", result);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user