Created
June 2, 2011 22:23
-
-
Save argv0/1005466 to your computer and use it in GitHub Desktop.
compile time typelists and fold metafunction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| /* an empty type to mark the empty list */ | |
| struct null_typelist {}; | |
| /* list representation */ | |
| template <class H, class T> | |
| struct typelist { | |
| typedef typelist<H, T> type; | |
| typedef H head; | |
| typedef T tail; | |
| }; | |
| /* constructor for typelists of length 0-4 */ | |
| template < | |
| class T1=null_typelist, class T2=null_typelist, | |
| class T3=null_typelist, class T4=null_typelist | |
| > | |
| struct make_typelist { | |
| private: | |
| // tail | |
| typedef typename make_typelist<T2,T3,T4>::type tail_type; | |
| public: | |
| // cons [H|T] | |
| typedef typelist<T1, tail_type> type; | |
| }; | |
| /* specialization to stop recursion */ | |
| template <> | |
| struct make_typelist<> { | |
| typedef null_typelist type; | |
| }; | |
| /* simple helper class that creates unique types from integer constants */ | |
| template <int i> | |
| struct int2type { | |
| typedef int2type<i> type; | |
| static const int value = i; | |
| }; | |
| /* some int-typedefs */ | |
| typedef int2type<0> zero; | |
| typedef int2type<1> one; | |
| typedef int2type<2> two; | |
| typedef int2type<3> three; | |
| typedef int2type<4> four; | |
| /* has inner "apply" metafunction that "returns" the result | |
| of adding two int2types */ | |
| struct adder { | |
| template <class Elem, class Acc> | |
| struct apply { | |
| typedef int2type<Elem::value + Acc::value> type; | |
| }; | |
| }; | |
| /* foldl implementation */ | |
| template <class L, class Fun, class Accin> | |
| struct foldl; | |
| /* primary template : foldl(List, Fun, Accin */ | |
| template <class L, class Fun, class Accin> | |
| struct foldl { | |
| /* call Fun(H, AccIn) -> NewAcc */ | |
| typedef typename Fun::template apply<typename L::head, Accin>::type NewAcc; | |
| /* foldl(Tail, Fun, NewAcc) */ | |
| typedef typename foldl<typename L::tail, Fun, NewAcc>::type type; | |
| }; | |
| /* specialization to stop fold */ | |
| template <class Fun, class Accin> | |
| struct foldl<null_typelist, Fun, Accin> { | |
| typedef typename Accin::type type; | |
| }; | |
| int main(int argc, char **argv) { | |
| typedef make_typelist<one, two, three, four>::type mylist; | |
| typedef foldl<mylist, adder, zero>::type folder; | |
| printf("%d\n", folder::value); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment