18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s
2*c6e68daaSAndy Gibbs // expected-no-diagnostics
3b7ae10f7SDouglas Gregor 
4b7ae10f7SDouglas Gregor // template<unsigned M, unsigned N>
5b7ae10f7SDouglas Gregor // struct Ackermann {
6b7ae10f7SDouglas Gregor //   enum {
709bb21f8SDaniel Dunbar //     value = M ? (N ? Ackermann<M-1, Ackermann<M, N-1> >::value
8b7ae10f7SDouglas Gregor //                    : Ackermann<M-1, 1>::value)
9b7ae10f7SDouglas Gregor //               : N + 1
10b7ae10f7SDouglas Gregor //   };
11b7ae10f7SDouglas Gregor // };
12b7ae10f7SDouglas Gregor 
13b7ae10f7SDouglas Gregor template<unsigned M, unsigned N>
14b7ae10f7SDouglas Gregor struct Ackermann {
15b7ae10f7SDouglas Gregor  enum {
16b7ae10f7SDouglas Gregor    value = Ackermann<M-1, Ackermann<M, N-1>::value >::value
17b7ae10f7SDouglas Gregor  };
18b7ae10f7SDouglas Gregor };
19b7ae10f7SDouglas Gregor 
20b7ae10f7SDouglas Gregor template<unsigned M> struct Ackermann<M, 0> {
21b7ae10f7SDouglas Gregor  enum {
22b7ae10f7SDouglas Gregor    value = Ackermann<M-1, 1>::value
23b7ae10f7SDouglas Gregor  };
24b7ae10f7SDouglas Gregor };
25b7ae10f7SDouglas Gregor 
26b7ae10f7SDouglas Gregor template<unsigned N> struct Ackermann<0, N> {
27b7ae10f7SDouglas Gregor  enum {
28b7ae10f7SDouglas Gregor    value = N + 1
29b7ae10f7SDouglas Gregor  };
30b7ae10f7SDouglas Gregor };
31b7ae10f7SDouglas Gregor 
32b7ae10f7SDouglas Gregor template<> struct Ackermann<0, 0> {
33b7ae10f7SDouglas Gregor  enum {
34b7ae10f7SDouglas Gregor    value = 1
35b7ae10f7SDouglas Gregor  };
36b7ae10f7SDouglas Gregor };
37b7ae10f7SDouglas Gregor 
3809bb21f8SDaniel Dunbar int g0[Ackermann<3, 4>::value == 125 ? 1 : -1];
3909bb21f8SDaniel Dunbar 
40