using size_t = __SIZE_TYPE__;
namespace std {
struct type_info;
}
template<float> struct Float {};
using F1 = Float<1.0f>; using F1 = Float<2.0f / 2>;
struct S { int n[3]; } s; union U { int a, b; } u;
int n;
template<int *> struct IntPtr {};
using IPn = IntPtr<&n + 1>; using IPn = IntPtr<&n + 1>;
using IP2 = IntPtr<&s.n[2]>; using IP2 = IntPtr<s.n + 2>;
using IP3 = IntPtr<&s.n[3]>; using IP3 = IntPtr<s.n + 3>;
template<int &> struct IntRef {};
using IPn = IntRef<*(&n + 1)>; using IPn = IntRef<*(&n + 1)>;
using IP2 = IntRef<s.n[2]>; using IP2 = IntRef<*(s.n + 2)>;
using IP3 = IntRef<s.n[3]>; using IP3 = IntRef<*(s.n + 3)>;
template<S> struct Struct {};
using S123 = Struct<S{1, 2, 3}>;
using S123 = Struct<S{1, 2, 3}>; using S123 = Struct<S{1, 2, 4}>; template<U> struct Union {};
using U1 = Union<U{1}>;
using U1 = Union<U{.a = 1}>; using U1 = Union<U{.b = 1}>;
template<_Complex int> struct ComplexInt {};
using CI = ComplexInt<1 + 3i>; using CI = ComplexInt<1 + 3i>;
template<_Complex float> struct ComplexFloat {};
using CF = ComplexFloat<1.0f + 3.0fi>; using CF = ComplexFloat<1.0f + 3.0fi>;
namespace ClassNTTP {
struct A { int x, y;
};
template<A a> constexpr int f() { return a.y; }
static_assert(f<A{1,2}>() == 2);
template<A a> int id;
constexpr A a = {1, 2};
static_assert(&id<A{1,2}> == &id<a>);
static_assert(&id<A{1,3}> != &id<a>);
int k = id<1>;
struct B {
constexpr B() {}
constexpr B(int) = delete; };
template<B> struct Q {}; Q<1> q;
struct C {
constexpr C() {}
C(const C&) = delete; };
template<C> struct R {}; constexpr C c;
R<c> r; }
namespace ConvertedConstant {
struct A {
constexpr A(float) {}
};
template <A> struct X {};
void f(X<1.0f>) {} void f(X<2>) {} }
namespace CopyCounting {
struct A { int n; constexpr A(int n = 0) : n(n) {} constexpr A(const A &a) : n(a.n+1) {} };
template<A a> struct X {};
template<A a> constexpr int f(X<a> x) { return a.n; }
static_assert(f(X<A{}>()) == 0);
template<A a> struct Y { void f(); };
template<A a> void g(Y<a> y) { y.Y<a>::f(); }
void h() { constexpr A a; g<a>(Y<a>{}); }
template<A a> struct Z {
constexpr int f() {
constexpr A v = a; return Z<v>().f() + 1; }
};
template<> struct Z<A{20}> {
constexpr int f() {
return 32;
}
};
static_assert(Z<A{}>().f() == 42);
}
namespace StableAddress {
template<size_t N> struct str {
char arr[N];
};
template<size_t N> str(const char (&)[N]) -> str<N>;
template<str s> constexpr int sum() {
int n = 0;
for (char c : s.arr)
n += c;
return n;
}
static_assert(sum<str{"$hello $world."}>() == 1234);
}
namespace TemplateSpecializations {
struct A { int arr[10]; };
template<A> struct X;
using T = X<A{1, 2, 3}>;
using T = X<A{1, 2, 3, 0}>;
using T = X<A{1, 2, 3, 0, 0}>;
using T = X<A{1, 2, 3, 0, 0, 0}>;
template<> struct X<A{1, 2, 3, 4}> {};
X<A{1, 2, 3, 4, 0}> x;
template<auto V, auto W> constexpr bool Same = false;
template<auto V> constexpr bool Same<V, V> = true;
static_assert(Same<A{}, A{0, 0}>);
static_assert(Same<A{1}, A{1, 0}>);
static_assert(!Same<A{1}, A{1, 1}>);
template<int N> struct X<A{N, N}> {};
template <A V> requires Same<V, A{V.arr[0], V.arr[0]}>
struct X<V> {
static constexpr bool match = true;
};
static_assert(X<A{1, 1}>::match);
static_assert(X<A{2, 2}>::match);
static_assert(X<A{1, 2}>::match);
template<int, A> struct Y; template<int N> struct Y<N, A{N, N, N}> {};
Y<1, A{1, 1, 1, 0}> y1;
Y<1, A{1, 1, 1, 1}> y2;
template<A, A> struct Z; template<A V> struct Z<V, V> {};
Z<A{1, 2}, A{1, 2, 0}> z1;
Z<A{1, 2}, A{1, 3}> z2;
template struct Z<A{1}, A{1, 0}>;
}
namespace Diags {
struct A { int n, m; };
template<A a> struct X { static_assert(a.n == a.m); }; template struct X<A{1, 2}>; }
namespace CTADPartialOrder {
template<int> struct A {};
template<typename T, typename U, A a> struct X; template<typename T, A a> struct X<T, int, a> { static constexpr int n = 1; }; template<typename T, A a> struct X<T *, int, a> { static constexpr int n = 2; };
template<typename T, A a> struct X<T, T, a> { static constexpr int n = 3; };
A<0> a;
static_assert(X<void, int, a>::n == 1);
static_assert(X<int*, int, a>::n == 2);
static_assert(X<void, void, a>::n == 3);
static_assert(X<int, int, a>::n == -1); static_assert(X<int*, void, a>::n == 2);
template<typename T, A<0> a> struct X<T, T, a> { static constexpr int n = 4; };
static_assert(X<float, float, a>::n == 4);
}
namespace UnnamedBitfield {
struct A {
__INT32_TYPE__ : 32;
};
template <A> struct X {};
constexpr A a;
using T = X<a>;
using T = X<A{}>;
using T = X<(A())>;
using T = X<__builtin_bit_cast(A, 0)>; }
namespace Temporary {
template<const int &> struct A {};
A<0> a0;
A<(const int&)1> a1; A<(int&&)2> a2;
int &&r3 = 3;
const int &r4 = 4;
A<r3> a3; A<r4> a4;
struct X { int a[5]; };
X &&x = X{};
A<x.a[3]> a5;
template<const int*> struct B {};
B<&(int&)(int&&)0> b0; B<&r3> b3; B<&x.a[3]> b5;
struct C { const int *p[2]; };
template<C> struct D {};
D<C{nullptr, &r3}> d; }
namespace StringLiteral {
template<decltype(auto)> struct Y {};
Y<&"hello"> y1; Y<"hello"> y2; Y<+"hello"> y3; Y<"hello"[2]> y4;
struct A { const char *p; };
struct B { const char &r; };
Y<A{"hello"}> y5; Y<B{"hello"[2]}> y6; }
namespace TypeInfo {
template<decltype(auto)> struct Y {};
Y<&typeid(int)> y1; Y<typeid(int)> y2;
struct A { const std::type_info *p; };
struct B { const std::type_info &r; };
Y<A{&typeid(int)}> y3; Y<B{typeid(int)}> y4; }
namespace Predefined {
template<decltype(auto)> struct Y {};
struct A { const char *p; };
struct B { const char &r; };
void f() {
Y<__func__>(); Y<__PRETTY_FUNCTION__>(); Y<(__func__)>(); Y<&__func__>(); Y<*&__func__>(); Y<A{__func__}>(); Y<B{__func__[0]}>(); }
}
namespace DependentCTAD {
template<auto> struct A {};
template<template<typename> typename T, T V> void f(A<V>); template<typename T> struct B { constexpr B(T) {} };
void g() {
f(A<B(0)>()); f<B>(A<B(0)>()); }
}