aboutsummaryrefslogtreecommitdiffstats
path: root/include/jau
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-09-02 04:17:23 +0200
committerSven Göthel <[email protected]>2024-09-02 13:39:33 +0200
commit72cf70045b8347a5e4276fbce809a85cd54403bc (patch)
treea33f9310d35272a98bc5ba1e5f1787126948e889 /include/jau
parent4b886061fcf166bced932f9a8df8655ec4af2347 (diff)
type_cue: Add to_string() and fprint(FILE *, ..) - decouple compilation unit from jau/string_util.hpp
Diffstat (limited to 'include/jau')
-rw-r--r--include/jau/string_util.hpp2
-rw-r--r--include/jau/type_traits_queries.hpp135
2 files changed, 79 insertions, 58 deletions
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<T> not available for "+type_cue<value_type>::print("unknown", TypeTraitGroup::ALL);
+ return "jau::to_string<T> n/a for type "+type_cue<value_type>::to_string();
}
template<typename T>
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 <code>"unnamed_type"</code> if RTTI is disabled.
* </p>
*/
- 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<T>
{
+ static std::string to_string(const bool withSize=true) noexcept {
+ if( withSize ) {
+ return jau::format_string("%s[%zu bytes]", type_name_cue<T>::name(), sizeof(T));
+ } else {
+ return type_name_cue<T>::name();
+ }
+ }
+
/**
* Print information of this type to stdout, potentially with all <i>Type traits</i> known.
+ * @param stream output stream
* @param typedefname the code typedefname (or typename) as a string, should match T
* @param verbose if true, prints all <i>Type traits</i> 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<T>::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<T>::name(), sizeof(T));
if( isTypeTraitBitSet(verbosity, TypeTraitGroup::PRIMARY_TYPE_CAT) ) {
- printf(" Primary Type Categories\n");
- printf(" void %d\n", std::is_void_v<T>);
- printf(" null ptr %d\n", std::is_null_pointer_v<T>);
- printf(" integral %d\n", std::is_integral_v<T>);
- printf(" floating point %d\n", std::is_floating_point_v<T>);
- printf(" array %d\n", std::is_array_v<T>);
- printf(" enum %d\n", std::is_enum_v<T>);
- printf(" union %d\n", std::is_union_v<T>);
- printf(" class %d\n", std::is_class_v<T>);
- printf(" function %d\n", std::is_function_v<T>);
- printf(" pointer %d\n", std::is_pointer_v<T>);
- printf(" lvalue ref %d\n", std::is_lvalue_reference_v<T>);
- printf(" rvalue ref %d\n", std::is_rvalue_reference_v<T>);
- printf(" member obj ptr %d\n", std::is_member_object_pointer_v<T>);
- printf(" member func ptr %d\n", std::is_member_function_pointer_v<T>);
- printf("\n");
+ std::fprintf(stream, " Primary Type Categories\n");
+ std::fprintf(stream, " void %d\n", std::is_void_v<T>);
+ std::fprintf(stream, " null ptr %d\n", std::is_null_pointer_v<T>);
+ std::fprintf(stream, " integral %d\n", std::is_integral_v<T>);
+ std::fprintf(stream, " floating point %d\n", std::is_floating_point_v<T>);
+ std::fprintf(stream, " array %d\n", std::is_array_v<T>);
+ std::fprintf(stream, " enum %d\n", std::is_enum_v<T>);
+ std::fprintf(stream, " union %d\n", std::is_union_v<T>);
+ std::fprintf(stream, " class %d\n", std::is_class_v<T>);
+ std::fprintf(stream, " function %d\n", std::is_function_v<T>);
+ std::fprintf(stream, " pointer %d\n", std::is_pointer_v<T>);
+ std::fprintf(stream, " lvalue ref %d\n", std::is_lvalue_reference_v<T>);
+ std::fprintf(stream, " rvalue ref %d\n", std::is_rvalue_reference_v<T>);
+ std::fprintf(stream, " member obj ptr %d\n", std::is_member_object_pointer_v<T>);
+ std::fprintf(stream, " member func ptr %d\n", std::is_member_function_pointer_v<T>);
+ std::fprintf(stream, "\n");
}
if( isTypeTraitBitSet(verbosity, TypeTraitGroup::TYPE_PROPERTIES) ) {
- printf(" Type Properties\n");
- printf(" const %d\n", std::is_const_v<T>);
- printf(" volatile %d\n", std::is_volatile_v<T>);
- printf(" trivial %d\n", std::is_trivial_v<T>);
- printf(" trivially_copy. %d\n", std::is_trivially_copyable_v<T>);
- printf(" standard_layout %d\n", std::is_standard_layout_v<T>);
- printf(" pod %d\n", std::is_standard_layout_v<T> && std::is_trivial_v<T>); // is_pod<>() is deprecated
- printf(" unique_obj_rep %d\n", std::has_unique_object_representations_v<T>);
- printf(" empty %d\n", std::is_empty_v<T>);
- printf(" polymorphic %d\n", std::is_polymorphic_v<T>);
- printf(" abstract %d\n", std::is_abstract_v<T>);
- printf(" final %d\n", std::is_final_v<T>);
- printf(" aggregate %d\n", std::is_aggregate_v<T>);
- printf(" signed %d\n", std::is_signed_v<T>);
- printf(" unsigned %d\n", std::is_unsigned_v<T>);
+ std::fprintf(stream, " Type Properties\n");
+ std::fprintf(stream, " const %d\n", std::is_const_v<T>);
+ std::fprintf(stream, " volatile %d\n", std::is_volatile_v<T>);
+ std::fprintf(stream, " trivial %d\n", std::is_trivial_v<T>);
+ std::fprintf(stream, " trivially_copy. %d\n", std::is_trivially_copyable_v<T>);
+ std::fprintf(stream, " standard_layout %d\n", std::is_standard_layout_v<T>);
+ std::fprintf(stream, " pod %d\n", std::is_standard_layout_v<T> && std::is_trivial_v<T>); // is_pod<>() is deprecated
+ std::fprintf(stream, " unique_obj_rep %d\n", std::has_unique_object_representations_v<T>);
+ std::fprintf(stream, " empty %d\n", std::is_empty_v<T>);
+ std::fprintf(stream, " polymorphic %d\n", std::is_polymorphic_v<T>);
+ std::fprintf(stream, " abstract %d\n", std::is_abstract_v<T>);
+ std::fprintf(stream, " final %d\n", std::is_final_v<T>);
+ std::fprintf(stream, " aggregate %d\n", std::is_aggregate_v<T>);
+ std::fprintf(stream, " signed %d\n", std::is_signed_v<T>);
+ std::fprintf(stream, " unsigned %d\n", std::is_unsigned_v<T>);
#if __cplusplus > 202002L
// C++ 23
- printf(" bounded_array %d\n", std::is_bounded_array_v<T>);
- printf(" unbounded_array %d\n", std::is_unbounded_array_v<T>);
- printf(" scoped enum %d\n", std::is_scoped_enum_v<T>);
+ std::fprintf(stream, " bounded_array %d\n", std::is_bounded_array_v<T>);
+ std::fprintf(stream, " unbounded_array %d\n", std::is_unbounded_array_v<T>);
+ std::fprintf(stream, " scoped enum %d\n", std::is_scoped_enum_v<T>);
#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<T>);
- printf(" arithmetic %d\n", std::is_arithmetic_v<T>);
- printf(" scalar %d\n", std::is_scalar_v<T>);
- printf(" object %d\n", std::is_object_v<T>);
- printf(" compound %d\n", std::is_compound_v<T>);
- printf(" reference %d\n", std::is_reference_v<T>);
- printf(" member ptr %d\n", std::is_member_pointer_v<T>);
- printf("\n");
+ std::fprintf(stream, " Composite Type Categories\n");
+ std::fprintf(stream, " fundamental %d\n", std::is_fundamental_v<T>);
+ std::fprintf(stream, " arithmetic %d\n", std::is_arithmetic_v<T>);
+ std::fprintf(stream, " scalar %d\n", std::is_scalar_v<T>);
+ std::fprintf(stream, " object %d\n", std::is_object_v<T>);
+ std::fprintf(stream, " compound %d\n", std::is_compound_v<T>);
+ std::fprintf(stream, " reference %d\n", std::is_reference_v<T>);
+ std::fprintf(stream, " member ptr %d\n", std::is_member_pointer_v<T>);
+ 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<T>,
std::is_trivially_constructible_v<T>, std::is_nothrow_constructible_v<T>);
- 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<T>,
std::is_trivially_default_constructible_v<T>, std::is_nothrow_default_constructible_v<T>);
- 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<T>,
std::is_trivially_copy_constructible_v<T>, std::is_nothrow_copy_constructible_v<T>);
- 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<T>,
std::is_trivially_move_constructible_v<T>, std::is_nothrow_move_constructible_v<T>);
- printf(" assignable %d {trivially %d, nothrow %d}\n",
+ std::fprintf(stream, " assignable %d {trivially %d, nothrow %d}\n",
std::is_assignable_v<T, T>,
std::is_trivially_assignable_v<T, T>, std::is_nothrow_assignable_v<T, T>);
- 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<T>,
std::is_trivially_copy_assignable_v<T>, std::is_nothrow_copy_assignable_v<T>);
- 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<T>,
std::is_trivially_move_assignable_v<T>, std::is_nothrow_move_assignable_v<T>);
- 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<T>,
std::is_trivially_destructible_v<T>, std::is_nothrow_destructible_v<T>,
std::has_virtual_destructor_v<T>);
- printf(" swappable %d {nothrow %d}\n",
+ std::fprintf(stream, " swappable %d {nothrow %d}\n",
std::is_swappable_v<T>, std::is_nothrow_swappable_v<T>);
}
}
+ /**
+ * Print information of this type to stdout, potentially with all <i>Type traits</i> known.
+ * @param typedefname the code typedefname (or typename) as a string, should match T
+ * @param verbose if true, prints all <i>Type traits</i> 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<A> { 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)