Paste number 28292: template hack Pasted by: psykotic When: 13 years, 11 months ago Share: Tweet this! | http://paste.lisp.org/+LTW Channel: None Paste contents: Raw Source | XML | Display As text/plain image/svg+xml text/html application/xhtml+xml

#include <stdio.h> template < bool B, typename T1, typename T2> struct Select { typedef T1 Value; } ; template < typename T1, typename T2> struct Select<false, T1, T2> { typedef T2 Value; } ; struct Null { } ; template < char VAR, typename VAL, typename ENV> struct Extend { } ; template < int N> struct Num { } ; template < char PARAM, typename BODY, typename ENV> struct Proc { template < typename ARG> struct Apply { typedef typename BODY::template Eval<Extend<PARAM, ARG, ENV> >::Value Value; } ; } ; template < int N> struct Lit { template < typename ENV> struct Eval { typedef Num<N> Value; } ; } ; template < char VAR> struct Var { template < typename ENV> struct Eval { typedef Null Value; } ; template < char AVAR, typename VAL, typename ENV> struct Eval<Extend<AVAR, VAL, ENV> > { typedef typename Select<VAR == AVAR, VAL, typename Eval<ENV>::Value>::Value Value; } ; } ; template < char PARAM, typename BODY> struct Abs { template < typename ENV> struct Eval { typedef Proc<PARAM, BODY, ENV> Value; } ; } ; template < typename OP, typename ARG> struct App { template < typename ENV> struct Eval { typedef typename OP::template Eval<ENV>::Value Op; typedef typename ARG::template Eval<ENV>::Value Arg; typedef typename Op::template Apply<Arg>::Value Value; } ; } ; template < typename EXP> struct Printer { } ; template < int N> struct Printer< Num<N> > { static void print ( ) { printf ( "%d" , N ) ; } } ; template < char PARAM, typename BODY, typename ENV> struct Printer<Proc<PARAM, BODY, ENV> > { static void print ( ) { printf ( "<proc>" ) ; } } ; template < typename EXP> void evalprint ( ) { Printer< typename EXP::template Eval<Null>::Value>::print ( ) ; printf ( "

" ) ; } int main ( ) { evalprint<Lit<42> > ( ) ; evalprint<Abs< 'x' , Lit<42> > > ( ) ; evalprint<App<Abs< 'x' , Lit<42> >, Lit<666> > > ( ) ; evalprint<App<Abs< 'x' , Var< 'x' > >, Lit<666> > > ( ) ; evalprint<App<Abs< 'x' , Abs< 'y' , Var< 'x' > > >, Lit<42> > > ( ) ; evalprint<App<App<Abs< 'x' , Abs< 'y' , Var< 'x' > > >, Lit<42> >, Lit<666> > > ( ) ; evalprint<App<App<Abs< 'x' , Abs< 'y' , Var< 'y' > > >, Lit<42> >, Lit<666> > > ( ) ; return 0; }