1*99451b44SJordan Rupprecht //===-- main.cpp ------------------------------------------------*- C++ -*-===//
2*99451b44SJordan Rupprecht //
3*99451b44SJordan Rupprecht // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*99451b44SJordan Rupprecht // See https://llvm.org/LICENSE.txt for license information.
5*99451b44SJordan Rupprecht // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*99451b44SJordan Rupprecht //
7*99451b44SJordan Rupprecht //===----------------------------------------------------------------------===//
8*99451b44SJordan Rupprecht #include <tuple>
9*99451b44SJordan Rupprecht 
10*99451b44SJordan Rupprecht template <int Arg>
11*99451b44SJordan Rupprecht class TestObj
12*99451b44SJordan Rupprecht {
13*99451b44SJordan Rupprecht public:
14*99451b44SJordan Rupprecht   int getArg()
15*99451b44SJordan Rupprecht   {
16*99451b44SJordan Rupprecht     return Arg;
17*99451b44SJordan Rupprecht   }
18*99451b44SJordan Rupprecht };
19*99451b44SJordan Rupprecht 
20*99451b44SJordan Rupprecht //----------------------------------------------------------------------
21*99451b44SJordan Rupprecht // Define a template class that we can specialize with an enumeration
22*99451b44SJordan Rupprecht //----------------------------------------------------------------------
23*99451b44SJordan Rupprecht enum class EnumType
24*99451b44SJordan Rupprecht {
25*99451b44SJordan Rupprecht     Member,
26*99451b44SJordan Rupprecht     Subclass
27*99451b44SJordan Rupprecht };
28*99451b44SJordan Rupprecht 
29*99451b44SJordan Rupprecht template <EnumType Arg> class EnumTemplate;
30*99451b44SJordan Rupprecht 
31*99451b44SJordan Rupprecht //----------------------------------------------------------------------
32*99451b44SJordan Rupprecht // Specialization for use when "Arg" is "EnumType::Member"
33*99451b44SJordan Rupprecht //----------------------------------------------------------------------
34*99451b44SJordan Rupprecht template <>
35*99451b44SJordan Rupprecht class EnumTemplate<EnumType::Member>
36*99451b44SJordan Rupprecht {
37*99451b44SJordan Rupprecht public:
38*99451b44SJordan Rupprecht     EnumTemplate(int m) :
39*99451b44SJordan Rupprecht         m_member(m)
40*99451b44SJordan Rupprecht     {
41*99451b44SJordan Rupprecht     }
42*99451b44SJordan Rupprecht 
43*99451b44SJordan Rupprecht     int getMember() const
44*99451b44SJordan Rupprecht     {
45*99451b44SJordan Rupprecht         return m_member;
46*99451b44SJordan Rupprecht     }
47*99451b44SJordan Rupprecht 
48*99451b44SJordan Rupprecht protected:
49*99451b44SJordan Rupprecht     int m_member;
50*99451b44SJordan Rupprecht };
51*99451b44SJordan Rupprecht 
52*99451b44SJordan Rupprecht //----------------------------------------------------------------------
53*99451b44SJordan Rupprecht // Specialization for use when "Arg" is "EnumType::Subclass"
54*99451b44SJordan Rupprecht //----------------------------------------------------------------------
55*99451b44SJordan Rupprecht template <>
56*99451b44SJordan Rupprecht class EnumTemplate<EnumType::Subclass> :
57*99451b44SJordan Rupprecht     public EnumTemplate<EnumType::Member>
58*99451b44SJordan Rupprecht {
59*99451b44SJordan Rupprecht public:
60*99451b44SJordan Rupprecht     EnumTemplate(int m) : EnumTemplate<EnumType::Member>(m)
61*99451b44SJordan Rupprecht     {
62*99451b44SJordan Rupprecht     }
63*99451b44SJordan Rupprecht };
64*99451b44SJordan Rupprecht 
65*99451b44SJordan Rupprecht template <typename FLOAT> struct T1 { FLOAT f = 1.5; };
66*99451b44SJordan Rupprecht template <typename FLOAT> struct T2 { FLOAT f = 2.5; int i = 42; };
67*99451b44SJordan Rupprecht template <typename FLOAT, template <typename> class ...Args> class C { std::tuple<Args<FLOAT>...> V; };
68*99451b44SJordan Rupprecht 
69*99451b44SJordan Rupprecht int main(int argc, char **argv)
70*99451b44SJordan Rupprecht {
71*99451b44SJordan Rupprecht   TestObj<1> testpos;
72*99451b44SJordan Rupprecht   TestObj<-1> testneg;
73*99451b44SJordan Rupprecht   EnumTemplate<EnumType::Member> member(123);
74*99451b44SJordan Rupprecht   EnumTemplate<EnumType::Subclass> subclass(123*2);
75*99451b44SJordan Rupprecht   C<float, T1> c1;
76*99451b44SJordan Rupprecht   C<double, T1, T2> c2;
77*99451b44SJordan Rupprecht   return testpos.getArg() - testneg.getArg() + member.getMember()*2 - subclass.getMember(); // Breakpoint 1
78*99451b44SJordan Rupprecht }
79