From d3e5cb7f73f069d6ba1d9f13e00bb31aebf03b90 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 17 Mar 2017 21:03:15 -0700 Subject: [PATCH] ircd::fmt: Add the %p format specifier for pointer types. --- ircd/fmt.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ircd/fmt.cc b/ircd/fmt.cc index 7aecf3755..07d4ed462 100644 --- a/ircd/fmt.cc +++ b/ircd/fmt.cc @@ -189,6 +189,17 @@ const char_specifier "c"s }; +struct pointer_specifier +:specifier +{ + bool operator()(char *&out, const size_t &max, const spec &, const arg &val) const override; + using specifier::specifier; +} +const pointer_specifier +{ + "p"s +}; + } // namespace fmt } // namespace ircd @@ -335,6 +346,40 @@ catch(const illegal &e) e.what()); } +bool +fmt::pointer_specifier::operator()(char *&out, + const size_t &max, + const spec &, + const arg &val) +const +{ + using karma::ulong_; + using karma::eps; + using karma::maxwidth; + + static const auto throw_illegal([] + { + throw illegal("Not a pointer"); + }); + + struct generator + :karma::grammar + { + karma::rule pointer_hex + { + lit("0x") << karma::hex + }; + + generator(): generator::base_type{pointer_hex} {} + } + static const generator; + + const auto &ptr(get<0>(val)); + const auto &type(get<1>(val)); + const void *const p(*reinterpret_cast(ptr)); + return karma::generate(out, maxwidth(max)[generator] | eps[throw_illegal], uintptr_t(p)); +} + bool fmt::char_specifier::operator()(char *&out, const size_t &max,