diff options
Diffstat (limited to 'src/lib/netlist/plib/pfmtlog.h')
-rw-r--r-- | src/lib/netlist/plib/pfmtlog.h | 97 |
1 files changed, 62 insertions, 35 deletions
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 749027bf95e..36dc9587d82 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -12,6 +12,8 @@ #include "putil.h" #include <limits> +#include <locale> +#include <sstream> namespace plib { @@ -28,7 +30,6 @@ struct ptype_traits_base { static const T cast(const T &x) { return x; } static const bool is_signed = std::numeric_limits<T>::is_signed; - static const char *size_spec() { return ""; } static char32_t fmt_spec() { return 'u'; } }; @@ -37,7 +38,6 @@ struct ptype_traits_base<bool> { static unsigned int cast(const bool &x) { return static_cast<unsigned int>(x); } static const bool is_signed = std::numeric_limits<bool>::is_signed; - static const char *size_spec() { return ""; } static char32_t fmt_spec() { return 'u'; } }; @@ -52,14 +52,12 @@ struct ptype_traits<bool> : ptype_traits_base<bool> template<> struct ptype_traits<char> : ptype_traits_base<char> { - static const char *size_spec() { return "h"; } static char32_t fmt_spec() { return is_signed ? 'd' : 'u'; } }; template<> struct ptype_traits<short> : ptype_traits_base<short> { - static const char *size_spec() { return "h"; } static char32_t fmt_spec() { return 'd'; } }; @@ -72,35 +70,30 @@ struct ptype_traits<int> : ptype_traits_base<int> template<> struct ptype_traits<long> : ptype_traits_base<long> { - static const char *size_spec() { return "l"; } static char32_t fmt_spec() { return 'd'; } }; template<> struct ptype_traits<long long> : ptype_traits_base<long long> { - static const char *size_spec() { return "ll"; } static char32_t fmt_spec() { return 'd'; } }; template<> struct ptype_traits<signed char> : ptype_traits_base<signed char> { - static const char *size_spec() { return "h"; } static char32_t fmt_spec() { return 'd'; } }; template<> struct ptype_traits<unsigned char> : ptype_traits_base<unsigned char> { - static const char *size_spec() { return "h"; } static char32_t fmt_spec() { return 'u'; } }; template<> struct ptype_traits<unsigned short> : ptype_traits_base<unsigned short> { - static const char *size_spec() { return "h"; } static char32_t fmt_spec() { return 'u'; } }; @@ -113,14 +106,12 @@ struct ptype_traits<unsigned int> : ptype_traits_base<unsigned int> template<> struct ptype_traits<unsigned long> : ptype_traits_base<unsigned long> { - static const char *size_spec() { return "l"; } static char32_t fmt_spec() { return 'u'; } }; template<> struct ptype_traits<unsigned long long> : ptype_traits_base<unsigned long long> { - static const char *size_spec() { return "ll"; } static char32_t fmt_spec() { return 'u'; } }; @@ -154,41 +145,45 @@ class pfmt { public: explicit pfmt(const pstring &fmt) - : m_str(fmt), m_arg(0) + : m_str(fmt), m_locale(std::locale::classic()), m_arg(0) { } + explicit pfmt(std::locale loc, const pstring &fmt) + : m_str(fmt), m_locale(loc), m_arg(0) + { + } + COPYASSIGNMOVE(pfmt, default) ~pfmt() noexcept = default; operator pstring() const { return m_str; } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - pfmt & e(const double &x) {return format_element("", 'e', x); } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - pfmt & g(const double &x) {return format_element("", 'g', x); } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - pfmt & e(const float &x) {return format_element("", 'e', static_cast<double>(x)); } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - pfmt & g(const float &x) {return format_element("", 'g', static_cast<double>(x)); } + template <typename T> + typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type + f(const T &x) {return format_element('f', x); } + + template <typename T> + typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type + e(const T &x) {return format_element('e', x); } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - pfmt &operator ()(const void *x) {return format_element("", 'p', x); } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - pfmt &operator ()(const pstring &x) {return format_element("", 's', x.c_str() ); } + template <typename T> + typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type + g(const T &x) {return format_element('g', x); } + + pfmt &operator ()(const void *x) {return format_element('p', x); } + pfmt &operator ()(const pstring &x) {return format_element('s', x.c_str() ); } template<typename T> pfmt &operator ()(const T &x) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - return format_element(ptype_traits<T>::size_spec(), ptype_traits<T>::fmt_spec(), ptype_traits<T>::cast(x)); + return format_element(ptype_traits<T>::fmt_spec(), ptype_traits<T>::cast(x)); } template<typename T> pfmt &operator ()(const T *x) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - return format_element(ptype_traits<T *>::size_spec(), ptype_traits<T *>::fmt_spec(), ptype_traits<T *>::cast(x)); + return format_element(ptype_traits<T *>::fmt_spec(), ptype_traits<T *>::cast(x)); } pfmt &operator ()() @@ -204,26 +199,58 @@ public: } template<typename T> - pfmt &x(const T &x) + typename std::enable_if<std::is_integral<T>::value, pfmt &>::type + x(const T &x) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - return format_element(ptype_traits<T>::size_spec(), 'x', x); + return format_element('x', x); } template<typename T> - pfmt &o(const T &x) + typename std::enable_if<std::is_integral<T>::value, pfmt &>::type + o(const T &x) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - return format_element(ptype_traits<T>::size_spec(), 'o', x); + return format_element('o', x); } protected: - pfmt &format_element(const char *l, const unsigned fmt_spec, ...); + struct rtype + { + rtype() : ret(0), p(0), sl(0), pend(0) {} + int ret; + pstring::size_type p; + pstring::size_type sl; + pstring::value_type pend; + + }; + rtype setfmt(std::stringstream &strm, unsigned cfmt_spec); + + template <typename T> + pfmt &format_element(const unsigned cfmt_spec, T &&val) + { + rtype ret; + + m_arg++; + + do { + std::stringstream strm; + strm.imbue(m_locale); + ret = setfmt(strm, cfmt_spec); + if (ret.ret>=0) + { + strm << std::forward<T>(val); + m_str = m_str.substr(0, ret.p) + pstring(strm.str()) + m_str.substr(ret.p + ret.sl); + } + } while (ret.ret == 1); + + return *this; + } + private: pstring m_str; + std::locale m_locale; unsigned m_arg; }; |