27inline namespace cpp20 {
42 if constexpr (std::is_const<T>::value) {
45 }
else if constexpr (std::is_lvalue_reference<T>::value) {
46 return os <<
"reference to "
48 typename std::remove_reference<T>::type>();
49 }
else if constexpr (std::is_pointer<T>::value) {
50 using PointedT =
typename std::remove_pointer<T>::type;
51 if constexpr (std::is_function<PointedT>::value) {
52 return os <<
"pointer to function returning "
54 typename std::invoke_result<PointedT>::type>();
58 }
else if constexpr (std::is_array<T>::value) {
59 if constexpr (std::is_bounded_array<T>::value) {
60 os << std::extent<T>::value <<
" element ";
63 return os <<
"array of "
65 typename std::remove_extent<T>::type>();
66 }
else if constexpr (std::is_function<T>::value) {
67 return os <<
"function returning "
69 typename std::invoke_result<T>::type>();
70 }
else if constexpr (std::is_fundamental<T>::value) {
75 if constexpr (std::is_integral<T>::value) {
79 if constexpr (std::is_unsigned<T>::value) {
83 if constexpr (
sizeof(T) == 1) {
return os <<
"char"; }
84 else if constexpr (
sizeof(T) == 2) {
return os <<
"short int"; }
85 else if constexpr (
sizeof(T) == 4) {
return os <<
"int"; }
86 else if constexpr (
sizeof(T) == 8) {
return os <<
"long int"; }
87 else return exercise_2_4::error_unhandled_type<T>();
89 return exercise_2_4::error_unhandled_type<T>();
92 return exercise_2_4::error_unhandled_type<T>();
consteval T * error_unhandled_type()
Produce a compile-time failure for an "unhandled" type.
Encapsulate solution for Exercise 2-4.
std::ostream & operator<<(std::ostream &os, type_descriptor_eng< T > const &)
Encapsulate solution for Exercise 2-5.
Display data-types in English wording.
Display data-types in English wording.