Terms with Variables (C++)
In this earlier post I showed a nifty OCaml type for modeling terms with variables for problems involving substitutions. I got interested in what it would take to implement the type in C++(03) (doing 'sum' types in C++ elegantly is a perennial problem). It ain't nowhere near as succinct but we got there nonetheless.
#include <list> #include <boost/variant.hpp> /* type ('a, 'b) term = | Term of 'a * ('a, 'b) term list | Var of 'b */ template <class A, class B> struct term; template <class B> struct var; template <class A, class B> struct make_tree { typedef boost::variant < boost::recursive_wrapper<term <A, B> >, var<B> > type; }; template <class A, class B> struct term { typedef typename make_tree <A, B>::type tree; A a; std::list <tree> children; term (A a , std::list<tree> const& children) : a (a), children (children) {} }; template <class A, class B> inline term <A, B> make_term ( A a, std::list<typename make_tree<A, B>::type> const& c, B const*) { return term<A, B> (a, c); } template <class B> struct var { B tag; var (B tag) : tag (tag) {} }; template <class B> inline var<B> make_var (B tag) { return var<B> (tag); }For example, this little program builds the term represented by the concrete syntax "a(b(), c)".
int main () { typedef make_tree<std::string, std::string>::type tree; typedef std::list<tree> term_list; std::string const* tag_str=(std::string const*)0L; // a(b(), c) term_list l; l.push_back (make_term(std::string("b"), term_list (), tag_str)); l.push_back (make_var(std::string("c"))); tree t = make_term(std::string("a"), l, tag_str); return 0; }