template<typename T, T val> struct A {};
template<typename T, typename U> constexpr bool is_same = false; template<typename T> constexpr bool is_same<T, T> = true;
namespace String {
A<const char*, "test"> a; A<const char (&)[5], "test"> b; }
namespace Array {
char arr[3];
char x;
A<const char*, arr> a;
A<const char(&)[3], arr> b;
A<const char*, &arr[0]> c;
A<const char*, &arr[1]> d; A<const char*, (&arr)[0]> e;
A<const char*, &x> f;
A<const char*, &(&x)[0]> g;
A<const char*, &(&x)[1]> h; A<const char*, 0> i; A<const char*, nullptr> j;
extern char aub[];
A<char[], aub> k;
}
namespace Function {
void f();
void g() noexcept;
void h();
void h(int);
template<typename...T> void i(T...);
typedef A<void (*)(), f> a;
typedef A<void (*)(), &f> a;
typedef A<void (*)(), g> b;
typedef A<void (*)(), &g> b;
typedef A<void (*)(), h> c;
typedef A<void (*)(), &h> c;
typedef A<void (*)(), i> d;
typedef A<void (*)(), &i> d;
typedef A<void (*)(), i<>> d;
typedef A<void (*)(), i<int>> e;
typedef A<void (*)(), 0> x; typedef A<void (*)(), nullptr> y;
}
void Func() {
A<const char*, __func__> a; }
namespace LabelAddrDiff {
void f() {
a: b: A<int, __builtin_constant_p(true) ? (__INTPTR_TYPE__)&&b - (__INTPTR_TYPE__)&&a : 0> s; };
}
namespace Temp {
struct S { int n; };
constexpr S &addr(S &&s) { return s; }
A<S &, addr({})> a; A<S *, &addr({})> b; A<int &, addr({}).n> c; A<int *, &addr({}).n> d; }
namespace std { struct type_info; }
namespace RTTI {
A<const std::type_info&, typeid(int)> a; A<const std::type_info*, &typeid(int)> b; }
namespace PtrMem {
struct B { int b; };
struct C : B {};
struct D : B {};
struct E : C, D { int e; };
constexpr int B::*b = &B::b;
constexpr int C::*cb = b;
constexpr int D::*db = b;
constexpr int E::*ecb = cb; constexpr int E::*edb = db;
constexpr int E::*e = &E::e;
constexpr int D::*de = (int D::*)e;
constexpr int C::*ce = (int C::*)e;
constexpr int B::*bde = (int B::*)de; constexpr int B::*bce = (int B::*)ce;
using Ab = A<int B::*, b>;
using Ab = A<int B::*, &B::b>;
using Abce = A<int B::*, bce>; using Abde = A<int B::*, bde>; static_assert(!is_same<Ab, Abce>, ""); static_assert(!is_same<Ab, Abde>, ""); static_assert(!is_same<Abce, Abde>, ""); static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>>, "");
using Ae = A<int E::*, e>;
using Ae = A<int E::*, &E::e>;
using Aecb = A<int E::*, ecb>; using Aedb = A<int E::*, edb>; static_assert(!is_same<Ae, Aecb>, ""); static_assert(!is_same<Ae, Aedb>, ""); static_assert(!is_same<Aecb, Aedb>, ""); static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>>, "");
using An = A<int E::*, nullptr>;
using A0 = A<int E::*, (int E::*)0>;
static_assert(is_same<An, A0>);
}
namespace DeduceDifferentType {
template<int N> struct A {};
template<long N> int a(A<N>); int a_imp = a(A<3>()); int a_exp = a<3>(A<3>());
template<decltype(nullptr)> struct B {};
template<int *P> int b(B<P>); int b_imp = b(B<nullptr>()); int b_exp = b<nullptr>(B<nullptr>());
struct X { constexpr operator int() { return 0; } } x;
template<X &> struct C {};
template<int N> int c(C<N>); int c_imp = c(C<x>()); int c_exp = c<x>(C<x>());
struct Z;
struct Y { constexpr operator Z&(); } y;
struct Z { constexpr operator Y&() { return y; } } z;
constexpr Y::operator Z&() { return z; }
template<Y &> struct D {};
template<Z &z> int d(D<z>); int d_imp = d(D<y>()); int d_exp = d<y>(D<y>());
}
namespace DeclMatch {
template<typename T, T> int f();
template<typename T> class X { friend int f<T, 0>(); static int n; };
template<typename T, T> int f() { return X<T>::n; }
int k = f<int, 0>(); }
namespace PR24921 {
enum E { e };
template<E> void f();
template<int> void f(int);
template<> void f<e>() {}
}
namespace Auto {
namespace Basic {
template<auto x> constexpr auto constant = x;
auto v1 = constant<5>;
auto v2 = constant<true>;
auto v3 = constant<'a'>;
auto v4 = constant<2.5>;
using T1 = decltype(v1);
using T1 = int;
using T2 = decltype(v2);
using T2 = bool;
using T3 = decltype(v3);
using T3 = char;
template<auto v> class B { };
template<auto* p> class B<p> { }; template<auto** pp> class B<pp> { };
template<auto* p0> int &f(B<p0> b); template<auto** pp0> float &f(B<pp0> b);
int a, *b = &a;
int &r = f(B<&a>());
float &s = f(B<&b>());
void type_affects_identity(B<&a>) {}
void type_affects_identity(B<(const int*)&a>) {}
void type_affects_identity(B<(void*)&a>) {}
void type_affects_identity(B<(const void*)&a>) {}
template<typename T, auto *T::*p> struct B<p> {};
template<typename T, auto **T::*p> struct B<p> {};
template<typename T, auto *T::*p0> char &f(B<p0> b); template<typename T, auto **T::*pp0> short &f(B<pp0> b);
struct X { int n; int *p; int **pp; typedef int a, b; };
auto t = f(B<&X::n>()); char &u = f(B<&X::p>());
short &v = f(B<&X::pp>());
struct Y : X {};
void type_affects_identity(B<&X::n>) {}
void type_affects_identity(B<(int Y::*)&X::n>) {} void type_affects_identity(B<(const int X::*)&X::n>) {}
void type_affects_identity(B<(const int Y::*)&X::n>) {}
template<typename T, auto *(*f)(T, typename T::a)> struct B<f> {}; template<typename T, auto **(*f)(T, typename T::b)> struct B<f> {}; int **g(X, int);
B<&g> bg; }
namespace Chained {
template<long n> struct C { };
template<class T> struct D;
template<class T, T n> struct D<C<n>>
{
using Q = T;
};
using DQ = long;
using DQ = D<C<short(2)>>::Q;
template<typename T> struct E;
template<typename T, T n> struct E<int[n]> {
using Q = T;
};
using EQ = E<int[short(42)]>::Q;
using EQ = decltype(sizeof 0);
template<int N> struct F;
template<typename T, T N> int foo(F<N> *) = delete; void foo(void *); void bar(F<0> *p) {
foo(p); }
}
namespace ArrayToPointer {
constexpr char s[] = "test";
template<const auto* p> struct S { };
S<s> p;
template<typename R, typename P, R F(P)> struct A {};
template<typename R, typename P, R F(P)> void x(A<R, P, F> a);
void g(int) { x(A<void, int, &g>()); }
}
namespace DecltypeAuto {
template<auto v> struct A { };
template<decltype(auto) v> struct DA { };
template<auto&> struct R { };
auto n = 0; A<n> a; DA<n> da1; DA<(n)> da2;
R<n> r;
}
namespace Decomposition {
template<auto> struct Any;
template<int N> struct Any<N> { typedef int Int; }; template<short N> struct Any<N> { typedef int Short; }; Any<0>::Int is_int; Any<(short)0>::Short is_short; Any<(char)0>::Short is_char;
template<int, auto> struct NestedAny;
template<auto N> struct NestedAny<0, N>; template<int N> struct NestedAny<0, N> { typedef int Int; }; template<short N> struct NestedAny<0, N> { typedef int Short; }; NestedAny<0, 0>::Int nested_int; NestedAny<0, (short)0>::Short nested_short; NestedAny<0, (char)0>::Short nested_char;
double foo(int, bool);
template<auto& f> struct fn_result_type;
template<class R, class... Args, R (& f)(Args...)>
struct fn_result_type<f>
{
using type = R;
};
using R1 = fn_result_type<foo>::type;
using R1 = double;
template<int, auto &f> struct fn_result_type_partial_order;
template<auto &f> struct fn_result_type_partial_order<0, f>;
template<class R, class... Args, R (& f)(Args...)>
struct fn_result_type_partial_order<0, f> {};
fn_result_type_partial_order<0, foo> frtpo;
}
namespace Variadic {
template<auto... vs> struct value_list { };
using size_t = decltype(sizeof 0);
template<size_t n, class List> struct nth_element;
template<size_t n, class List> constexpr auto nth_element_v = nth_element<n, List>::value;
template<size_t n, auto v0, auto... vs>
struct nth_element<n, value_list<v0, vs...>>
{
static constexpr auto value = nth_element<n - 1, value_list<vs...>>::value;
};
template<auto v0, auto... vs>
struct nth_element<0, value_list<v0, vs...>>
{
static constexpr auto value = v0;
};
static_assert(nth_element_v<2, value_list<'a', 27U, false>> == false, "value mismatch");
}
}
namespace Nested {
template<typename T> struct A {
template<auto X> struct B;
template<auto *P> struct B<P>;
template<auto **P> struct B<P> { using pointee = decltype(+**P); };
template<auto (*P)(T)> struct B<P> { using param = T; };
template<typename U, auto (*P)(T, U)> struct B<P> { using param2 = U; };
};
using Int = int;
int *n;
using Int = A<int>::B<&n>::pointee;
void f(int);
using Int = A<int>::B<&f>::param;
void g(int, int);
using Int = A<int>::B<&g>::param2;
}
namespace rdar41852459 {
template <auto V> struct G {};
template <class T> struct S {
template <auto V> void f() {
G<V> x;
}
template <auto *PV> void f2() {
G<PV> x;
}
template <decltype(auto) V> void f3() {
G<V> x;
}
};
template <auto *PV> struct I {};
template <class T> struct K {
template <auto *PV> void f() {
I<PV> x;
}
template <auto V> void f2() {
I<V> x;
}
template <decltype(auto) V> void f3() {
I<V> x;
}
};
template <decltype(auto)> struct L {};
template <class T> struct M {
template <auto *PV> void f() {
L<PV> x;
}
template <auto V> void f() {
L<V> x;
}
template <decltype(auto) V> void f() {
L<V> x;
}
};
}
namespace PR42362 {
template<auto ...A> struct X { struct Y; void f(int...[A]); };
template<auto ...A> struct X<A...>::Y {};
template<auto ...A> void X<A...>::f(int...[A]) {}
void f() { X<1, 2>::Y y; X<1, 2>().f(0, 0); }
template<typename, auto...> struct Y;
template<auto ...A> struct Y<int, A...> {};
Y<int, 1, 2, 3> y;
template<auto (&...F)()> struct Z { struct Q; };
template<auto (&...F)()> struct Z<F...>::Q {};
Z<f, f, f>::Q q;
}
namespace QualConv {
int *X;
template<const int *const *P> void f() {
using T = decltype(P);
using T = const int* const*;
}
template void f<&X>();
template<const int *const &R> void g() {
using T = decltype(R);
using T = const int *const &;
}
template void g<(const int *const&)X>();
}
namespace FunctionConversion {
struct a { void c(char *) noexcept; };
template<void (a::*f)(char*)> void g() {
using T = decltype(f);
using T = void (a::*)(char*); }
template void g<&a::c>();
void c() noexcept;
template<void (*p)()> void h() {
using T = decltype(p);
using T = void (*)(); }
template void h<&c>();
}
namespace VoidPtr {
template<void *P> void f() {
using T = decltype(P);
using T = void*;
}
int n;
template void f<(void*)&n>();
}
namespace PR42108 {
struct R {};
struct S { constexpr S() {} constexpr S(R) {} };
struct T { constexpr operator S() { return {}; } };
template <const S &> struct A {};
void f() {
A<R{}>(); A<S{}>(); A<T{}>(); }
}
namespace PR46637 {
template<auto (*f)() -> auto> struct X { auto call() { return f(); }
};
X<nullptr> x;
void *f();
X<f> y;
int n = y.call(); }
namespace PR48517 {
template<const int *P> struct A { static constexpr const int *p = P; };
template<typename T> auto make_nonconst() {
static int n;
return A<&n>();
};
using T = decltype(make_nonconst<int>()); using U = decltype(make_nonconst<float>());
static_assert(T::p != U::p);
using T = U;
template<typename T> auto make_const() {
static constexpr int n = 42;
return A<&n>();
};
using V = decltype(make_const<int>()); using W = decltype(make_const<float>());
static_assert(*V::p == *W::p);
static_assert(V::p != W::p);
using V = W;
template<auto V> struct Q {
using X = int;
static_assert(V == "primary template should not be instantiated");
};
template<typename T> struct R {
int n;
constexpr int f() {
return Q<&R::n>::X;
}
};
template<> struct Q<&R<int>::n> { static constexpr int X = 1; };
static_assert(R<int>().f() == 1);
}
namespace dependent_reference {
template<int &r> struct S { int *q = &r; };
template<int> auto f() { static int n; return S<n>(); }
auto v = f<0>();
auto w = f<1>();
static_assert(!is_same<decltype(v), decltype(w)>);
int n = *v.q + *w.q;
}
namespace decay {
template<typename T, typename C, const char *const A[(int)T::count]> struct X {
template<typename CC> void f(const X<T, CC, A> &v) {}
};
struct A {
static constexpr const char *arr[] = {"hello", "world"};
static constexpr int count = 2;
};
void f() {
X<A, int, A::arr> x1;
X<A, float, A::arr> x2;
x1.f(x2);
}
}
namespace TypeSuffix {
template <auto N> struct A {};
template <> struct A<1> { using type = int; }; A<1L>::type a;
template <auto N> struct B {};
template <> struct B<1> { using type = int; }; B<2>::type b;
template <auto N> struct C {};
template <> struct C<'a'> { using type = signed char; }; C<(signed char)'a'>::type c;
template <auto N> struct D {};
template <> struct D<'a'> { using type = signed char; }; D<'b'>::type d;
template <auto N> struct E {};
template <> struct E<'a'> { using type = unsigned char; }; E<(unsigned char)'a'>::type e;
template <auto N> struct F {};
template <> struct F<'a'> { using type = unsigned char; }; F<'b'>::type f;
template <auto... N> struct X {};
X<1, 1u>::type y; X<1, 1>::type z; }