1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4 
5 template <typename ...xs>
6 struct list { };
7 
8 template <typename T>
9 struct basic_type { using type = T; };
10 
11 template <typename T>
12 constexpr basic_type<T> type{};
13 
14 
15 template <typename x, typename ...xs>
head(list<x,xs...>)16 constexpr auto head(list<x, xs...>)
17 { return type<x>; }
18 
19 template <typename x, typename ...xs>
tail(list<x,xs...>)20 constexpr auto tail(list<x, xs...>)
21 { return list<xs...>{}; }
22 
23 template <typename F, typename State, typename X, typename ...Xs>
foldl(F f,State s,list<X,Xs...> xs)24 constexpr auto foldl(F f, State s, list<X, Xs...> xs)
25 { return foldl(f, f(s, head(xs)), tail(xs)); }
26 
27 template <typename F, typename State>
foldl(F,State s,list<>)28 constexpr auto foldl(F, State s, list<>)
29 { return s; }
30 
31 //////////////////////////////////////////////////////////////////////////////
32 
33 
34 struct f {
35     template <typename ...>
36     struct result { };
37 
38     template <typename X, typename Y>
operator ()f39     constexpr auto operator()(X, Y) const
40     { return result<X, Y>{}; }
41 };
42 
43 template <int> struct x { };
44 struct state { };
45 
main()46 int main() {
47     constexpr auto xs = list<
48         <%= (1..input_size).map { |i| "x<#{i}>" }.join(', ') %>
49     >{};
50 
51     constexpr auto result = foldl(f{}, state{}, xs);
52     (void)result;
53 }
54