#include <iostream>
#include <type_traits>
#include <string>
using callback = auto (*)() -> void;
class foo_data final
{
public:
operator callback() { return nullptr; }
};
template <class Ty1, std::enable_if_t<
std::is_pointer<Ty1>{}(), std::nullptr_t> = nullptr>
auto foo(Ty1&&) { printf("redirect user data\n"); }
template <class Ty1>
auto foo(std::nullptr_t) -> void { printf("nil\n"); }
template <class Ty1>
auto foo(bool) -> void { printf("boolean\n"); }
template <class Ty1>
auto foo(std::size_t) -> void { printf("integer\n"); }
template <class Ty1>
auto foo(std::ptrdiff_t) -> void { printf("integer\n"); }
template <class Ty1>
auto foo(double) -> void { printf("number\n"); }
template <class Ty1>
auto foo(const char*) -> void { printf("native string\n"); }
template <class Ty1>
auto foo(const std::string&) -> void { printf("C++ string\n"); }
template <class Ty1>
auto foo(const void*) -> void { printf("user data\n"); }
int main()
{
// foo(nullptr);
// foo(true);
// foo(false);
// std::uint8_t num_data = 10;
// foo(100);
// foo(-100);
// foo(num_data);
// foo(1.4);
// foo(-1.3f);
// foo("The text");
// foo(std::string{});
// int* ptr_data = nullptr;
// foo(ptr_data);
auto d = foo_data{};
foo<decltype(d)>(d);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxzdHJpbmc+Cgp1c2luZyBjYWxsYmFjayA9IGF1dG8gKCopKCkgLT4gdm9pZDsKCmNsYXNzIGZvb19kYXRhIGZpbmFsCnsKcHVibGljOgoJb3BlcmF0b3IgY2FsbGJhY2soKSB7IHJldHVybiBudWxscHRyOyB9Cn07Cgp0ZW1wbGF0ZSA8Y2xhc3MgVHkxLCBzdGQ6OmVuYWJsZV9pZl90PAoJc3RkOjppc19wb2ludGVyPFR5MT57fSgpLCBzdGQ6Om51bGxwdHJfdD4gPSBudWxscHRyPgphdXRvIGZvbyhUeTEmJikgeyBwcmludGYoInJlZGlyZWN0IHVzZXIgZGF0YVxuIik7IH0KCnRlbXBsYXRlIDxjbGFzcyBUeTE+CmF1dG8gZm9vKHN0ZDo6bnVsbHB0cl90KSAtPiB2b2lkIHsgcHJpbnRmKCJuaWxcbiIpOyB9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVHkxPgphdXRvIGZvbyhib29sKSAtPiB2b2lkIHsgcHJpbnRmKCJib29sZWFuXG4iKTsgfQoKdGVtcGxhdGUgPGNsYXNzIFR5MT4KYXV0byBmb28oc3RkOjpzaXplX3QpIC0+IHZvaWQgeyBwcmludGYoImludGVnZXJcbiIpOyB9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVHkxPgphdXRvIGZvbyhzdGQ6OnB0cmRpZmZfdCkgLT4gdm9pZCB7IHByaW50ZigiaW50ZWdlclxuIik7IH0KCnRlbXBsYXRlIDxjbGFzcyBUeTE+CmF1dG8gZm9vKGRvdWJsZSkgLT4gdm9pZCB7IHByaW50ZigibnVtYmVyXG4iKTsgfQoKdGVtcGxhdGUgPGNsYXNzIFR5MT4KYXV0byBmb28oY29uc3QgY2hhciopIC0+IHZvaWQgeyBwcmludGYoIm5hdGl2ZSBzdHJpbmdcbiIpOyB9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVHkxPgphdXRvIGZvbyhjb25zdCBzdGQ6OnN0cmluZyYpIC0+IHZvaWQgeyBwcmludGYoIkMrKyBzdHJpbmdcbiIpOyB9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVHkxPgphdXRvIGZvbyhjb25zdCB2b2lkKikgLT4gdm9pZCB7IHByaW50ZigidXNlciBkYXRhXG4iKTsgfQoKaW50IG1haW4oKQp7CgkvLyBmb28obnVsbHB0cik7CgkKCS8vIGZvbyh0cnVlKTsKCS8vIGZvbyhmYWxzZSk7CgkKCS8vIHN0ZDo6dWludDhfdCBudW1fZGF0YSA9IDEwOwoJLy8gZm9vKDEwMCk7CgkvLyBmb28oLTEwMCk7CgkvLyBmb28obnVtX2RhdGEpOwoJCgkvLyBmb28oMS40KTsKCS8vIGZvbygtMS4zZik7CgkKCS8vIGZvbygiVGhlIHRleHQiKTsKCS8vIGZvbyhzdGQ6OnN0cmluZ3t9KTsKCQoJLy8gaW50KiBwdHJfZGF0YSA9IG51bGxwdHI7CgkvLyBmb28ocHRyX2RhdGEpOwoJCglhdXRvIGQgPSBmb29fZGF0YXt9OwoJZm9vPGRlY2x0eXBlKGQpPihkKTsKCQoJcmV0dXJuIDA7Cn0=