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