diff --git a/src/lib/format-obj.cpp b/src/lib/format-obj.cpp index 8fd4ca1f2..d9e9f5885 100644 --- a/src/lib/format-obj.cpp +++ b/src/lib/format-obj.cpp @@ -42,6 +42,7 @@ #include "lib/error.hpp" #include "lib/format-obj.hpp" +//#include "lib/format-string.hpp" #include "lib/unique-malloc-owner.hpp" #include "lib/symbol.hpp" @@ -49,11 +50,26 @@ #include #endif +#include +#include #include - +//using util::_Fmt; using std::string; + +namespace { // hard-wired configuration for debugging output.... + + // precision for rendering of double values + const auto DIAGNOSTICS_DOUBLE_PRECISION = 8; + const auto DIAGNOSTICS_FLOAT_PRECISION = 5; + + /** amount of hex digits required to represent an address on this plattform */ + const auto PLATFORM_ADDRESS_HEX_DIGITS = sizeof(size_t) * 2; +} + + + namespace lib { namespace meta { @@ -132,7 +148,12 @@ apologies for that." return typeName; } -}} +}}// namespace lib::meta + + + + +/* === formatting and pretty printing support uitls === */ namespace util { @@ -141,11 +162,59 @@ namespace util { }//(End) implementation details - + using std::ostringstream; + using std::hex; + using std::setw; + using std::right; + using std::setfill; + using std::noshowbase; /** + * @return 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) */ + string + showDouble (double val) noexcept + try { + ostringstream buffer; + buffer.precision (DIAGNOSTICS_DOUBLE_PRECISION); + buffer << val; + return buffer.str(); + } + catch(...) + { return "↯"; } + + + string + showFloat (float val) noexcept + try { + std::ostringstream buffer; + buffer.precision (DIAGNOSTICS_FLOAT_PRECISION); + buffer << val; + return buffer.str(); + } + catch(...) + { return "↯"; } + + + string + showAddr (void *addr) noexcept + try { + std::ostringstream buffer; + buffer << hex + << noshowbase + << setw (PLATFORM_ADDRESS_HEX_DIGITS) + << setfill('_') + << right + << addr; + return buffer.str(); + } + catch(...) + { return "↯"; } diff --git a/src/lib/format-obj.hpp b/src/lib/format-obj.hpp index 6bb0d5edc..7d018b396 100644 --- a/src/lib/format-obj.hpp +++ b/src/lib/format-obj.hpp @@ -68,11 +68,15 @@ namespace meta { std::string humanReadableTypeID (lib::Literal); -}} // namespace lib::meta +}}// namespace lib::meta namespace util { + std::string showDouble (double) noexcept; + std::string showFloat (float) noexcept; + std::string showAddr (void *addr) noexcept; + } // namespace util diff --git a/src/lib/meta/util.hpp b/src/lib/meta/util.hpp index b519cff39..9f713aa30 100644 --- a/src/lib/meta/util.hpp +++ b/src/lib/meta/util.hpp @@ -204,16 +204,18 @@ namespace meta { */ template inline std::string - typeStr (const TY* obj=nullptr) - { - auto mangledType = obj? typeid(obj).name() - : typeid(TY).name(); - return humanReadableTypeID (mangledType); - } + typeStr (const TY* obj =nullptr) noexcept + try { + auto mangledType = obj? typeid(obj).name() + : typeid(TY).name(); + return humanReadableTypeID (mangledType); + } + catch(...) + { return "↯"; } template inline std::string - typeStr (TY const& ref) + typeStr (TY const& ref) noexcept { return typeStr (&ref); } @@ -234,20 +236,55 @@ namespace meta { template struct CustomStringConv { - static std::string invoke (X const& x) { return "«"+typeStr(x)+"»"; } + static std::string + invoke (X const& x) noexcept + try { return "«"+typeStr(x)+"»"; } + catch(...) { return "↯"; } }; template struct CustomStringConv> > { static std::string - invoke (X const& val) + invoke (X const& val) noexcept try { return std::string(val); } catch(...) { return "↯"; } }; + + // NOTE: this is meant to be extensible; + // more specialisations are e.g. in format-obj.hpp + +}}// namespace lib::meta + + +namespace util { + + /** pretty-print a double in fixed-point format */ + std::string showDouble (double) noexcept; + std::string showFloat (float) noexcept; + + /** pretty-print an address as hex-string */ + std::string showAddr (void *addr) noexcept; + + template + inline std::string + showAddr (const X& elm) noexcept + { + return showAddr(&elm); + } + + + /** diagnostics helper for explicitly indicating pointers */ + template + inline std::string + showPtr (X* ptr =nullptr) + { + return ptr? showAddr(ptr) + " ↗" + lib::meta::CustomStringConv::invoke(*ptr) + : "⟂ «" + typeStr(ptr) + "»"; + } -}} // namespace lib::meta -#endif +}// namespace util +#endif /*LIB_META_UTIL_H*/