Skip to content

Instantly share code, notes, and snippets.

@ipid
Last active April 8, 2019 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ipid/8178b80c4a10302f6d8452282203f32f to your computer and use it in GitHub Desktop.
Save ipid/8178b80c4a10302f6d8452282203f32f to your computer and use it in GitHub Desktop.
Functions to print name of a type, with std::cout. Work under C++14.
#pragma once
#ifndef PRINT_TYPE_NAME_HPP_DEFINED
#define PRINT_TYPE_NAME_HPP_DEFINED
/*
Usage:
void print_type_name<T>() {...}
Print type name of T, exactly the same as declaration.
void print_type_name_endl<T>() {...}
Calls print_type_name<T> and prints std::endl.
Example:
print_type_name_endl<decltype(123)>(); // int
print_type_name_endl<decltype((123))>(); // int &
print_type_name_endl<int * volatile * const volatile>(); // Exactly as input
*/
#include <iostream>
#include <type_traits>
namespace steps_to_peel_type {
template <typename TNotPtr>
void step3_peel_cv() {
if constexpr (std::is_const_v<TNotPtr>) {
std::cout << "const ";
}
if constexpr (std::is_volatile_v<TNotPtr>) {
std::cout << "volatile ";
}
std::cout << typeid(std::remove_cv_t<TNotPtr>).name();
}
template <typename TNotRef>
void step2_peel_pointer_recursively() {
// int *** -> int
using rm_ptr_t = std::remove_pointer_t<TNotRef>;
if constexpr (std::is_pointer_v<TNotRef>) {
step2_peel_pointer_recursively<rm_ptr_t>();
std::cout << " *";
if constexpr (std::is_const_v<TNotRef>) {
std::cout << " const";
}
if constexpr (std::is_volatile_v<TNotRef>) {
std::cout << " volatile";
}
} else {
step3_peel_cv<TNotRef>();
}
}
template <typename T>
void step1_peel_reference() {
// T && -> T
// T & -> T
using rm_ref_t = std::remove_reference_t<T>;
step2_peel_pointer_recursively<rm_ref_t>();
if constexpr (std::is_lvalue_reference_v<T>) {
std::cout << " &";
} else if constexpr (std::is_rvalue_reference_v<T>) {
std::cout << " &&";
}
}
}
template <typename T>
void print_type_name() {
std::cout << "[";
steps_to_peel_type::step1_peel_reference<T>();
std::cout << "]";
}
template <typename T>
void print_type_name_endl() {
print_type_name<T>();
std::cout << std::endl;
}
#endif // PRINT_TYPE_NAME_HPP_DEFINED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment