class Iterable {
public:
using const_iterator = int* const*;
const_iterator begin() { return nullptr; }
const_iterator end() { return nullptr; }
};
using AliasWithPtr = int*;
AliasWithPtr return_alias_with_ptr() {
return nullptr;
}
AliasWithPtr* return_ptr_to_alias_with_ptr() {
return nullptr;
}
typedef int* TypedefWithPtr;
TypedefWithPtr return_typedef_with_ptr() {
return nullptr;
}
class Foo {
public:
void foo() {}
};
template <typename T>
T copy(T orig) {
auto copy = orig;
return copy;
}
void f();
int main() {
int integer;
Foo foo;
auto int_copy = integer;
auto int_copy2 = copy(integer);
const auto const_int_copy = integer;
const auto& const_int_ref = integer;
auto raw_int_ptr = &integer;
auto* raw_int_ptr_copy = copy(&integer);
const auto const_raw_int_ptr = &integer;
const auto& const_raw_int_ptr_ref = &integer;
auto* raw_int_ptr_valid = &integer;
const auto* const_raw_int_ptr_valid = &integer;
auto raw_foo_ptr = &foo;
const auto const_raw_foo_ptr = &foo;
const auto& const_raw_foo_ptr_ref = &foo;
auto* raw_foo_ptr_valid = &foo;
const auto* const_raw_foo_ptr_valid = &foo;
int* int_ptr;
auto double_ptr_auto = &int_ptr;
auto* double_ptr_auto_ptr = &int_ptr;
auto** double_ptr_auto_double_ptr = &int_ptr;
auto function_ptr = &f;
auto method_ptr = &Foo::foo;
int* const* const volatile** const* pointer_awesomeness;
auto auto_awesome = pointer_awesomeness;
auto& int_ptr_ref = int_ptr;
const auto& const_int_ptr_ref = int_ptr;
auto&& int_ptr_rref = static_cast<int*&&>(int_ptr);
const auto&& const_int_ptr_rref = static_cast<int*&&>(int_ptr);
static auto static_ptr = new int;
Iterable iterable;
for (auto& it : iterable) {
(void)it;
}
auto alias = return_alias_with_ptr();
auto* good_ptr_to_alias = return_ptr_to_alias_with_ptr();
auto bad_ptr_to_alias = return_ptr_to_alias_with_ptr();
auto tdef = return_typedef_with_ptr();
auto lambda = [foo_ptr = &foo] { return *foo_ptr; };
}
template <typename T, typename U>
T* specialization(U _) {
return nullptr;
}
template <>
void* specialization(int) {
void* p = nullptr;
auto bad = p;
return bad;
}
template <class T, class U>
struct WithDependentType {
void func() {
auto x = T::foo();
}
void f2() {};
};
template <class U>
struct WithDependentType<void*, U> {
void f2() {
void* p = nullptr;
auto bad = p;
auto u = U();
}
};
constexpr auto foo = WithDependentType<void*, void*>();
void use_template() {
struct S {
static int* foo() { return nullptr; };
};
WithDependentType<S, int>().func();
}
template <class T>
concept Concept = true;
void use_concept() {
int x = 0;
Concept auto c = &x;
}
template <class T>
T auto_function_return_alias_with_ptr() {
return return_alias_with_ptr();
}
void template_function() {
auto auto_alias = auto_function_return_alias_with_ptr<AliasWithPtr>();
}
template <class T>
using AliasOfT = T;
template <class T>
AliasOfT<T> auto_function_return_elaborated_alias_with_ptr() {
return return_alias_with_ptr();
}
void alias_template_specialization_function() {
auto auto_alias =
auto_function_return_elaborated_alias_with_ptr<AliasWithPtr>();
}
struct auto_type_level_three {
template <class T>
inline auto foo() const {
return T();
}
};
constexpr auto auto_type_level_two = auto_type_level_three{};
template <typename T>
constexpr auto auto_type_level_one() {
return auto_type_level_two.foo<T>();
}
void nested_auto_function() {
auto x = auto_type_level_one<AliasWithPtr>();
}