#define CONST const
#ifdef PRECXX11
#define static_assert _Static_assert
#endif
class A {
template<typename T> CONST T wrong; template<typename T> CONST T wrong_init = 5; template<typename T, typename T0> static CONST T right = T(100);
template<typename T> static CONST T right<T,int> = 5;
template<typename T> CONST int right<int,T>; template<typename T> CONST float right<float,T> = 5; template<> static CONST int right<int,int> = 7;
template<> static CONST float right<float,int>;
template static CONST int right<int,int>; };
namespace out_of_line {
class B0 {
template<typename T, typename T0> static CONST T right = T(100);
template<typename T> static CONST T right<T,int> = T(5);
};
template<> CONST int B0::right<int,int> = 7; template CONST int B0::right<int,int>; template<> CONST int B0::right<int,float>; template CONST int B0::right<int,float>;
class B1 {
template<typename T, typename T0> static CONST T right;
template<typename T> static CONST T right<T,int>;
};
template<typename T, typename T0> CONST T B1::right = T(100);
template<typename T> CONST T B1::right<T,int> = T(5);
class B2 {
template<typename T, typename T0> static CONST T right = T(100); template<typename T> static CONST T right<T,int> = T(5); };
template<typename T, typename T0> CONST T B2::right = T(100); template<typename T> CONST T B2::right<T,int> = T(5);
class B3 {
template<typename T, typename T0> static CONST T right = T(100);
template<typename T> static CONST T right<T,int> = T(5);
};
template<typename T, typename T0> CONST T B3::right;
template<typename T> CONST T B3::right<T,int>;
class B4 {
template<typename T, typename T0> static CONST T a;
template<typename T> static CONST T a<T,int> = T(100);
template<typename T, typename T0> static CONST T b = T(100);
template<typename T> static CONST T b<T,int>;
};
template<typename T, typename T0> CONST T B4::a; template<typename T> CONST T B4::a<T,int>;
template CONST int B4::a<int,char>; template CONST int B4::a<int,int>;
template<typename T, typename T0> CONST T B4::b;
template<typename T> CONST T B4::b<T,int>; template CONST int B4::b<int,char>;
template CONST int B4::b<int,int>; }
namespace non_const_init {
class A {
template<typename T> static T wrong_inst_undefined = T(10); template<typename T> static T wrong_inst_defined = T(10); template<typename T> static T wrong_inst_out_of_line;
};
template const int A::wrong_inst_undefined<const int>;
template<typename T> T A::wrong_inst_defined;
template const int A::wrong_inst_defined<const int>;
template int A::wrong_inst_defined<int>;
template<typename T> T A::wrong_inst_out_of_line = T(10);
template int A::wrong_inst_out_of_line<int>;
class B {
template<typename T> static T wrong_inst; template<typename T> static T wrong_inst<T*> = T(100);
template<typename T> static T wrong_inst_fixed;
template<typename T> static T wrong_inst_fixed<T*>;
};
template int B::wrong_inst<int>; template int B::wrong_inst<int*>; template const int B::wrong_inst<const int*>; template<typename T> T B::wrong_inst_fixed = T(100);
template int B::wrong_inst_fixed<int>;
class C {
template<typename T> static CONST T right_inst = T(10); template<typename T> static CONST T right_inst<T*> = T(100); };
template CONST int C::right_inst<int>; template CONST int C::right_inst<int*>;
namespace pointers {
struct C0 {
template<typename U> static U Data;
template<typename U> static CONST U Data<U*> = U();
template<typename U> static U Data2;
template<typename U> static CONST U Data2<U*> = U();
};
const int c0_test = C0::Data<int*>;
static_assert(c0_test == 0, "");
template const int C0::Data<int*>;
template<typename U> const U C0::Data2<U*>;
template const int C0::Data2<int*>;
struct C1a {
template<typename U> static U Data;
template<typename U> static U* Data<U*>; };
template<typename T> T* C1a::Data<T*> = new T();
template int* C1a::Data<int*>;
struct C1b {
template<typename U> static U Data;
template<typename U> static CONST U* Data<U*>; };
template<typename T> CONST T* C1b::Data<T*> = (T*)(0);
template CONST int* C1b::Data<int*>;
struct C2a {
template<typename U> static int Data;
template<typename U> static U* Data<U*> = new U(); };
template int* C2a::Data<int*>;
struct C2b {
template<typename U> static int Data;
template<typename U> static U *const Data<U*> = (U*)(0); };
template<typename U> U *const C2b::Data<U*>;
template int *const C2b::Data<int*>; }
}
#ifndef PRECXX11
namespace constexpred {
class A {
template<typename T> constexpr T wrong; template<typename T> constexpr T wrong_init = 5; template<typename T, typename T0> static constexpr T right = T(100);
template<typename T> static constexpr T right<T,int> = 5;
template<typename T> constexpr int right<int,T>; template<typename T> constexpr float right<float,T> = 5; template<> static constexpr int right<int,int> = 7;
template <> static constexpr float right<float, int>; template static constexpr int right<int,int>; };
}
#endif
namespace in_class_template {
template<typename T>
class D0 {
template<typename U> static U Data; template<typename U> static CONST U Data<U*> = U();
};
template CONST int D0<float>::Data<int*>;
template int D0<float>::Data<int>; template<typename T> template<typename U> const U D0<T>::Data<U*>;
template<typename T>
class D1 {
template<typename U> static U Data;
template<typename U> static U* Data<U*>;
};
template<typename T>
template<typename U> U* D1<T>::Data<U*> = (U*)(0);
template int* D1<float>::Data<int*>; template int* D1<float>::Data<int*>;
template<typename T>
class D2 {
template<typename U> static U Data;
template<typename U> static U* Data<U*>;
};
template<>
template<typename U> U* D2<float>::Data<U*> = (U*)(0) + 1;
template int* D2<float>::Data<int*>; template int* D2<float>::Data<int*>;
template<typename T>
struct D3 {
template<typename U> static CONST U Data = U(100); };
static_assert(D3<float>::Data<int> == 100, "");
template const char D3<float>::Data<char>;
namespace bug_files {
template<typename T>
class D0a {
template<typename U> static U Data;
template<typename U> static CONST U Data<U*> = U(10); };
template<>
template<typename U> U D0a<float>::Data<U*> = U(100);
template<typename T>
class D1 {
template<typename U> static U Data;
template<typename U> static CONST U Data<U*> = U(10); };
template<>
template<typename U> U D1<float>::Data = U(10);
template<>
template<typename U> U D1<float>::Data<U*> = U(100); }
namespace definition_after_outer_instantiation {
template<typename A> struct S {
template<typename B> static const int V1;
template<typename B> static const int V2; };
template struct S<int>;
template<typename A> template<typename B> const int S<A>::V1 = 123;
template<typename A> template<typename B> const int S<A>::V2<B*> = 456;
static_assert(S<int>::V1<int> == 123, "");
static_assert(S<int>::V2<int*> == 456, ""); static_assert(S<int>::V2<int&> == 789, "");
template<typename A> template<typename B> const int S<A>::V2<B&> = 789;
static_assert(S<int>::V2<int&> == 789, "");
static_assert(S<char>::V1<int> == 123, "");
static_assert(S<char>::V2<int*> == 456, "");
static_assert(S<char>::V2<int&> == 789, "");
}
namespace incomplete_array {
template<typename T> extern T var[];
template<typename T> T var[] = { 1, 2, 3 };
template<> char var<char>[] = "hello";
template<typename T> char var<T*>[] = "pointer";
static_assert(sizeof(var<int>) == 12, "");
static_assert(sizeof(var<char>) == 6, "");
static_assert(sizeof(var<void*>) == 8, "");
template<typename...> struct tuple;
template<typename T> struct A {
template<typename U> static T x[];
template<typename U> static T y[];
template<typename...U> static T y<tuple<U...> >[];
};
int *use_before_definition = A<int>::x<char>;
template<typename T> template<typename U> T A<T>::x[sizeof(U)];
static_assert(sizeof(A<int>::x<char>) == 4, "");
template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... };
static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, "");
}
namespace bad_reference {
struct S {
template<typename T> static int A; };
template<typename T> void f() {
typename T::template A<int> a; }
template<typename T> void g() {
T::template A<int>::B = 0; }
template<typename T> void h() {
class T::template A<int> c; }
template<typename T>
struct X : T::template A<int> {};
template void f<S>(); template void g<S>(); template void h<S>(); template struct X<S>; }
}
namespace in_nested_classes {
}
namespace bitfield {
struct S {
template <int I>
static int f : I; };
}
namespace b20896909 {
template<typename T> struct helper {};
template<typename T> class A {
template <typename> static helper<typename T::error> x; };
void test() {
A<int> ai; }
}
namespace member_access_is_ok {
#ifdef CPP1Y
namespace ns1 {
struct A {
template<class T, T N> constexpr static T Var = N;
};
static_assert(A{}.Var<int,5> == 5,"");
} #endif
namespace ns2 {
template<class T> struct A {
template<class U, T N, U M> static T&& Var;
};
template<class T> template<class U, T N, U M> T&& A<T>::Var = T(N + M);
int *AV = &A<int>().Var<char, 5, 'A'>;
} }
#ifdef CPP1Y
namespace PR24473 {
struct Value
{
template<class T>
static constexpr T value = 0;
};
template<typename TValue>
struct Something
{
void foo() {
static_assert(TValue::template value<int> == 0, ""); }
};
int main() {
Something<Value>{}.foo();
return 0;
}
} #endif
namespace dependent_static_var_template {
struct A {
template<int = 0> static int n; };
int &r = A::template n;
template<typename T>
int &f() { return T::template n; } int &s = f<A>();
namespace B {
template<int = 0> static int n; }
int &t = B::template n;
struct C {
template <class T> static T G;
};
template<class T> T C::G = T(6);
template <class T> T F() {
C c;
return c.G<T>;
}
int cf() { return F<int>(); }
}
#ifndef PRECXX11
namespace template_vars_in_template {
template <int> struct TakesInt {};
template <class T2>
struct S {
template <class T1>
static constexpr int v = 42;
template <class T>
void mf() {
constexpr int val = v<T>;
}
void mf2() {
constexpr int val = v<char>;
TakesInt<val> ti;
(void)ti.x; }
};
void useit() {
S<int> x;
x.mf<double>();
x.mf2(); }
}
#endif