Skip to content

Instantly share code, notes, and snippets.

@tatsuhiro-t
Last active October 31, 2015 01:42
Show Gist options
  • Save tatsuhiro-t/6360660284d028c055d2 to your computer and use it in GitHub Desktop.
Save tatsuhiro-t/6360660284d028c055d2 to your computer and use it in GitHub Desktop.
Describe data type in English
#include <iostream>
#include <cxxabi.h>
template <typename T> struct TypeDescriptor {};
// function
template <typename Ret, typename... Args>
std::ostream &operator<<(std::ostream &os,
const TypeDescriptor<Ret(Args...)> &td) {
return os << "function returning " << TypeDescriptor<Ret>();
}
// pointer
template <typename T>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<T *> &td) {
return os << "pointer to " << TypeDescriptor<T>();
}
// reference
template <typename T>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<T &> &td) {
return os << "reference to " << TypeDescriptor<T>();
}
template <typename T>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<T &&> &td) {
return os << "rvalue reference to " << TypeDescriptor<T>();
}
// array
template <typename T>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<T[]> &td) {
return os << "array of " << TypeDescriptor<T>();
}
template <typename T>
std::ostream &operator<<(std::ostream &os,
const TypeDescriptor<const T[]> &td) {
return os << "array of " << TypeDescriptor<const T>();
}
// array with size
template <typename T, size_t N>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<T[N]> &td) {
return os << "array (size " << N << ") of " << TypeDescriptor<T>();
}
template <typename T, size_t N>
std::ostream &operator<<(std::ostream &os,
const TypeDescriptor<const T[N]> &td) {
return os << "array (size " << N << ") of " << TypeDescriptor<const T>();
}
// const
template <typename T>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<const T> &td) {
return os << "const-qualified " << TypeDescriptor<T>();
}
// terminal
template <typename T>
std::ostream &operator<<(std::ostream &os, const TypeDescriptor<T> &td) {
int status;
auto mname = typeid(T).name();
auto name = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
if (status != 0) {
return os << mname;
}
os << name;
free(name);
return os;
}
int main() {
std::cerr << TypeDescriptor<int()>() << std::endl;
std::cerr << TypeDescriptor<int[20]>() << std::endl;
std::cerr << TypeDescriptor<int[]>() << std::endl;
std::cerr << TypeDescriptor<const int>() << std::endl;
std::cerr << TypeDescriptor<const int[]>() << std::endl;
std::cerr << TypeDescriptor<int *>() << std::endl;
std::cerr << TypeDescriptor<const int *>() << std::endl;
std::cerr << TypeDescriptor<const int *const>() << std::endl;
std::cerr << TypeDescriptor<const int &>() << std::endl;
std::cerr << TypeDescriptor<int &&>() << std::endl;
std::cerr << TypeDescriptor<const int(*())[10]>() << std::endl;
std::cerr << TypeDescriptor<const int (*(*)())[10][9]>() << std::endl;
std::cerr << TypeDescriptor<const char *>() << std::endl;
std::cerr << TypeDescriptor<char *const>() << std::endl;
std::cerr << TypeDescriptor<const char *const>() << std::endl;
std::cerr << TypeDescriptor<const char[10]>() << std::endl;
std::cerr << TypeDescriptor<const std::string[30]>() << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment