62 lines
1.1 KiB
C++
62 lines
1.1 KiB
C++
|
#include <cstdio>
|
||
|
#include <tuple>
|
||
|
|
||
|
/* unchanged from et/1_first_draft.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; }
|
||
|
};
|
||
|
/* end of unchanged */
|
||
|
|
||
|
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()...);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/* unchanged from et/1_first_draft.cpp */
|
||
|
int main() {
|
||
|
using SubExpr = Expr<Mul, Value<int>, Value<int>>;
|
||
|
using MyExpr = Expr<Add, Value<int>, SubExpr>;
|
||
|
|
||
|
int volatile v0 = 3, v1 = 5, v2 = 7;
|
||
|
int result;
|
||
|
|
||
|
MyExpr expr{{v0}, {{v1}, {v2}}};
|
||
|
result = expr.eval();
|
||
|
|
||
|
std::printf("%d\n", result);
|
||
|
}
|
||
|
/* end of unchanged */
|