From 72cf70045b8347a5e4276fbce809a85cd54403bc Mon Sep 17 00:00:00 2001
From: Sven Göthel
Date: Mon, 2 Sep 2024 04:17:23 +0200
Subject: type_cue: Add to_string() and fprint(FILE *, ..) - decouple
compilation unit from jau/string_util.hpp
---
include/jau/string_util.hpp | 2 +-
include/jau/type_traits_queries.hpp | 135 +++++++++++++++++++++---------------
2 files changed, 79 insertions(+), 58 deletions(-)
(limited to 'include/jau')
diff --git a/include/jau/string_util.hpp b/include/jau/string_util.hpp
index 6584c07..7788f1b 100644
--- a/include/jau/string_util.hpp
+++ b/include/jau/string_util.hpp
@@ -403,7 +403,7 @@ namespace jau {
bool> = true>
inline std::string to_string(const value_type & ref) {
(void)ref;
- return "jau::to_string not available for "+type_cue::print("unknown", TypeTraitGroup::ALL);
+ return "jau::to_string n/a for type "+type_cue::to_string();
}
template
diff --git a/include/jau/type_traits_queries.hpp b/include/jau/type_traits_queries.hpp
index f3f9616..5b9036c 100644
--- a/include/jau/type_traits_queries.hpp
+++ b/include/jau/type_traits_queries.hpp
@@ -37,6 +37,9 @@
namespace jau {
+ // #include "jau/string_util.hpp"
+ std::string format_string(const char* format, ...);
+
/** \addtogroup CppLang
*
* @{
@@ -113,7 +116,7 @@ namespace jau {
* or "unnamed_type"
if RTTI is disabled.
*
*/
- static const char * name() {
+ static const char * name() noexcept {
#if defined(__cxx_rtti_available__)
return typeid(T).name();
#else
@@ -132,98 +135,116 @@ namespace jau {
struct type_cue : public type_name_cue
{
+ static std::string to_string(const bool withSize=true) noexcept {
+ if( withSize ) {
+ return jau::format_string("%s[%zu bytes]", type_name_cue::name(), sizeof(T));
+ } else {
+ return type_name_cue::name();
+ }
+ }
+
/**
* Print information of this type to stdout, potentially with all Type traits known.
+ * @param stream output stream
* @param typedefname the code typedefname (or typename) as a string, should match T
* @param verbose if true, prints all Type traits known for this type. Be aware of the long output. Defaults to false.
*/
- static void print(const std::string& typedefname, const TypeTraitGroup verbosity=TypeTraitGroup::NONE) {
- printf("Type: %s -> %s, %zu bytes\n", typedefname.c_str(), type_name_cue::name(), sizeof(T));
+ static void fprint(std::FILE *stream, const std::string& typedefname, const TypeTraitGroup verbosity=TypeTraitGroup::NONE) {
+ std::fprintf(stream, "Type: %s -> %s, %zu bytes\n", typedefname.c_str(), type_name_cue::name(), sizeof(T));
if( isTypeTraitBitSet(verbosity, TypeTraitGroup::PRIMARY_TYPE_CAT) ) {
- printf(" Primary Type Categories\n");
- printf(" void %d\n", std::is_void_v);
- printf(" null ptr %d\n", std::is_null_pointer_v);
- printf(" integral %d\n", std::is_integral_v);
- printf(" floating point %d\n", std::is_floating_point_v);
- printf(" array %d\n", std::is_array_v);
- printf(" enum %d\n", std::is_enum_v);
- printf(" union %d\n", std::is_union_v);
- printf(" class %d\n", std::is_class_v);
- printf(" function %d\n", std::is_function_v);
- printf(" pointer %d\n", std::is_pointer_v);
- printf(" lvalue ref %d\n", std::is_lvalue_reference_v);
- printf(" rvalue ref %d\n", std::is_rvalue_reference_v);
- printf(" member obj ptr %d\n", std::is_member_object_pointer_v);
- printf(" member func ptr %d\n", std::is_member_function_pointer_v);
- printf("\n");
+ std::fprintf(stream, " Primary Type Categories\n");
+ std::fprintf(stream, " void %d\n", std::is_void_v);
+ std::fprintf(stream, " null ptr %d\n", std::is_null_pointer_v);
+ std::fprintf(stream, " integral %d\n", std::is_integral_v);
+ std::fprintf(stream, " floating point %d\n", std::is_floating_point_v);
+ std::fprintf(stream, " array %d\n", std::is_array_v);
+ std::fprintf(stream, " enum %d\n", std::is_enum_v);
+ std::fprintf(stream, " union %d\n", std::is_union_v);
+ std::fprintf(stream, " class %d\n", std::is_class_v);
+ std::fprintf(stream, " function %d\n", std::is_function_v);
+ std::fprintf(stream, " pointer %d\n", std::is_pointer_v);
+ std::fprintf(stream, " lvalue ref %d\n", std::is_lvalue_reference_v);
+ std::fprintf(stream, " rvalue ref %d\n", std::is_rvalue_reference_v);
+ std::fprintf(stream, " member obj ptr %d\n", std::is_member_object_pointer_v);
+ std::fprintf(stream, " member func ptr %d\n", std::is_member_function_pointer_v);
+ std::fprintf(stream, "\n");
}
if( isTypeTraitBitSet(verbosity, TypeTraitGroup::TYPE_PROPERTIES) ) {
- printf(" Type Properties\n");
- printf(" const %d\n", std::is_const_v);
- printf(" volatile %d\n", std::is_volatile_v);
- printf(" trivial %d\n", std::is_trivial_v);
- printf(" trivially_copy. %d\n", std::is_trivially_copyable_v);
- printf(" standard_layout %d\n", std::is_standard_layout_v);
- printf(" pod %d\n", std::is_standard_layout_v && std::is_trivial_v); // is_pod<>() is deprecated
- printf(" unique_obj_rep %d\n", std::has_unique_object_representations_v);
- printf(" empty %d\n", std::is_empty_v);
- printf(" polymorphic %d\n", std::is_polymorphic_v);
- printf(" abstract %d\n", std::is_abstract_v);
- printf(" final %d\n", std::is_final_v);
- printf(" aggregate %d\n", std::is_aggregate_v);
- printf(" signed %d\n", std::is_signed_v);
- printf(" unsigned %d\n", std::is_unsigned_v);
+ std::fprintf(stream, " Type Properties\n");
+ std::fprintf(stream, " const %d\n", std::is_const_v);
+ std::fprintf(stream, " volatile %d\n", std::is_volatile_v);
+ std::fprintf(stream, " trivial %d\n", std::is_trivial_v);
+ std::fprintf(stream, " trivially_copy. %d\n", std::is_trivially_copyable_v);
+ std::fprintf(stream, " standard_layout %d\n", std::is_standard_layout_v);
+ std::fprintf(stream, " pod %d\n", std::is_standard_layout_v && std::is_trivial_v); // is_pod<>() is deprecated
+ std::fprintf(stream, " unique_obj_rep %d\n", std::has_unique_object_representations_v);
+ std::fprintf(stream, " empty %d\n", std::is_empty_v);
+ std::fprintf(stream, " polymorphic %d\n", std::is_polymorphic_v);
+ std::fprintf(stream, " abstract %d\n", std::is_abstract_v);
+ std::fprintf(stream, " final %d\n", std::is_final_v);
+ std::fprintf(stream, " aggregate %d\n", std::is_aggregate_v);
+ std::fprintf(stream, " signed %d\n", std::is_signed_v);
+ std::fprintf(stream, " unsigned %d\n", std::is_unsigned_v);
#if __cplusplus > 202002L
// C++ 23
- printf(" bounded_array %d\n", std::is_bounded_array_v);
- printf(" unbounded_array %d\n", std::is_unbounded_array_v);
- printf(" scoped enum %d\n", std::is_scoped_enum_v);
+ std::fprintf(stream, " bounded_array %d\n", std::is_bounded_array_v);
+ std::fprintf(stream, " unbounded_array %d\n", std::is_unbounded_array_v);
+ std::fprintf(stream, " scoped enum %d\n", std::is_scoped_enum_v);
#endif
- printf("\n");
+ std::fprintf(stream, "\n");
}
if( isTypeTraitBitSet(verbosity, TypeTraitGroup::COMPOSITE_TYPE_CAT) ) {
- printf(" Composite Type Categories\n");
- printf(" fundamental %d\n", std::is_fundamental_v);
- printf(" arithmetic %d\n", std::is_arithmetic_v);
- printf(" scalar %d\n", std::is_scalar_v);
- printf(" object %d\n", std::is_object_v);
- printf(" compound %d\n", std::is_compound_v);
- printf(" reference %d\n", std::is_reference_v);
- printf(" member ptr %d\n", std::is_member_pointer_v);
- printf("\n");
+ std::fprintf(stream, " Composite Type Categories\n");
+ std::fprintf(stream, " fundamental %d\n", std::is_fundamental_v);
+ std::fprintf(stream, " arithmetic %d\n", std::is_arithmetic_v);
+ std::fprintf(stream, " scalar %d\n", std::is_scalar_v);
+ std::fprintf(stream, " object %d\n", std::is_object_v);
+ std::fprintf(stream, " compound %d\n", std::is_compound_v);
+ std::fprintf(stream, " reference %d\n", std::is_reference_v);
+ std::fprintf(stream, " member ptr %d\n", std::is_member_pointer_v);
+ std::fprintf(stream, "\n");
}
if( isTypeTraitBitSet(verbosity, TypeTraitGroup::SUPPORTED_OPERATIONS) ) {
- printf(" Supported Operations\n");
- printf(" constructible %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " Supported Operations\n");
+ std::fprintf(stream, " constructible %d {trivially %d, nothrow %d}\n",
std::is_constructible_v,
std::is_trivially_constructible_v, std::is_nothrow_constructible_v);
- printf(" default_constructible %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " default_constructible %d {trivially %d, nothrow %d}\n",
std::is_default_constructible_v,
std::is_trivially_default_constructible_v, std::is_nothrow_default_constructible_v);
- printf(" copy_constructible %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " copy_constructible %d {trivially %d, nothrow %d}\n",
std::is_copy_constructible_v,
std::is_trivially_copy_constructible_v, std::is_nothrow_copy_constructible_v);
- printf(" move_constructible %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " move_constructible %d {trivially %d, nothrow %d}\n",
std::is_move_constructible_v,
std::is_trivially_move_constructible_v, std::is_nothrow_move_constructible_v);
- printf(" assignable %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " assignable %d {trivially %d, nothrow %d}\n",
std::is_assignable_v,
std::is_trivially_assignable_v, std::is_nothrow_assignable_v);
- printf(" copy_assignable %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " copy_assignable %d {trivially %d, nothrow %d}\n",
std::is_copy_assignable_v,
std::is_trivially_copy_assignable_v, std::is_nothrow_copy_assignable_v);
- printf(" move_assignable %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " move_assignable %d {trivially %d, nothrow %d}\n",
std::is_move_assignable_v,
std::is_trivially_move_assignable_v, std::is_nothrow_move_assignable_v);
- printf(" destructible %d {trivially %d, nothrow %d, virtual %d}\n",
+ std::fprintf(stream, " destructible %d {trivially %d, nothrow %d, virtual %d}\n",
std::is_destructible_v,
std::is_trivially_destructible_v, std::is_nothrow_destructible_v,
std::has_virtual_destructor_v);
- printf(" swappable %d {nothrow %d}\n",
+ std::fprintf(stream, " swappable %d {nothrow %d}\n",
std::is_swappable_v, std::is_nothrow_swappable_v);
}
}
+ /**
+ * Print information of this type to stdout, potentially with all Type traits known.
+ * @param typedefname the code typedefname (or typename) as a string, should match T
+ * @param verbose if true, prints all Type traits known for this type. Be aware of the long output. Defaults to false.
+ */
+ static void print(const std::string& typedefname, const TypeTraitGroup verbosity=TypeTraitGroup::NONE) {
+ fprint(stdout, typedefname, verbosity);
+ }
+
};
#define JAU_TYPENAME_CUE(A) template<> struct jau::type_name_cue { static const char * name() { return #A; } };
#define JAU_TYPENAME_CUE_ALL(A) JAU_TYPENAME_CUE(A) JAU_TYPENAME_CUE(A*) JAU_TYPENAME_CUE(const A*) JAU_TYPENAME_CUE(A&) JAU_TYPENAME_CUE(const A&) // NOLINT(bugprone-macro-parentheses)
--
cgit v1.2.3