|
|
|
@ -156,8 +156,7 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
// Format the value by casting to type fmtT. This default implementation
|
|
|
|
// Format the value by casting to type fmtT. This default implementation
|
|
|
|
// should never be called.
|
|
|
|
// should never be called.
|
|
|
|
template <typename T,
|
|
|
|
template <typename T, typename fmtT,
|
|
|
|
typename fmtT,
|
|
|
|
|
|
|
|
bool convertible = is_convertible<T, fmtT>::value>
|
|
|
|
bool convertible = is_convertible<T, fmtT>::value>
|
|
|
|
struct formatValueAsType {
|
|
|
|
struct formatValueAsType {
|
|
|
|
static void invoke(std::ostream & /*out*/, const T & /*value*/) { assert(0); }
|
|
|
|
static void invoke(std::ostream & /*out*/, const T & /*value*/) { assert(0); }
|
|
|
|
@ -227,11 +226,8 @@ TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(char)
|
|
|
|
/// operator<< to format the type T, with special cases for the %c and %p
|
|
|
|
/// operator<< to format the type T, with special cases for the %c and %p
|
|
|
|
/// conversions.
|
|
|
|
/// conversions.
|
|
|
|
template <typename T>
|
|
|
|
template <typename T>
|
|
|
|
inline void formatValue(std::ostream &out,
|
|
|
|
inline void formatValue(std::ostream &out, const char * /*fmtBegin*/,
|
|
|
|
const char * /*fmtBegin*/,
|
|
|
|
const char *fmtEnd, int ntrunc, const T &value) {
|
|
|
|
const char *fmtEnd,
|
|
|
|
|
|
|
|
int ntrunc,
|
|
|
|
|
|
|
|
const T &value) {
|
|
|
|
|
|
|
|
// The mess here is to support the %c and %p conversions: if these
|
|
|
|
// The mess here is to support the %c and %p conversions: if these
|
|
|
|
// conversions are active we try to convert the type to a char or const
|
|
|
|
// conversions are active we try to convert the type to a char or const
|
|
|
|
// void* respectively and format that instead of the value itself. For the
|
|
|
|
// void* respectively and format that instead of the value itself. For the
|
|
|
|
@ -254,11 +250,8 @@ inline void formatValue(std::ostream &out,
|
|
|
|
|
|
|
|
|
|
|
|
// Overloaded version for char types to support printing as an integer
|
|
|
|
// Overloaded version for char types to support printing as an integer
|
|
|
|
#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \
|
|
|
|
#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \
|
|
|
|
inline void formatValue(std::ostream &out, \
|
|
|
|
inline void formatValue(std::ostream &out, const char * /*fmtBegin*/, \
|
|
|
|
const char * /*fmtBegin*/, \
|
|
|
|
const char *fmtEnd, int /**/, charType value) { \
|
|
|
|
const char *fmtEnd, \
|
|
|
|
|
|
|
|
int /**/, \
|
|
|
|
|
|
|
|
charType value) { \
|
|
|
|
|
|
|
|
switch (*(fmtEnd - 1)) { \
|
|
|
|
switch (*(fmtEnd - 1)) { \
|
|
|
|
case 'u': \
|
|
|
|
case 'u': \
|
|
|
|
case 'd': \
|
|
|
|
case 'd': \
|
|
|
|
@ -477,9 +470,7 @@ public:
|
|
|
|
m_formatImpl(&formatImpl<T>),
|
|
|
|
m_formatImpl(&formatImpl<T>),
|
|
|
|
m_toIntImpl(&toIntImpl<T>) {}
|
|
|
|
m_toIntImpl(&toIntImpl<T>) {}
|
|
|
|
|
|
|
|
|
|
|
|
void format(std::ostream &out,
|
|
|
|
void format(std::ostream &out, const char *fmtBegin, const char *fmtEnd,
|
|
|
|
const char *fmtBegin,
|
|
|
|
|
|
|
|
const char *fmtEnd,
|
|
|
|
|
|
|
|
int ntrunc) const {
|
|
|
|
int ntrunc) const {
|
|
|
|
m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value);
|
|
|
|
m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -488,11 +479,8 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
template <typename T>
|
|
|
|
template <typename T>
|
|
|
|
static void formatImpl(std::ostream &out,
|
|
|
|
static void formatImpl(std::ostream &out, const char *fmtBegin,
|
|
|
|
const char *fmtBegin,
|
|
|
|
const char *fmtEnd, int ntrunc, const void *value) {
|
|
|
|
const char *fmtEnd,
|
|
|
|
|
|
|
|
int ntrunc,
|
|
|
|
|
|
|
|
const void *value) {
|
|
|
|
|
|
|
|
formatValue(out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T *>(value));
|
|
|
|
formatValue(out, fmtBegin, fmtEnd, ntrunc, *static_cast<const T *>(value));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -502,11 +490,8 @@ private:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const void *m_value;
|
|
|
|
const void *m_value;
|
|
|
|
void (*m_formatImpl)(std::ostream &out,
|
|
|
|
void (*m_formatImpl)(std::ostream &out, const char *fmtBegin,
|
|
|
|
const char *fmtBegin,
|
|
|
|
const char *fmtEnd, int ntrunc, const void *value);
|
|
|
|
const char *fmtEnd,
|
|
|
|
|
|
|
|
int ntrunc,
|
|
|
|
|
|
|
|
const void *value);
|
|
|
|
|
|
|
|
int (*m_toIntImpl)(const void *value);
|
|
|
|
int (*m_toIntImpl)(const void *value);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
@ -555,12 +540,10 @@ inline const char *printFormatStringLiteral(std::ostream &out,
|
|
|
|
// necessary to pull out variable width and precision . The function returns a
|
|
|
|
// necessary to pull out variable width and precision . The function returns a
|
|
|
|
// pointer to the character after the end of the current format spec.
|
|
|
|
// pointer to the character after the end of the current format spec.
|
|
|
|
inline const char *streamStateFromFormat(std::ostream &out,
|
|
|
|
inline const char *streamStateFromFormat(std::ostream &out,
|
|
|
|
bool &spacePadPositive,
|
|
|
|
bool &spacePadPositive, int &ntrunc,
|
|
|
|
int &ntrunc,
|
|
|
|
|
|
|
|
const char *fmtStart,
|
|
|
|
const char *fmtStart,
|
|
|
|
const detail::FormatArg *formatters,
|
|
|
|
const detail::FormatArg *formatters,
|
|
|
|
int &argIndex,
|
|
|
|
int &argIndex, int numFormatters) {
|
|
|
|
int numFormatters) {
|
|
|
|
|
|
|
|
if (*fmtStart != '%') {
|
|
|
|
if (*fmtStart != '%') {
|
|
|
|
TINYFORMAT_ERROR(
|
|
|
|
TINYFORMAT_ERROR(
|
|
|
|
"tinyformat: Not enough conversion specifiers in format string");
|
|
|
|
"tinyformat: Not enough conversion specifiers in format string");
|
|
|
|
@ -736,10 +719,8 @@ inline const char *streamStateFromFormat(std::ostream &out,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
inline void formatImpl(std::ostream &out,
|
|
|
|
inline void formatImpl(std::ostream &out, const char *fmt,
|
|
|
|
const char *fmt,
|
|
|
|
const detail::FormatArg *formatters, int numFormatters) {
|
|
|
|
const detail::FormatArg *formatters,
|
|
|
|
|
|
|
|
int numFormatters) {
|
|
|
|
|
|
|
|
// Saved stream state
|
|
|
|
// Saved stream state
|
|
|
|
std::streamsize origWidth = out.width();
|
|
|
|
std::streamsize origWidth = out.width();
|
|
|
|
std::streamsize origPrecision = out.precision();
|
|
|
|
std::streamsize origPrecision = out.precision();
|
|
|
|
@ -751,13 +732,9 @@ inline void formatImpl(std::ostream &out,
|
|
|
|
fmt = printFormatStringLiteral(out, fmt);
|
|
|
|
fmt = printFormatStringLiteral(out, fmt);
|
|
|
|
bool spacePadPositive = false;
|
|
|
|
bool spacePadPositive = false;
|
|
|
|
int ntrunc = -1;
|
|
|
|
int ntrunc = -1;
|
|
|
|
const char *fmtEnd = streamStateFromFormat(out,
|
|
|
|
const char *fmtEnd =
|
|
|
|
spacePadPositive,
|
|
|
|
streamStateFromFormat(out, spacePadPositive, ntrunc, fmt, formatters,
|
|
|
|
ntrunc,
|
|
|
|
argIndex, numFormatters);
|
|
|
|
fmt,
|
|
|
|
|
|
|
|
formatters,
|
|
|
|
|
|
|
|
argIndex,
|
|
|
|
|
|
|
|
numFormatters);
|
|
|
|
|
|
|
|
if (argIndex >= numFormatters) {
|
|
|
|
if (argIndex >= numFormatters) {
|
|
|
|
// Check args remain after reading any variable width/precision
|
|
|
|
// Check args remain after reading any variable width/precision
|
|
|
|
TINYFORMAT_ERROR("tinyformat: Not enough format arguments");
|
|
|
|
TINYFORMAT_ERROR("tinyformat: Not enough format arguments");
|
|
|
|
@ -810,8 +787,7 @@ public:
|
|
|
|
FormatList(detail::FormatArg *formatters, int N)
|
|
|
|
FormatList(detail::FormatArg *formatters, int N)
|
|
|
|
: m_formatters(formatters), m_N(N) {}
|
|
|
|
: m_formatters(formatters), m_N(N) {}
|
|
|
|
|
|
|
|
|
|
|
|
friend void vformat(std::ostream &out,
|
|
|
|
friend void vformat(std::ostream &out, const char *fmt,
|
|
|
|
const char *fmt,
|
|
|
|
|
|
|
|
const FormatList &list);
|
|
|
|
const FormatList &list);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
|