merge with vitaut/format
This commit is contained in:
parent
5dd604b481
commit
f2e75f74cc
36
format.cc
36
format.cc
@ -160,12 +160,6 @@ void fmt::BasicWriter<Char>::FormatDecimal(
|
|||||||
buffer[0] = internal::DIGITS[index];
|
buffer[0] = internal::DIGITS[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
void fmt::BasicWriter<Char>::FormatDecimal(
|
|
||||||
CharPtr buffer, unsigned long long value, unsigned num_digits) {
|
|
||||||
return fmt::BasicWriter<Char>::FormatDecimal(buffer, static_cast<uint64_t>(value), num_digits);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
typename fmt::BasicWriter<Char>::CharPtr
|
typename fmt::BasicWriter<Char>::CharPtr
|
||||||
fmt::BasicWriter<Char>::PrepareFilledBuffer(
|
fmt::BasicWriter<Char>::PrepareFilledBuffer(
|
||||||
@ -402,13 +396,14 @@ inline const typename fmt::BasicFormatter<Char>::Arg
|
|||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
void fmt::BasicFormatter<Char>::CheckSign(const Char *&s, const Arg &arg) {
|
void fmt::BasicFormatter<Char>::CheckSign(const Char *&s, const Arg &arg) {
|
||||||
|
char sign = static_cast<char>(*s);
|
||||||
if (arg.type > LAST_NUMERIC_TYPE) {
|
if (arg.type > LAST_NUMERIC_TYPE) {
|
||||||
ReportError(s,
|
ReportError(s,
|
||||||
Format("format specifier '{0}' requires numeric argument") << *s);
|
Format("format specifier '{}' requires numeric argument") << sign);
|
||||||
}
|
}
|
||||||
if (arg.type == UINT || arg.type == ULONG || arg.type == ULLONG) {
|
if (arg.type == UINT || arg.type == ULONG || arg.type == ULONG_LONG) {
|
||||||
ReportError(s,
|
ReportError(s,
|
||||||
Format("format specifier '{0}' requires signed argument") << *s);
|
Format("format specifier '{}' requires signed argument") << sign);
|
||||||
}
|
}
|
||||||
++s;
|
++s;
|
||||||
}
|
}
|
||||||
@ -419,7 +414,6 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
format_ = 0;
|
format_ = 0;
|
||||||
next_arg_index_ = 0;
|
next_arg_index_ = 0;
|
||||||
const Char *s = start;
|
const Char *s = start;
|
||||||
typedef internal::Array<Char, BasicWriter<Char>::INLINE_BUFFER_SIZE> Buffer;
|
|
||||||
BasicWriter<Char> &writer = *writer_;
|
BasicWriter<Char> &writer = *writer_;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
Char c = *s++;
|
Char c = *s++;
|
||||||
@ -526,7 +520,7 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
++s;
|
++s;
|
||||||
++num_open_braces_;
|
++num_open_braces_;
|
||||||
const Arg &precision_arg = ParseArgIndex(s);
|
const Arg &precision_arg = ParseArgIndex(s);
|
||||||
unsigned long long value = 0;
|
ULongLong value = 0;
|
||||||
switch (precision_arg.type) {
|
switch (precision_arg.type) {
|
||||||
case INT:
|
case INT:
|
||||||
if (precision_arg.int_value < 0)
|
if (precision_arg.int_value < 0)
|
||||||
@ -544,7 +538,12 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
case ULONG:
|
case ULONG:
|
||||||
value = precision_arg.ulong_value;
|
value = precision_arg.ulong_value;
|
||||||
break;
|
break;
|
||||||
case ULLONG:
|
case LONG_LONG:
|
||||||
|
if (precision_arg.long_long_value < 0)
|
||||||
|
ReportError(s, "negative precision in format");
|
||||||
|
value = precision_arg.long_long_value;
|
||||||
|
break;
|
||||||
|
case ULONG_LONG:
|
||||||
value = precision_arg.ulong_long_value;
|
value = precision_arg.ulong_long_value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -552,7 +551,7 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
}
|
}
|
||||||
if (value > INT_MAX)
|
if (value > INT_MAX)
|
||||||
ReportError(s, "number is too big in format");
|
ReportError(s, "number is too big in format");
|
||||||
precision = value;
|
precision = static_cast<int>(value);
|
||||||
if (*s++ != '}')
|
if (*s++ != '}')
|
||||||
throw FormatError("unmatched '{' in format");
|
throw FormatError("unmatched '{' in format");
|
||||||
--num_open_braces_;
|
--num_open_braces_;
|
||||||
@ -588,7 +587,10 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
case ULONG:
|
case ULONG:
|
||||||
writer.FormatInt(arg.ulong_value, spec);
|
writer.FormatInt(arg.ulong_value, spec);
|
||||||
break;
|
break;
|
||||||
case ULLONG:
|
case LONG_LONG:
|
||||||
|
writer.FormatInt(arg.long_long_value, spec);
|
||||||
|
break;
|
||||||
|
case ULONG_LONG:
|
||||||
writer.FormatInt(arg.ulong_long_value, spec);
|
writer.FormatInt(arg.ulong_long_value, spec);
|
||||||
break;
|
break;
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
@ -668,9 +670,6 @@ template fmt::BasicWriter<char>::CharPtr
|
|||||||
template void fmt::BasicWriter<char>::FormatDecimal(
|
template void fmt::BasicWriter<char>::FormatDecimal(
|
||||||
CharPtr buffer, uint64_t value, unsigned num_digits);
|
CharPtr buffer, uint64_t value, unsigned num_digits);
|
||||||
|
|
||||||
template void fmt::BasicWriter<char>::FormatDecimal(
|
|
||||||
CharPtr buffer, unsigned long long value, unsigned num_digits);
|
|
||||||
|
|
||||||
template fmt::BasicWriter<char>::CharPtr
|
template fmt::BasicWriter<char>::CharPtr
|
||||||
fmt::BasicWriter<char>::PrepareFilledBuffer(
|
fmt::BasicWriter<char>::PrepareFilledBuffer(
|
||||||
unsigned size, const AlignSpec &spec, char sign);
|
unsigned size, const AlignSpec &spec, char sign);
|
||||||
@ -703,9 +702,6 @@ template fmt::BasicWriter<wchar_t>::CharPtr
|
|||||||
template void fmt::BasicWriter<wchar_t>::FormatDecimal(
|
template void fmt::BasicWriter<wchar_t>::FormatDecimal(
|
||||||
CharPtr buffer, uint64_t value, unsigned num_digits);
|
CharPtr buffer, uint64_t value, unsigned num_digits);
|
||||||
|
|
||||||
template void fmt::BasicWriter<wchar_t>::FormatDecimal(
|
|
||||||
CharPtr buffer, unsigned long long value, unsigned num_digits);
|
|
||||||
|
|
||||||
template fmt::BasicWriter<wchar_t>::CharPtr
|
template fmt::BasicWriter<wchar_t>::CharPtr
|
||||||
fmt::BasicWriter<wchar_t>::PrepareFilledBuffer(
|
fmt::BasicWriter<wchar_t>::PrepareFilledBuffer(
|
||||||
unsigned size, const AlignSpec &spec, char sign);
|
unsigned size, const AlignSpec &spec, char sign);
|
||||||
|
|||||||
178
format.h
178
format.h
@ -42,24 +42,42 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Compatibility with compilers other than clang.
|
// Compatibility with compilers other than clang.
|
||||||
#ifndef __has_feature
|
#ifndef __has_feature
|
||||||
# define __has_feature(x) 0
|
# define __has_feature(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FMT_USE_INITIALIZER_LIST
|
||||||
|
# define FMT_USE_INITIALIZER_LIST \
|
||||||
|
(__has_feature(cxx_generalized_initializers) || \
|
||||||
|
(FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || _MSC_VER >= 1700)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FMT_USE_INITIALIZER_LIST
|
||||||
|
# include <initializer_list>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Define FMT_USE_NOEXCEPT to make format use noexcept (C++11 feature).
|
// Define FMT_USE_NOEXCEPT to make format use noexcept (C++11 feature).
|
||||||
#if FMT_USE_NOEXCEPT || \
|
#if FMT_USE_NOEXCEPT || __has_feature(cxx_noexcept) || \
|
||||||
(defined(__has_feature) && __has_feature(cxx_noexcept))
|
(FMT_GCC_VERSION >= 408 && __cplusplus >= 201103)
|
||||||
# define FMT_NOEXCEPT(expr) noexcept(expr)
|
# define FMT_NOEXCEPT(expr) noexcept(expr)
|
||||||
#else
|
#else
|
||||||
# define FMT_NOEXCEPT(expr)
|
# define FMT_NOEXCEPT(expr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#if FMT_GCC_VERSION >= 406
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
# define FMT_GCC_DIAGNOSTIC
|
||||||
# pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wlong-long"
|
# pragma GCC diagnostic ignored "-Wlong-long"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if _MSC_VER
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable: 4521)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace fmt {
|
namespace fmt {
|
||||||
@ -151,11 +169,16 @@ void Array<T, SIZE>::append(const T *begin, const T *end) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct CharTraits;
|
class CharTraits;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct CharTraits<char> {
|
class CharTraits<char> {
|
||||||
typedef wchar_t UnsupportedType;
|
private:
|
||||||
|
// Conversion from wchar_t to char is not supported.
|
||||||
|
static char ConvertWChar(wchar_t);
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef const wchar_t *UnsupportedStrType;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static int FormatFloat(char *buffer, std::size_t size,
|
static int FormatFloat(char *buffer, std::size_t size,
|
||||||
@ -163,8 +186,11 @@ struct CharTraits<char> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct CharTraits<wchar_t> {
|
class CharTraits<wchar_t> {
|
||||||
typedef char UnsupportedType;
|
public:
|
||||||
|
typedef const char *UnsupportedStrType;
|
||||||
|
|
||||||
|
static wchar_t ConvertWChar(wchar_t value) { return value; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static int FormatFloat(wchar_t *buffer, std::size_t size,
|
static int FormatFloat(wchar_t *buffer, std::size_t size,
|
||||||
@ -189,9 +215,6 @@ struct SignedIntTraits {
|
|||||||
template <>
|
template <>
|
||||||
struct IntTraits<int> : SignedIntTraits<int, unsigned> {};
|
struct IntTraits<int> : SignedIntTraits<int, unsigned> {};
|
||||||
|
|
||||||
template <>
|
|
||||||
struct IntTraits<uint32_t> : SignedIntTraits<uint32_t, unsigned> {};
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct IntTraits<long> : SignedIntTraits<long, unsigned long> {};
|
struct IntTraits<long> : SignedIntTraits<long, unsigned long> {};
|
||||||
|
|
||||||
@ -379,11 +402,6 @@ class IntFormatter : public SpecT {
|
|||||||
*/
|
*/
|
||||||
IntFormatter<int, TypeSpec<'b'> > bin(int value);
|
IntFormatter<int, TypeSpec<'b'> > bin(int value);
|
||||||
|
|
||||||
/**
|
|
||||||
Returns an integer formatter that formats the value in base 2.
|
|
||||||
*/
|
|
||||||
IntFormatter<int, TypeSpec<'B'> > binu(int value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns an integer formatter that formats the value in base 8.
|
Returns an integer formatter that formats the value in base 8.
|
||||||
*/
|
*/
|
||||||
@ -421,9 +439,7 @@ IntFormatter<int, AlignTypeSpec<TYPE_CODE> > pad(
|
|||||||
inline IntFormatter<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
|
inline IntFormatter<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
|
||||||
return IntFormatter<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
|
return IntFormatter<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
|
||||||
} \
|
} \
|
||||||
inline IntFormatter<TYPE, TypeSpec<'B'> > binu(TYPE value) { \
|
\
|
||||||
return IntFormatter<TYPE, TypeSpec<'B'> >(value, TypeSpec<'B'>()); \
|
|
||||||
} \
|
|
||||||
inline IntFormatter<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
|
inline IntFormatter<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
|
||||||
return IntFormatter<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
|
return IntFormatter<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
|
||||||
} \
|
} \
|
||||||
@ -454,6 +470,7 @@ DEFINE_INT_FORMATTERS(int)
|
|||||||
DEFINE_INT_FORMATTERS(long)
|
DEFINE_INT_FORMATTERS(long)
|
||||||
DEFINE_INT_FORMATTERS(unsigned)
|
DEFINE_INT_FORMATTERS(unsigned)
|
||||||
DEFINE_INT_FORMATTERS(unsigned long)
|
DEFINE_INT_FORMATTERS(unsigned long)
|
||||||
|
DEFINE_INT_FORMATTERS(long long)
|
||||||
DEFINE_INT_FORMATTERS(unsigned long long)
|
DEFINE_INT_FORMATTERS(unsigned long long)
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -511,9 +528,6 @@ class BasicWriter {
|
|||||||
static void FormatDecimal(
|
static void FormatDecimal(
|
||||||
CharPtr buffer, uint64_t value, unsigned num_digits);
|
CharPtr buffer, uint64_t value, unsigned num_digits);
|
||||||
|
|
||||||
static void FormatDecimal(
|
|
||||||
CharPtr buffer, unsigned long long value, unsigned num_digits);
|
|
||||||
|
|
||||||
static CharPtr FillPadding(CharPtr buffer,
|
static CharPtr FillPadding(CharPtr buffer,
|
||||||
unsigned total_size, std::size_t content_size, wchar_t fill);
|
unsigned total_size, std::size_t content_size, wchar_t fill);
|
||||||
|
|
||||||
@ -551,7 +565,7 @@ class BasicWriter {
|
|||||||
// char stream and vice versa. If you want to print a wide string
|
// char stream and vice versa. If you want to print a wide string
|
||||||
// as a pointer as std::ostream does, cast it to const void*.
|
// as a pointer as std::ostream does, cast it to const void*.
|
||||||
// Do not implement!
|
// Do not implement!
|
||||||
void operator<<(const typename internal::CharTraits<Char>::UnsupportedType *);
|
void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -752,9 +766,8 @@ BasicWriter<Char> &BasicWriter<Char>::operator<<(
|
|||||||
} while ((n >>= 1) != 0);
|
} while ((n >>= 1) != 0);
|
||||||
Char *p = GetBase(PrepareFilledBuffer(size, f, sign));
|
Char *p = GetBase(PrepareFilledBuffer(size, f, sign));
|
||||||
n = abs_value;
|
n = abs_value;
|
||||||
const char *digits = "01";
|
|
||||||
do {
|
do {
|
||||||
*p-- = digits[n & 0x1];
|
*p-- = '0' + (n & 1);
|
||||||
} while ((n >>= 1) != 0);
|
} while ((n >>= 1) != 0);
|
||||||
if (print_prefix) {
|
if (print_prefix) {
|
||||||
*p-- = f.type();
|
*p-- = f.type();
|
||||||
@ -787,7 +800,8 @@ BasicWriter<Char> &BasicWriter<Char>::operator<<(
|
|||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
BasicFormatter<Char> BasicWriter<Char>::Format(StringRef format) {
|
BasicFormatter<Char> BasicWriter<Char>::Format(StringRef format) {
|
||||||
return BasicFormatter<Char>(*this, format.c_str());
|
BasicFormatter<Char> f(*this, format.c_str());
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BasicWriter<char> Writer;
|
typedef BasicWriter<char> Writer;
|
||||||
@ -826,7 +840,7 @@ class BasicFormatter {
|
|||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
// Numeric types should go first.
|
// Numeric types should go first.
|
||||||
INT, UINT, LONG, ULONG, ULLONG, DOUBLE, LONG_DOUBLE,
|
INT, UINT, LONG, ULONG, LONG_LONG, ULONG_LONG, DOUBLE, LONG_DOUBLE,
|
||||||
LAST_NUMERIC_TYPE = LONG_DOUBLE,
|
LAST_NUMERIC_TYPE = LONG_DOUBLE,
|
||||||
CHAR, STRING, WSTRING, POINTER, CUSTOM
|
CHAR, STRING, WSTRING, POINTER, CUSTOM
|
||||||
};
|
};
|
||||||
@ -847,12 +861,6 @@ class BasicFormatter {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
Arg(T *value);
|
Arg(T *value);
|
||||||
|
|
||||||
// This method is private to disallow formatting of wide characters.
|
|
||||||
// If you want to output a wide character cast it to integer type.
|
|
||||||
// Do not implement!
|
|
||||||
// TODO
|
|
||||||
//Arg(wchar_t value);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Type type;
|
Type type;
|
||||||
union {
|
union {
|
||||||
@ -861,6 +869,7 @@ class BasicFormatter {
|
|||||||
double double_value;
|
double double_value;
|
||||||
long long_value;
|
long long_value;
|
||||||
unsigned long ulong_value;
|
unsigned long ulong_value;
|
||||||
|
long long long_long_value;
|
||||||
unsigned long long ulong_long_value;
|
unsigned long long ulong_long_value;
|
||||||
long double long_double_value;
|
long double long_double_value;
|
||||||
const void *pointer_value;
|
const void *pointer_value;
|
||||||
@ -881,12 +890,18 @@ class BasicFormatter {
|
|||||||
Arg(unsigned value) : type(UINT), uint_value(value), formatter(0) {}
|
Arg(unsigned value) : type(UINT), uint_value(value), formatter(0) {}
|
||||||
Arg(long value) : type(LONG), long_value(value), formatter(0) {}
|
Arg(long value) : type(LONG), long_value(value), formatter(0) {}
|
||||||
Arg(unsigned long value) : type(ULONG), ulong_value(value), formatter(0) {}
|
Arg(unsigned long value) : type(ULONG), ulong_value(value), formatter(0) {}
|
||||||
Arg(unsigned long long value) : type(ULLONG), ulong_long_value(value), formatter(0) {}
|
Arg(long long value)
|
||||||
|
: type(LONG_LONG), long_long_value(value), formatter(0) {}
|
||||||
|
Arg(unsigned long long value)
|
||||||
|
: type(ULONG_LONG), ulong_long_value(value), formatter(0) {}
|
||||||
Arg(float value) : type(DOUBLE), double_value(value), formatter(0) {}
|
Arg(float value) : type(DOUBLE), double_value(value), formatter(0) {}
|
||||||
Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {}
|
Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {}
|
||||||
Arg(long double value)
|
Arg(long double value)
|
||||||
: type(LONG_DOUBLE), long_double_value(value), formatter(0) {}
|
: type(LONG_DOUBLE), long_double_value(value), formatter(0) {}
|
||||||
Arg(Char value) : type(CHAR), int_value(value), formatter(0) {}
|
Arg(char value) : type(CHAR), int_value(value), formatter(0) {}
|
||||||
|
Arg(wchar_t value)
|
||||||
|
: type(CHAR), int_value(internal::CharTraits<Char>::ConvertWChar(value)),
|
||||||
|
formatter(0) {}
|
||||||
|
|
||||||
Arg(const Char *value) : type(STRING), formatter(0) {
|
Arg(const Char *value) : type(STRING), formatter(0) {
|
||||||
string.value = value;
|
string.value = value;
|
||||||
@ -908,6 +923,11 @@ class BasicFormatter {
|
|||||||
string.size = value.size();
|
string.size = value.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Arg(StringRef value) : type(STRING), formatter(0) {
|
||||||
|
string.value = value.c_str();
|
||||||
|
string.size = value.size();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Arg(const T &value) : type(CUSTOM), formatter(0) {
|
Arg(const T &value) : type(CUSTOM), formatter(0) {
|
||||||
custom.value = &value;
|
custom.value = &value;
|
||||||
@ -938,16 +958,18 @@ class BasicFormatter {
|
|||||||
int num_open_braces_;
|
int num_open_braces_;
|
||||||
int next_arg_index_;
|
int next_arg_index_;
|
||||||
|
|
||||||
|
typedef unsigned long long ULongLong;
|
||||||
|
|
||||||
friend class internal::FormatterProxy<Char>;
|
friend class internal::FormatterProxy<Char>;
|
||||||
|
|
||||||
// Forbid copying other than from a temporary. Do not implement.
|
// Forbid copying from a temporary as in the following example:
|
||||||
BasicFormatter(BasicFormatter &);
|
// fmt::Formatter<> f = Format("test"); // not allowed
|
||||||
|
// This is done because BasicFormatter objects should normally exist
|
||||||
|
// only as temporaries returned by one of the formatting functions.
|
||||||
|
// Do not implement.
|
||||||
|
BasicFormatter(const BasicFormatter &);
|
||||||
BasicFormatter& operator=(const BasicFormatter &);
|
BasicFormatter& operator=(const BasicFormatter &);
|
||||||
|
|
||||||
void Add(const Arg &arg) {
|
|
||||||
args_.push_back(&arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReportError(const Char *s, StringRef message) const;
|
void ReportError(const Char *s, StringRef message) const;
|
||||||
|
|
||||||
unsigned ParseUInt(const Char *&s) const;
|
unsigned ParseUInt(const Char *&s) const;
|
||||||
@ -957,6 +979,8 @@ class BasicFormatter {
|
|||||||
|
|
||||||
void CheckSign(const Char *&s, const Arg &arg);
|
void CheckSign(const Char *&s, const Arg &arg);
|
||||||
|
|
||||||
|
// Parses the format string and performs the actual formatting,
|
||||||
|
// writing the output to writer_.
|
||||||
void DoFormat();
|
void DoFormat();
|
||||||
|
|
||||||
struct Proxy {
|
struct Proxy {
|
||||||
@ -980,27 +1004,35 @@ class BasicFormatter {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructs a formatter with a writer to be used for output and a format
|
// Constructs a formatter with a writer to be used for output and a format
|
||||||
// format string.
|
// string.
|
||||||
BasicFormatter(BasicWriter<Char> &w, const Char *format = 0)
|
BasicFormatter(BasicWriter<Char> &w, const Char *format = 0)
|
||||||
: writer_(&w), format_(format) {}
|
: writer_(&w), format_(format) {}
|
||||||
|
|
||||||
|
#if FMT_USE_INITIALIZER_LIST
|
||||||
|
// Constructs a formatter with formatting arguments.
|
||||||
|
BasicFormatter(BasicWriter<Char> &w,
|
||||||
|
const Char *format, std::initializer_list<Arg> args)
|
||||||
|
: writer_(&w), format_(format) {
|
||||||
|
args_.reserve(args.size());
|
||||||
|
for (const Arg &arg: args)
|
||||||
|
args_.push_back(&arg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Performs formatting if the format string is non-null. The format string
|
||||||
|
// can be null if its ownership has been transferred to another formatter.
|
||||||
~BasicFormatter() {
|
~BasicFormatter() {
|
||||||
CompleteFormatting();
|
CompleteFormatting();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a formatter from a proxy object.
|
BasicFormatter(BasicFormatter &f) : writer_(f.writer_), format_(f.format_) {
|
||||||
BasicFormatter(const Proxy &p) : writer_(p.writer), format_(p.format) {}
|
f.format_ = 0;
|
||||||
|
|
||||||
operator Proxy() {
|
|
||||||
const Char *format = format_;
|
|
||||||
format_ = 0;
|
|
||||||
return Proxy(writer_, format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feeds an argument to a formatter.
|
// Feeds an argument to a formatter.
|
||||||
BasicFormatter &operator<<(const Arg &arg) {
|
BasicFormatter &operator<<(const Arg &arg) {
|
||||||
arg.formatter = this;
|
arg.formatter = this;
|
||||||
Add(arg);
|
args_.push_back(&arg);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,7 +1121,8 @@ class NoAction {
|
|||||||
|
|
||||||
// Formats an error message and prints it to stdout.
|
// Formats an error message and prints it to stdout.
|
||||||
fmt::Formatter<PrintError> ReportError(const char *format) {
|
fmt::Formatter<PrintError> ReportError(const char *format) {
|
||||||
return fmt::Formatter<PrintError>(format);
|
fmt::Formatter f<PrintError>(format);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportError("File not found: {}") << path;
|
ReportError("File not found: {}") << path;
|
||||||
@ -1102,16 +1135,9 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
bool inactive_;
|
bool inactive_;
|
||||||
|
|
||||||
// Forbid copying other than from a temporary. Do not implement.
|
// Forbid copying other than from a temporary. Do not implement.
|
||||||
Formatter(Formatter &);
|
Formatter(const Formatter &);
|
||||||
Formatter& operator=(const Formatter &);
|
Formatter& operator=(const Formatter &);
|
||||||
|
|
||||||
struct Proxy {
|
|
||||||
const Char *format;
|
|
||||||
Action action;
|
|
||||||
|
|
||||||
Proxy(const Char *fmt, Action a) : format(fmt), action(a) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
@ -1127,10 +1153,10 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
inactive_(false) {
|
inactive_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a formatter from a proxy object.
|
Formatter(Formatter &f)
|
||||||
Formatter(const Proxy &p)
|
: Action(f), BasicFormatter<Char>(writer_, f.TakeFormatString()),
|
||||||
: Action(p.action), BasicFormatter<Char>(writer_, p.format),
|
|
||||||
inactive_(false) {
|
inactive_(false) {
|
||||||
|
f.inactive_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1142,12 +1168,6 @@ class Formatter : private Action, public BasicFormatter<Char> {
|
|||||||
(*this)(writer_);
|
(*this)(writer_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts the formatter into a proxy object.
|
|
||||||
operator Proxy() {
|
|
||||||
inactive_ = true;
|
|
||||||
return Proxy(this->TakeFormatString(), *this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1196,10 +1216,9 @@ class FormatInt {
|
|||||||
}
|
}
|
||||||
explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {}
|
explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {}
|
||||||
explicit FormatInt(uint64_t value) : str_(FormatDecimal(value)) {}
|
explicit FormatInt(uint64_t value) : str_(FormatDecimal(value)) {}
|
||||||
explicit FormatInt(unsigned long long value) : str_(FormatDecimal(value)) {}
|
|
||||||
|
|
||||||
inline const char *c_str() const { return str_; }
|
const char *c_str() const { return str_; }
|
||||||
inline std::string str() const { return str_; }
|
std::string str() const { return str_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1224,11 +1243,13 @@ class FormatInt {
|
|||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
inline Formatter<> Format(StringRef format) {
|
inline Formatter<> Format(StringRef format) {
|
||||||
return Formatter<>(format);
|
Formatter<> f(format);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Formatter<NoAction, wchar_t> Format(WStringRef format) {
|
inline Formatter<NoAction, wchar_t> Format(WStringRef format) {
|
||||||
return Formatter<NoAction, wchar_t>(format);
|
Formatter<NoAction, wchar_t> f(format);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A formatting action that writes formatted output to stdout. */
|
/** A formatting action that writes formatted output to stdout. */
|
||||||
@ -1244,14 +1265,17 @@ class Write {
|
|||||||
// Example:
|
// Example:
|
||||||
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
||||||
inline Formatter<Write> Print(StringRef format) {
|
inline Formatter<Write> Print(StringRef format) {
|
||||||
return Formatter<Write>(format);
|
Formatter<Write> f(format);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef FMT_GCC_DIAGNOSTIC
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
|
||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if _MSC_VER
|
||||||
|
# pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // FORMAT_H_
|
#endif // FORMAT_H_
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user