Last active
April 8, 2019 14:08
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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