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

Go to the source code of this file.

Description

Some implementation helpers for simple object display.

This file provides some basic implementation functions, which can be called from a generic front-end (header). The reason we stash away some functions into an implementation unit is to keep the include overhead low, which helps to reduce both code size and compilation time. The functions here perform some formatting tasks commonly used from debugging and diagnostics code, both to investigate object contents and show types and addresses. They are referred from our [lightweight string converter](util::StringConv), but also from the util::toString() function and more common formatting utils.

See also
FormatHelper_test
FormatString_test

Definition in file format-obj.cpp.

#include "lib/error.hpp"
#include "lib/format-obj.hpp"
#include "lib/ios-savepoint.hpp"
#include "lib/unique-malloc-owner.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include <limits>
#include <iomanip>
#include <sstream>
#include <string>
#include <regex>

Macros

#define TYP_EXP   "[\\w<>\\(\\):,\\s]+"
 

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
 
string sanitisedSymbol (std::string const &)
 condense a string and retain only valid identifiers More...
 
ostream & showAdr (std::ostream &, void const *addr)
 preconfigured format for pretty-printing of addresses More...
 
string showAdr (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
 
template<typename F >
string showFloatingPoint (F val, size_t precision) noexcept
 
string showHash (size_t hash, uint showBytes=8) noexcept
 renders the size_t in hex, optionally only trailing bytes
 
string showSize (size_t val) noexcept
 

Variables

const string BOOL_FALSE_STR = "false"
 
const string BOOL_TRUE_STR = "true"
 
const string BOTTOM_INDICATOR = "⟂"
 
const size_t DIAGNOSTICS_ADDRESS_SUFFIX_LEN = 4
 show only this amount of trailing bytes from an address
 
const auto DIAGNOSTICS_DOUBLE_PRECISION = 8
 
const auto DIAGNOSTICS_FLOAT_PRECISION = 5
 
const string FAILURE_INDICATOR = "↯"
 
const string FUNCTION_INDICATOR = "Function"
 
template<typename F >
constexpr size_t PRECISION_COMPLETE = std::numeric_limits<F>::max_digits10
 decimal digits require tod represent each different floating-point value
 
template<typename F >
constexpr size_t PRECISION_DECIMAL = std::numeric_limits<F>::digits10
 maximum decimal digits able to pass through a round trip without value change
 
const string VOID_INDICATOR = "void"
 

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 159 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 190 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 268 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:

◆ sanitisedSymbol()

std::string sanitisedSymbol ( std::string const &  )

condense a string and retain only valid identifiers

Returns
string starting with letter, followed by letters, digits and underscore

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

References lib::meta::sanitisedSymbol().

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

+ 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 360 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:

◆ showAdr()

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

preconfigured format for pretty-printing of addresses

Note
show only the trailing X bytes of any address
Examples:
/Werk/devel/lumi/src/lib/test/test-helper.hpp.

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

References util::showAdr().

Referenced by util::showAdr().

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