Aleksei Sidorin | daf82f6 | 2017-01-23 09:45:29 +0000 | [diff] [blame] | 1 | template<typename T, class P> |
| 2 | struct TwoOptionTemplate {}; |
| 3 | |
| 4 | template<typename T> |
| 5 | struct TwoOptionTemplate<T, char> { |
| 6 | int member; |
| 7 | }; |
| 8 | |
| 9 | |
| 10 | template<typename T> |
| 11 | struct TwoOptionTemplate<T, double> { |
| 12 | float member; |
| 13 | }; |
| 14 | |
| 15 | template<typename T> |
| 16 | struct TwoOptionTemplate<T, T> { |
| 17 | T** member; |
| 18 | }; |
| 19 | |
| 20 | TwoOptionTemplate<int, char> X0; |
| 21 | TwoOptionTemplate<int, float> X1; |
| 22 | TwoOptionTemplate<void *, wchar_t> X2; |
| 23 | TwoOptionTemplate<long, long> X3; |
| 24 | TwoOptionTemplate<float, float> X4; |
| 25 | TwoOptionTemplate<long, long> SingleSource; |
| 26 | TwoOptionTemplate<char, double> SecondDoubleSource; |
| 27 | |
| 28 | |
| 29 | template<int I, class C> |
| 30 | struct IntTemplateSpec {}; |
| 31 | |
| 32 | template<class C> |
| 33 | struct IntTemplateSpec<4, C> { |
| 34 | C member; |
| 35 | }; |
| 36 | |
| 37 | template<int I> |
| 38 | struct IntTemplateSpec<I, void *> { |
| 39 | int member; |
| 40 | static constexpr int val = I; |
| 41 | }; |
| 42 | |
| 43 | template<int I> |
| 44 | struct IntTemplateSpec<I, double> { |
| 45 | char member; |
| 46 | static constexpr int val = I; |
| 47 | }; |
| 48 | |
| 49 | IntTemplateSpec<4, wchar_t> Y0; |
| 50 | IntTemplateSpec<5, void *> Y1; |
| 51 | IntTemplateSpec<1, long> Y2; |
| 52 | IntTemplateSpec<3, int> Y3; |
| 53 | //template<int I> constexpr int IntTemplateSpec<I, double>::val; |
| 54 | IntTemplateSpec<42, double> NumberSource; |
| 55 | static_assert(NumberSource.val == 42); |
| 56 | |
| 57 | namespace One { |
| 58 | namespace Two { |
| 59 | // Just an empty namespace to ensure we can deal with multiple namespace decls. |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | |
| 64 | namespace One { |
| 65 | namespace Two { |
| 66 | namespace Three { |
| 67 | |
| 68 | template<class T> |
| 69 | class Parent {}; |
| 70 | |
| 71 | } // namespace Three |
| 72 | |
| 73 | } // namespace Two |
| 74 | |
| 75 | template<typename T, typename X> |
| 76 | struct Child1: public Two::Three::Parent<unsigned> { |
| 77 | char member; |
| 78 | }; |
| 79 | |
| 80 | template<class T> |
| 81 | struct Child1<T, One::Two::Three::Parent<T>> { |
| 82 | T member; |
| 83 | }; |
| 84 | |
| 85 | } // namespace One |
| 86 | |
| 87 | One::Child1<int, double> Z0Source; |
| 88 | |
| 89 | // Test import of nested namespace specifiers |
| 90 | template<typename T> |
| 91 | struct Outer { |
| 92 | template<typename U> class Inner0; |
| 93 | }; |
| 94 | |
| 95 | template<typename X> |
| 96 | template<typename Y> |
| 97 | class Outer<X>::Inner0 { |
| 98 | public: |
| 99 | void f(X, Y); |
| 100 | template<typename Z> struct Inner1; |
| 101 | }; |
| 102 | |
| 103 | template<typename X> |
| 104 | template<typename Y> |
| 105 | void Outer<X>::Inner0<Y>::f(X, Y) {} |
| 106 | |
| 107 | template<typename X> |
| 108 | template<typename Y> |
| 109 | template<typename Z> |
| 110 | class Outer<X>::Inner0<Y>::Inner1 { |
| 111 | public: |
| 112 | void f(Y, Z); |
| 113 | }; |
| 114 | |
| 115 | template<typename X> |
| 116 | template<typename Y> |
| 117 | template<typename Z> |
| 118 | void Outer<X>::Inner0<Y>::Inner1<Z>::f(Y, Z) {} |