Skip to content

Instantly share code, notes, and snippets.

@cjxgm
Created July 29, 2014 10:53
Show Gist options
  • Save cjxgm/54e48d229620af3cc1cb to your computer and use it in GitHub Desktop.
Save cjxgm/54e48d229620af3cc1cb to your computer and use it in GitHub Desktop.
compile-time list in c++11
#include <iostream>
#include <utility>
using namespace std;
namespace list
{
using std::pair;
using std::make_pair;
struct nil {};
#define RETURN(BODY) -> decltype(BODY) { return (BODY); }
// cons
constexpr auto cons()
RETURN(nil{});
template <class Value, class ConsOrNil>
constexpr auto cons(Value value, ConsOrNil next)
RETURN(make_pair(value, next));
template <class Value>
constexpr auto cons(Value value)
RETURN(cons(value, cons()));
// reverse
template <class Cons>
constexpr auto reverse(Cons current)
RETURN(reverse(current.second, cons(current.first)));
constexpr auto reverse(nil)
RETURN(nil{});
template <class Cons, class Result>
constexpr auto reverse(Cons current, Result result)
RETURN(reverse(current.second, cons(current.first, result)));
template <class Result>
constexpr auto reverse(nil, Result result)
RETURN(result);
// foldl
template <class Cons, class BinOp>
constexpr auto foldl(Cons current, BinOp op)
RETURN(foldl(current.second, op, current.first));
template <class Init, class Cons, class BinOp>
constexpr auto foldl(Cons current, BinOp op, Init init)
RETURN(op(current.first, foldl(current.second, op, init)));
template <class Init, class BinOp>
constexpr auto foldl(nil, BinOp, Init init={})
RETURN(init);
// map
template <class Cons, class Unary>
constexpr auto map(Cons current, Unary op)
RETURN(cons(op(current.first), map(current.second, op)));
template <class Unary>
constexpr auto map(nil, Unary)
RETURN(nil{});
// first
template <class Cons>
constexpr auto first(Cons current)
RETURN(cons(current.first));
constexpr auto first(nil)
RETURN(nil{});
// last
template <class ConsOrNil>
constexpr auto last(ConsOrNil current)
RETURN(first(reverse(current)));
// append
template <class ConsOrNil, class Value>
constexpr auto append(ConsOrNil current, Value value)
RETURN(reverse(cons(value, reverse(current))));
// sum
struct add_op
{
template <class T, class U>
constexpr auto operator()(T t, U u)
RETURN(t+u);
};
template <class Cons>
constexpr auto sum(Cons current)
RETURN(foldl(current, add_op{}, 0));
// inc
struct inc_op
{
template <class T>
constexpr auto operator()(T t)
RETURN(t+1);
};
template <class Cons>
constexpr auto inc(Cons current)
RETURN(map(current, inc_op{}));
// print
struct print_op
{
template <class T>
constexpr auto operator()(T t)
RETURN(bool(cout << t << endl));
};
template <class Cons>
constexpr auto print(Cons current)
RETURN(map(current, print_op{}));
#undef RETURN
};
int main()
{
using namespace list;
constexpr auto lst = cons(1, cons(2, cons(3)));
constexpr auto ils = inc(lst);
constexpr auto rls = reverse(ils, nil{});
constexpr auto als = append(rls, 10);
constexpr auto s = sum(ils);
cout << s << endl;
print(rls);
print(first(rls));
print(last(rls));
cout << endl;
print(als);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment