Lumiera  0.pre.03
»edit your freedom«
format-obj.hpp File Reference

Go to the source code of this file.

Description

Simple functions to represent objects, for debugging and diagnostics.

The helpers provided here are rather commonplace, but written in a way as to incur only modest header inclusion load. It should be OK to use these even on widely used interface headers.

  • util::toString() performs a failsafe to-String conversion, thereby preferring a built-in conversion operator, falling back to a lexical conversion (boost) or just a unmangled and simplified type string as default.
  • util::typedString() combines this with a always visible type display
  • lib::meta::demangleCxx() uses the built-in compiler support to translate a mangled type-ID (as given by typeid(TY).name()) into a readable, fully qualified C++ type name. This is only supported for GNU compatible compilers.
Todo:
is it possible to stash away the boost::lexical_cast behind a custom facade, the way we did it for boost::format? This would reduce inclusion cost...
See also
FormatHelper_test
frontend for boost::format, printf-style

Definition in file format-obj.hpp.

#include "lib/symbol.hpp"
#include "lib/meta/trait.hpp"
#include <boost/lexical_cast.hpp>

Classes

class  basic_ostream< Char >
 STL class.
 
class  char_traits< C >
 
struct  StringConv< bool >
 
struct  StringConv< double >
 explicit specialisation to control precision of double values. More...
 
struct  StringConv< float >
 
struct  StringConv< SP, show_SmartPointer< SP > >
 
struct  StringConv< X, enable_LexicalConversion< X > >
 

Typedefs

template<typename X >
using enable_LexicalConversion = lib::meta::enable_if< lib::meta::use_LexicalConversion< X > >
 toggle to prefer specialisation with direct lexical conversion
 
using ostream = basic_ostream< char, char_traits< char > >
 
template<typename SP >
using show_SmartPointer = lib::meta::enable_if< lib::meta::is_smart_ptr< typename lib::meta::Strip< SP >::TypeReferred > >
 

Functions

string demangleCxx (Literal rawName)
 Fallback type-ID: More...
 
string humanReadableTypeID (lib::Literal)
 pretty-print an internal C++ type representation More...
 
string primaryTypeComponent (lib::Literal)
 extract core name component from a raw type spec More...
 
string sanitisedFullTypeName (lib::Literal)
 build a sanitised ID from full type name
 
ostream & showAddr (std::ostream &, void const *addr)
 preconfigured format for pretty-printing of addresses More...
 
string showAddr (void const *addr) noexcept
 pretty-print an address as hex-suffix
 
string showComplete (double) noexcept
 show enough decimal digits to represent every distinct value
 
string showComplete (float val) noexcept
 
string showComplete (f128 val) noexcept
 
string showDecimal (double) noexcept
 show maximum reproducible decimal representation
 
string showDecimal (float val) noexcept
 
string showDecimal (f128 val) noexcept
 
string showDouble (double) noexcept
 pretty-print a double in (rounded) fixed-point format More...
 
string showFloat (float val) noexcept
 
string showHash (size_t hash, uint showBytes=8) noexcept
 renders the size_t in hex, optionally only trailing bytes
 
std::string showHashLSB (size_t hash) noexcept
 
string showSize (size_t val) noexcept
 
template<typename TY >
std::string toString (TY const &val) noexcept
 get some string representation of any object, reliably. More...
 
template<typename TY >
std::string typedString (TY const &val) noexcept
 indicate type and possibly a (custom) conversion to string More...
 

Namespaces

 lib
 Implementation namespace for support and library code.
 

Function Documentation

◆ demangleCxx()

std::string demangleCxx ( Literal  rawName)

Fallback type-ID:

reverse the effect of C++ name mangling.

Returns
unaltered internal type-ID
string in language-level form of a C++ type or object name, or a string with the original input if demangling fails.
Warning
implementation relies on the cross vendor C++ ABI in use by GCC and compatible compilers, so portability is limited. The implementation is accessed through libStdC++ Name representation in emitted object code and type IDs is essentially an implementation detail and subject to change.
Examples:
/Werk/devel/lumi/src/lib/test/test-helper.hpp.

Definition at line 168 of file format-obj.cpp.

References lib::meta::demangleCxx().

Referenced by lib::meta::demangleCxx(), lib::meta::humanReadableTypeID(), and lib::meta::primaryTypeComponent().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ humanReadableTypeID()

std::string humanReadableTypeID ( Literal  rawType)

pretty-print an internal C++ type representation

implementation notes
  • we do not strip type adornments like const, & or *, however, the typical usage from within util::typeStr() is arranged in a way to absorb these adornments by the way the template signatures are defined
  • we do simplify the type display and strip some obnoxious namespace prefixes with the help of std::regex_replace
  • we perform those simplifying rewrites in place thus overwriting the result string. This exploits the fact that the replacements are always shorter than what is being replaced (beware).
  • standard regular expressions can be assumed to be threadsafe. Thus, we're able to build an embedded shared static variable on demand and use the performance optimisation offered by the standard library
  • performance wise we'll assume the transformation happens within the cache, so it doesn't make much of a difference if we scan the same comparatively short string multiple times
See also
format-obj.cpp implementation
Examples:
/Werk/devel/lumi/src/lib/test/test-helper.hpp.

Definition at line 199 of file format-obj.cpp.

References lib::meta::demangleCxx(), and lib::meta::humanReadableTypeID().

Referenced by lib::meta::humanReadableTypeID(), and lib::meta::sanitisedFullTypeName().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ primaryTypeComponent()

std::string primaryTypeComponent ( Literal  rawType)

extract core name component from a raw type spec

implementation notes
We want to get at the name of the most relevant type entity. This in itself is a heuristic. But we can work on the assumption, that we get a sequence of nested namespaces and type names, and we'll be interested in the last, the innermost of these types. In the most general case, each type could be templated, and thus will be followed by parameter specs enclosed in angle braces. Behind this spec, only type adornments will follow. Thus we'll inspect the string from the back side, skipping over all type parameter contents, until we reach brace level zero again. From this point, we have to search backwards to the first namespace separator ::
Warning
we acknowledge this function can fail in various ways, some of which will be indicated by returning the string "void". But it may well happen that the returned string contains whitespace, superfluous punctuation or even the whole demangled type specification as is.
Returns
simple identifier possibly "the" type
Warning
implemented lexically, not necessarily correct!

Definition at line 270 of file format-obj.cpp.

References lib::meta::demangleCxx(), lib::meta::primaryTypeComponent(), and lib::meta::typeStr().

Referenced by lib::meta::primaryTypeComponent().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ showDouble()

std::string showDouble ( double  val)
noexcept

pretty-print a double in (rounded) fixed-point format

Returns
fixed point string representation, never empty
Note
we set an explicit precision, since this is a diagnostic facility
Remarks
typically do not want to see all digits, but, for test code, we do want a predictable string representation of simple fractional values like 0.1 (which can not be represented as binary floats)

Definition at line 362 of file format-obj.cpp.

References util::showDouble().

Referenced by util::showDouble().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ showAddr()

std::ostream & showAddr ( ostream &  stream,
void const *  addr 
)

preconfigured format for pretty-printing of addresses

Note
show only the trailing X bytes of any address

Definition at line 387 of file format-obj.cpp.

References util::showAddr().

Referenced by util::showAddr().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toString()

std::string toString ( TY const &  val)
inlinenoexcept

get some string representation of any object, reliably.

A custom string conversion operator is invoked, if applicable, while all lexically convertible types (numbers etc) are treated by boost::lexical_cast. For double or float values, hard wired rounding to a fixed number of digits will be performed, to yield a predictable display of printed unit-test results.

Remarks
while the actual parameter is passed by const-ref, cv-qualifiactions and references are stripped from the type
Note
Deliberately there is no magic detection/support for pointers. This function must not be overloaded (to avoid ambiguities in more elaborate template instantiations).
Remarks
Since 10/2023 an attempt was made to solve this problem down in StringConf<TY>, yet this solution might be brittle. If you want pointers to be indicated (with address), consider using util::showPtr explicitly.

Definition at line 200 of file format-obj.hpp.

References util::toString().

Referenced by FormatHelper_test::check2String(), and util::toString().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ typedString()

std::string util::typedString ( TY const &  val)
inlinenoexcept

indicate type and possibly a (custom) conversion to string

Returns
human readable type name '|' string representation. or just the type, when no string representation available

Definition at line 214 of file format-obj.hpp.

References util::typedString().

Referenced by util::typedString().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: