Skip to content

Instantly share code, notes, and snippets.

@kdungs
Last active May 15, 2016 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kdungs/cc216fae675bac78ac567d3da1d53e4a to your computer and use it in GitHub Desktop.
Save kdungs/cc216fae675bac78ac567d3da1d53e4a to your computer and use it in GitHub Desktop.
A minimalistic solution for the Expression Problem as presented by Eli Bendersky in [his blog](http://eli.thegreenplace.net/2016/the-expression-problem-and-its-solutions/).
#pragma once
#include <string>
#include <utility>
struct Constant {
double value;
};
double eval(const Constant& c) { return c.value; }
template <typename LHS, typename RHS>
struct BinaryPlus {
LHS lhs;
RHS rhs;
};
template <typename LHS, typename RHS>
auto makeBinaryPlus(LHS&& lhs, RHS&& rhs) {
return BinaryPlus<LHS, RHS>{std::forward<LHS>(lhs), std::forward<RHS>(rhs)};
}
template <typename LHS, typename RHS>
double eval(const BinaryPlus<LHS, RHS>& bp) {
return eval(bp.lhs) + eval(bp.rhs);
}
// Adding toString function
std::string toString(const Constant& c) { return std::to_string(c.value); }
template <typename LHS, typename RHS>
std::string toString(const BinaryPlus<LHS, RHS>& bp) {
return toString(bp.lhs) + " + " + toString(bp.rhs);
}
// Adding new type
template <typename F, typename EXPR>
struct FunctionCall {
F f;
EXPR expr;
};
template <typename F, typename EXPR>
auto makeFunctionCall(F&& f, EXPR&& expr) {
return FunctionCall<F, EXPR>{std::forward<F>(f), std::forward<EXPR>(expr)};
}
template <typename F, typename EXPR>
double eval(const FunctionCall<F, EXPR>& fc) {
return fc.f(eval(fc.expr));
}
template <typename F, typename EXPR>
std::string toString(const FunctionCall<F, EXPR>& fc) {
return "f(" + toString(fc.expr) + ")";
}
#include "expr2.h"
#include <iostream>
int main() {
auto c1 = Constant{1.2};
auto c2 = Constant{3.4};
auto c3 = Constant{5.6};
auto b1 = makeBinaryPlus(c1, c2);
auto b2 = makeBinaryPlus(b1, c3);
auto f1 = makeFunctionCall([](double x) { return 2 * x; }, b2);
std::cout << toString(f1) << " = " << eval(f1) << '\n';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment