summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pfmtlog.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/pfmtlog.h')
-rw-r--r--src/lib/netlist/plib/pfmtlog.h693
1 files changed, 402 insertions, 291 deletions
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h
index 531b76fafe7..2e45498c637 100644
--- a/src/lib/netlist/plib/pfmtlog.h
+++ b/src/lib/netlist/plib/pfmtlog.h
@@ -1,372 +1,483 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * pfmtlog.h
- */
-#ifndef PFMT_H_
-#define PFMT_H_
+///
+/// \file pfmtlog.h
+///
+#ifndef PFMTLOG_H_
+#define PFMTLOG_H_
+
+#include "penum.h"
+#include "pgsl.h"
+#include "ppmf.h"
#include "pstring.h"
#include "ptypes.h"
-#include "putil.h"
#include <limits>
#include <locale>
#include <sstream>
+#define PERRMSGV(name, argument_count, str) \
+ struct name : public plib::perrmsg \
+ { \
+ template<typename... Args> explicit name(Args&&... args) \
+ : plib::perrmsg(str, std::forward<Args>(args)...) \
+ { static_assert((argument_count) == sizeof...(args), "Argument count mismatch"); } \
+ };
+
namespace plib {
-P_ENUM(plog_level,
- DEBUG,
- VERBOSE,
- INFO,
- WARNING,
- ERROR,
- FATAL)
-
-template <typename T>
-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 char32_t fmt_spec() { return 'u'; }
-};
-
-template <>
-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 char32_t fmt_spec() { return 'u'; }
-};
-
-template <typename T>
-struct ptype_traits;
-
-template<>
-struct ptype_traits<bool> : ptype_traits_base<bool>
-{
-};
-
-template<>
-struct ptype_traits<char> : ptype_traits_base<char>
-{
- static char32_t fmt_spec() { return is_signed ? 'd' : 'u'; }
-};
-
-template<>
-struct ptype_traits<short> : ptype_traits_base<short>
-{
- static char32_t fmt_spec() { return 'd'; }
-};
-
-template<>
-struct ptype_traits<int> : ptype_traits_base<int>
-{
- static char32_t fmt_spec() { return 'd'; }
-};
-
-template<>
-struct ptype_traits<long> : ptype_traits_base<long>
-{
- static char32_t fmt_spec() { return 'd'; }
-};
-
-template<>
-struct ptype_traits<long long> : ptype_traits_base<long long>
-{
- static char32_t fmt_spec() { return 'd'; }
-};
-
-template<>
-struct ptype_traits<signed char> : ptype_traits_base<signed char>
-{
- static char32_t fmt_spec() { return 'd'; }
-};
-
-template<>
-struct ptype_traits<unsigned char> : ptype_traits_base<unsigned char>
-{
- static char32_t fmt_spec() { return 'u'; }
-};
-
-template<>
-struct ptype_traits<unsigned short> : ptype_traits_base<unsigned short>
-{
- static char32_t fmt_spec() { return 'u'; }
-};
-
-template<>
-struct ptype_traits<unsigned int> : ptype_traits_base<unsigned int>
-{
- static char32_t fmt_spec() { return 'u'; }
-};
-
-template<>
-struct ptype_traits<unsigned long> : ptype_traits_base<unsigned long>
-{
- static char32_t fmt_spec() { return 'u'; }
-};
-
-template<>
-struct ptype_traits<unsigned long long> : ptype_traits_base<unsigned long long>
-{
- static char32_t fmt_spec() { return 'u'; }
-};
-
-template<>
-struct ptype_traits<float> : ptype_traits_base<float>
-{
- static char32_t fmt_spec() { return 'f'; }
-};
-
-template<>
-struct ptype_traits<double> : ptype_traits_base<double>
-{
- static char32_t fmt_spec() { return 'f'; }
-};
-
-template<>
-struct ptype_traits<char *> : ptype_traits_base<char *>
-{
- static const char *cast(const char *x) { return x; }
- static char32_t fmt_spec() { return 's'; }
-};
-
-template<>
-struct ptype_traits<std::string> : ptype_traits_base<char *>
-{
- static const char *cast(const std::string &x) { return x.c_str(); }
- static char32_t fmt_spec() { return 's'; }
-};
-
-class pfmt
-{
-public:
- explicit pfmt(const pstring &fmt)
- : m_str(fmt), m_locale(std::locale::classic()), m_arg(0)
- {
- }
- explicit pfmt(const 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; }
+ PENUM(plog_level,
+ DEBUG,
+ VERBOSE,
+ INFO,
+ WARNING,
+ ERROR,
+ FATAL)
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type
- f(const T &x) {return format_element('f', x); }
+ struct format_traits_base
+ {
+ static constexpr const bool is_signed = std::numeric_limits<T>::is_signed;
+ static char32_t fmt_spec() { return 'u'; }
+ static void streamify(std::ostream &s, const T &v)
+ {
+ s << v;
+ }
+ };
- template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, pfmt &>::type
- e(const T &x) {return format_element('e', x); }
+ #if (PUSE_FLOAT128)
+ template <>
+ struct format_traits_base<FLOAT128>
+ {
+ // FIXME: need native support at some time
+ static constexpr const bool is_signed = true;
+ static char32_t fmt_spec() { return 'f'; }
+ static void streamify(std::ostream &s, const FLOAT128 &v)
+ {
+ s << narrow_cast<long double>(v);
+ }
+ };
+ #endif
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() ); }
+ struct format_traits;
- template<typename T>
- pfmt &operator ()(const T &x)
+ template<>
+ struct format_traits<compile_info::int128_type>
{
- return format_element(ptype_traits<T>::fmt_spec(), ptype_traits<T>::cast(x));
- }
+ // FIXME: need native support at some time
+ static constexpr const bool is_signed = true;
+ static char32_t fmt_spec() { return 'd'; }
+ template <typename T, typename = std::enable_if_t<plib::is_arithmetic<T>::value>>
+ static void streamify(std::ostream &s, const T &v)
+ {
+ s << narrow_cast<long long>(v);
+ }
+ };
- template<typename T>
- pfmt &operator ()(const T *x)
+ template<>
+ struct format_traits<bool> : format_traits_base<bool>
{
- return format_element(ptype_traits<T *>::fmt_spec(), ptype_traits<T *>::cast(x));
- }
+ };
- pfmt &operator ()()
+ template<>
+ struct format_traits<char> : format_traits_base<char>
{
- return *this;
- }
+ static char32_t fmt_spec() { return is_signed ? 'd' : 'u'; }
+ };
+ template<>
+ struct format_traits<short> : format_traits_base<short>
+ {
+ static char32_t fmt_spec() { return 'd'; }
+ };
- template<typename X, typename Y, typename... Args>
- pfmt &operator()(X&& x, Y && y, Args&&... args)
+ template<>
+ struct format_traits<int> : format_traits_base<int>
{
- return ((*this)(std::forward<X>(x)))(std::forward<Y>(y), std::forward<Args>(args)...);
- }
+ static char32_t fmt_spec() { return 'd'; }
+ };
- template<typename T>
- typename std::enable_if<std::is_integral<T>::value, pfmt &>::type
- x(const T &x)
+ template<>
+ struct format_traits<long> : format_traits_base<long>
{
- return format_element('x', x);
- }
+ static char32_t fmt_spec() { return 'd'; }
+ };
- template<typename T>
- typename std::enable_if<std::is_integral<T>::value, pfmt &>::type
- o(const T &x)
+ template<>
+ struct format_traits<long long> : format_traits_base<long long>
{
- return format_element('o', x);
- }
+ static char32_t fmt_spec() { return 'd'; }
+ };
- friend std::ostream& operator<<(std::ostream &ostrm, const pfmt &fmt)
+ template<>
+ struct format_traits<signed char> : format_traits_base<signed char>
{
- ostrm << fmt.m_str;
- return ostrm;
- }
+ static char32_t fmt_spec() { return 'd'; }
+ };
-protected:
+ template<>
+ struct format_traits<unsigned char> : format_traits_base<unsigned char>
+ {
+ static char32_t fmt_spec() { return 'u'; }
+ };
- struct rtype
+ template<>
+ struct format_traits<unsigned short> : format_traits_base<unsigned short>
{
- rtype() : ret(0), p(0), sl(0), pend(0), width(0) {}
- int ret;
- pstring::size_type p;
- pstring::size_type sl;
- char32_t pend;
- pstring::size_type width;
+ static char32_t fmt_spec() { return 'u'; }
+ };
+ template<>
+ struct format_traits<unsigned int> : format_traits_base<unsigned int>
+ {
+ static char32_t fmt_spec() { return 'u'; }
};
- rtype setfmt(std::stringstream &strm, char32_t cfmt_spec);
- template <typename T>
- pfmt &format_element(const char32_t cfmt_spec, T &&val)
+ template<>
+ struct format_traits<unsigned long> : format_traits_base<unsigned long>
{
- rtype ret;
+ static char32_t fmt_spec() { return 'u'; }
+ };
- m_arg++;
+ template<>
+ struct format_traits<unsigned long long> : format_traits_base<unsigned long long>
+ {
+ static char32_t fmt_spec() { return 'u'; }
+ };
- do {
- std::stringstream strm;
- strm.imbue(m_locale);
- ret = setfmt(strm, cfmt_spec);
- if (ret.ret>=0)
- {
- strm << std::forward<T>(val);
- const pstring ps(strm.str());
- pstring pad("");
- if (ret.width > ps.length())
- pad = pstring(ret.width - ps.length(), ' ');
+ template<>
+ struct format_traits<float> : format_traits_base<float>
+ {
+ static char32_t fmt_spec() { return 'f'; }
+ };
- m_str = m_str.substr(0, ret.p) + pad + ps + m_str.substr(ret.p + ret.sl);
- }
- } while (ret.ret == 1);
+ template<>
+ struct format_traits<double> : format_traits_base<double>
+ {
+ static char32_t fmt_spec() { return 'f'; }
+ };
- return *this;
- }
+ template<>
+ struct format_traits<long double> : format_traits_base<long double>
+ {
+ static char32_t fmt_spec() { return 'f'; }
+ };
+ #if (PUSE_FLOAT128)
+ template<>
+ struct format_traits<FLOAT128> : format_traits_base<FLOAT128>
+ {
+ static char32_t fmt_spec() { return 'f'; }
+ };
+ #endif
-private:
- pstring m_str;
- std::locale m_locale;
- unsigned m_arg;
-};
+ template<>
+ struct format_traits<char *> : format_traits_base<char *>
+ {
+ static char32_t fmt_spec() { return 's'; }
+ };
-template <class T, bool build_enabled = true>
-class pfmt_writer_t
-{
-public:
- explicit pfmt_writer_t() : m_enabled(true) { }
+ template<>
+ struct format_traits<const char *> : format_traits_base<const char *>
+ {
+ static char32_t fmt_spec() { return 's'; }
+ };
- COPYASSIGNMOVE(pfmt_writer_t, delete)
+ template<>
+ struct format_traits<const char16_t *> : format_traits_base<const char16_t *>
+ {
+ static char32_t fmt_spec() { return 's'; }
+ static void streamify(std::ostream &s, const char16_t *v)
+ {
+ const putf16string su16(v);
+ s << putf8string(su16).c_str();
+ }
+ };
- /* runtime enable */
- template<bool enabled, typename... Args>
- void log(const pstring & fmt, Args&&... args) const
+ template<>
+ struct format_traits<const char32_t *> : format_traits_base<const char32_t *>
{
- if (build_enabled && enabled && m_enabled)
+ static char32_t fmt_spec() { return 's'; }
+ static void streamify(std::ostream &s, const char32_t *v)
{
- pfmt pf(fmt);
- static_cast<T *>(this)->vdowrite(xlog(pf, std::forward<Args>(args)...));
+ const putf32string su32(v);
+ s << putf8string(su32).c_str();
}
- }
+ };
+
+ template<>
+ struct format_traits<std::string> : format_traits_base<std::string>
+ {
+ static char32_t fmt_spec() { return 's'; }
+ };
+
+ template<>
+ struct format_traits<putf8string> : format_traits_base<putf8string>
+ {
+ static char32_t fmt_spec() { return 's'; }
+ };
- template<typename... Args>
- void operator ()(const pstring &fmt, Args&&... args) const
+ template<>
+ struct format_traits<putf16string> : format_traits_base<putf16string>
{
- if (build_enabled && m_enabled)
+ static char32_t fmt_spec() { return 's'; }
+ static void streamify(std::ostream &s, const putf16string &v)
{
- pfmt pf(fmt);
- static_cast<const T *>(this)->vdowrite(xlog(pf, std::forward<Args>(args)...));
+ s << putf8string(v).c_str();
}
- }
+ };
+
+ template<>
+ struct format_traits<const void *> : format_traits_base<const void *>
+ {
+ static char32_t fmt_spec() { return 'p'; }
+ };
- void set_enabled(const bool v)
+ class pfmt
{
- m_enabled = v;
- }
+ public:
+ explicit pfmt(const pstring &fmt)
+ : m_str(fmt), m_locale(std::locale::classic()), m_arg(0)
+ {
+ }
+ explicit pfmt(const std::locale &loc, const pstring &fmt)
+ : m_str(fmt), m_locale(loc), m_arg(0)
+ {
+ }
- bool is_enabled() const { return m_enabled; }
+ PCOPYASSIGNMOVE(pfmt, default)
-protected:
- ~pfmt_writer_t() noexcept = default;
+ ~pfmt() noexcept = default;
-private:
- pfmt &xlog(pfmt &fmt) const { return fmt; }
+ operator pstring() const { return m_str; }
- template<typename X, typename... Args>
- pfmt &xlog(pfmt &fmt, X&& x, Args&&... args) const
+ template <typename T>
+ std::enable_if_t<plib::is_floating_point<T>::value, pfmt &>
+ f(const T &x) {return format_element('f', x); }
+
+ template <typename T>
+ std::enable_if_t<plib::is_floating_point<T>::value, pfmt &>
+ e(const T &x) {return format_element('e', x); }
+
+ template <typename T>
+ std::enable_if_t<plib::is_floating_point<T>::value, pfmt &>
+ 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)
+ {
+ return format_element(x);
+ }
+
+ template<typename T>
+ pfmt &operator ()(const T *x)
+ {
+ return format_element(x);
+ }
+
+ pfmt &operator ()()
+ {
+ return *this;
+ }
+
+ template<typename X, typename Y, typename... Args>
+ pfmt &operator()(X&& x, Y && y, Args&&... args)
+ {
+ return ((*this)(std::forward<X>(x)))(std::forward<Y>(y), std::forward<Args>(args)...);
+ }
+
+ template<typename T>
+ std::enable_if_t<plib::is_integral<T>::value, pfmt &>
+ x(const T &x)
+ {
+ return format_element('x', x);
+ }
+
+ template<typename T>
+ std::enable_if_t<plib::is_integral<T>::value, pfmt &>
+ o(const T &x)
+ {
+ return format_element('o', x);
+ }
+
+ friend std::ostream& operator<<(std::ostream &out_stream, const pfmt &fmt)
+ {
+ out_stream << putf8string(fmt.m_str);
+ return out_stream;
+ }
+
+ protected:
+
+ struct rtype
+ {
+ rtype() : ret(0), p(0), sl(0) {}
+ int ret;
+ pstring::size_type p;
+ pstring::size_type sl;
+ };
+ rtype set_format(std::stringstream &strm, char32_t char_format);
+
+ template <typename T>
+ pfmt &format_element(T &&v)
+ {
+ return format_element(format_traits<typename std::decay<T>::type>::fmt_spec(), std::forward<T>(v));
+ }
+
+ template <typename T>
+ pfmt &format_element(const char32_t char_format, T &&v)
+ {
+ rtype ret;
+
+ m_arg++;
+
+ do {
+ std::stringstream strm;
+ strm.imbue(m_locale);
+ ret = set_format(strm, char_format);
+ if (ret.ret>=0)
+ {
+ format_traits<typename std::decay<T>::type>::streamify(strm, std::forward<T>(v));
+ const pstring ps(putf8string(strm.str()));
+ m_str = m_str.substr(0, ret.p) + ps + m_str.substr(ret.p + ret.sl);
+ }
+ } while (ret.ret == 1);
+
+ return *this;
+ }
+
+
+ private:
+
+ pstring m_str;
+ std::locale m_locale;
+ unsigned m_arg;
+ };
+
+ template <class T, bool build_enabled = true>
+ class pfmt_writer_t
{
- return xlog(fmt(std::forward<X>(x)), std::forward<Args>(args)...);
- }
+ public:
+ explicit pfmt_writer_t() : m_enabled(true) { }
+
+ PCOPYASSIGNMOVE(pfmt_writer_t, delete)
+
+ // runtime enable
+ template<bool enabled, typename... Args>
+ void log(const pstring & fmt, Args&&... args) const noexcept
+ {
+ if (build_enabled && enabled && m_enabled)
+ {
+ pfmt pf(fmt);
+ plib::dynamic_downcast<T &>(*this).upstream_write(log_translate(pf, std::forward<Args>(args)...));
+ }
+ }
+
+ template<typename... Args>
+ void operator ()(const pstring &fmt, Args&&... args) const noexcept
+ {
+ if (build_enabled && m_enabled)
+ {
+ pfmt pf(fmt);
+ static_cast<const T &>(*this).upstream_write(log_translate(pf, std::forward<Args>(args)...));
+ }
+ }
+
+ void set_enabled(const bool v)
+ {
+ m_enabled = v;
+ }
+
+ bool is_enabled() const { return m_enabled; }
+
+ protected:
+ ~pfmt_writer_t() noexcept = default;
- bool m_enabled;
+ private:
+ pfmt &log_translate(pfmt &fmt) const { return fmt; }
-};
+ template<typename X, typename... Args>
+ pfmt &log_translate(pfmt &fmt, X&& x, Args&&... args) const
+ {
+ return log_translate(fmt(std::forward<X>(x)), std::forward<Args>(args)...);
+ }
-template <class T, plog_level::E L, bool build_enabled = true>
-class plog_channel : public pfmt_writer_t<plog_channel<T, L, build_enabled>, build_enabled>
-{
- friend class pfmt_writer_t<plog_channel<T, L, build_enabled>, build_enabled>;
-public:
- explicit plog_channel(T &b) : pfmt_writer_t<plog_channel, build_enabled>(), m_base(b) { }
+ bool m_enabled;
- COPYASSIGNMOVE(plog_channel, delete)
+ };
- ~plog_channel() noexcept = default;
+ using plog_delegate = plib::pmfp<void (plog_level, const pstring &)>;
-protected:
- void vdowrite(const pstring &ls) const
+ template <plog_level::E L, bool build_enabled = true>
+ class plog_channel : public pfmt_writer_t<plog_channel<L, build_enabled>, build_enabled>
{
- m_base.vlog(L, ls);
- }
+ friend class pfmt_writer_t<plog_channel<L, build_enabled>, build_enabled>;
+ public:
+ explicit plog_channel(plog_delegate logger)
+ : pfmt_writer_t<plog_channel, build_enabled>()
+ , m_logger(logger) { }
+
+ PCOPYASSIGNMOVE(plog_channel, delete)
-private:
- T &m_base;
-};
+ ~plog_channel() noexcept = default;
-template<class T, bool debug_enabled>
-class plog_base
-{
-public:
+ protected:
+ void upstream_write(const pstring &ls) const noexcept
+ {
+ m_logger(L, ls);
+ }
+
+ private:
+ plog_delegate m_logger;
+ };
- explicit plog_base(T &proxy)
- : debug(proxy),
- info(proxy),
- verbose(proxy),
- warning(proxy),
- error(proxy),
- fatal(proxy)
- {}
+ template<bool debug_enabled>
+ class plog_base
+ {
+ public:
+
+ explicit plog_base(plog_delegate logger)
+ : debug(logger),
+ info(logger),
+ verbose(logger),
+ warning(logger),
+ error(logger),
+ fatal(logger)
+ {}
+
+ PCOPYASSIGNMOVE(plog_base, delete)
+ virtual ~plog_base() noexcept = default;
+
+ plog_channel<plog_level::DEBUG, debug_enabled> debug;
+ plog_channel<plog_level::INFO> info;
+ plog_channel<plog_level::VERBOSE> verbose;
+ plog_channel<plog_level::WARNING> warning;
+ plog_channel<plog_level::ERROR> error;
+ plog_channel<plog_level::FATAL> fatal;
+ };
- COPYASSIGNMOVE(plog_base, default)
- virtual ~plog_base() noexcept = default;
+ struct perrmsg
+ {
+ template<std::size_t N, typename... Args>
+ explicit perrmsg(const char (&fmt)[N], Args&&... args) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ : m_msg(plib::pfmt(fmt)(std::forward<Args>(args)...))
+ { }
+ operator pstring const & () const noexcept { return m_msg; }
+ const pstring & operator ()() const noexcept { return m_msg; }
+ private:
+ pstring m_msg;
+ };
- plog_channel<T, plog_level::DEBUG, debug_enabled> debug;
- plog_channel<T, plog_level::INFO> info;
- plog_channel<T, plog_level::VERBOSE> verbose;
- plog_channel<T, plog_level::WARNING> warning;
- plog_channel<T, plog_level::ERROR> error;
- plog_channel<T, plog_level::FATAL> fatal;
-};
} // namespace plib
template<typename T>
plib::pfmt& operator<<(plib::pfmt &p, T&& val) { return p(std::forward<T>(val)); }
-#endif /* PSTRING_H_ */
+#endif // PFMT_LOG_H_