mirror of
https://github.com/fmtlib/fmt.git
synced 2025-08-01 19:54:46 +02:00
ArgInfo -> Arg
This commit is contained in:
62
format.cc
62
format.cc
@@ -51,6 +51,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using fmt::ULongLong;
|
using fmt::ULongLong;
|
||||||
|
using fmt::internal::Arg;
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
@@ -118,10 +119,9 @@ void ReportError(FormatFunc func,
|
|||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fmt::internal::ArgInfo DUMMY_ARG = {fmt::internal::ArgInfo::INT, 0};
|
const Arg DUMMY_ARG = {Arg::INT, 0};
|
||||||
|
|
||||||
fmt::ULongLong GetIntValue(const fmt::internal::ArgInfo &arg) {
|
fmt::ULongLong GetIntValue(const Arg &arg) {
|
||||||
typedef fmt::internal::ArgInfo Arg;
|
|
||||||
switch (arg.type) {
|
switch (arg.type) {
|
||||||
case Arg::INT:
|
case Arg::INT:
|
||||||
return arg.int_value;
|
return arg.int_value;
|
||||||
@@ -135,6 +135,25 @@ fmt::ULongLong GetIntValue(const fmt::internal::ArgInfo &arg) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parses an unsigned integer advancing s to the end of the parsed input.
|
||||||
|
// This function assumes that the first character of s is a digit.
|
||||||
|
template <typename Char>
|
||||||
|
int ParseNonnegativeInt(const Char *&s, const char *&error) FMT_NOEXCEPT(true) {
|
||||||
|
assert('0' <= *s && *s <= '9');
|
||||||
|
unsigned value = 0;
|
||||||
|
do {
|
||||||
|
unsigned new_value = value * 10 + (*s++ - '0');
|
||||||
|
// Check if value wrapped around.
|
||||||
|
value = new_value >= value ? new_value : UINT_MAX;
|
||||||
|
} while ('0' <= *s && *s <= '9');
|
||||||
|
if (value > INT_MAX) {
|
||||||
|
if (!error)
|
||||||
|
error = "number is too big in format";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int fmt::internal::SignBitNoInline(double value) { return SignBit(value); }
|
int fmt::internal::SignBitNoInline(double value) { return SignBit(value); }
|
||||||
@@ -349,26 +368,6 @@ void fmt::internal::FormatErrorReporter<Char>::operator()(
|
|||||||
throw fmt::FormatError("unmatched '{' in format");
|
throw fmt::FormatError("unmatched '{' in format");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses an unsigned integer advancing s to the end of the parsed input.
|
|
||||||
// This function assumes that the first character of s is a digit.
|
|
||||||
template <typename Char>
|
|
||||||
int fmt::internal::ParseNonnegativeInt(
|
|
||||||
const Char *&s, const char *&error) FMT_NOEXCEPT(true) {
|
|
||||||
assert('0' <= *s && *s <= '9');
|
|
||||||
unsigned value = 0;
|
|
||||||
do {
|
|
||||||
unsigned new_value = value * 10 + (*s++ - '0');
|
|
||||||
// Check if value wrapped around.
|
|
||||||
value = new_value >= value ? new_value : UINT_MAX;
|
|
||||||
} while ('0' <= *s && *s <= '9');
|
|
||||||
if (value > INT_MAX) {
|
|
||||||
if (!error)
|
|
||||||
error = "number is too big in format";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fills the padding around the content and returns the pointer to the
|
// Fills the padding around the content and returns the pointer to the
|
||||||
// content area.
|
// content area.
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@@ -553,7 +552,7 @@ void fmt::BasicWriter<Char>::write_str(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline const typename fmt::BasicWriter<Char>::Arg
|
inline const Arg
|
||||||
&fmt::BasicWriter<Char>::FormatParser::ParseArgIndex(const Char *&s) {
|
&fmt::BasicWriter<Char>::FormatParser::ParseArgIndex(const Char *&s) {
|
||||||
unsigned arg_index = 0;
|
unsigned arg_index = 0;
|
||||||
if (*s < '0' || *s > '9') {
|
if (*s < '0' || *s > '9') {
|
||||||
@@ -571,7 +570,7 @@ inline const typename fmt::BasicWriter<Char>::Arg
|
|||||||
}
|
}
|
||||||
next_arg_index_ = -1;
|
next_arg_index_ = -1;
|
||||||
const char *error = 0;
|
const char *error = 0;
|
||||||
arg_index = internal::ParseNonnegativeInt(s, error);
|
arg_index = ParseNonnegativeInt(s, error);
|
||||||
if (error)
|
if (error)
|
||||||
report_error_(s, error); // TODO
|
report_error_(s, error); // TODO
|
||||||
}
|
}
|
||||||
@@ -630,7 +629,7 @@ unsigned fmt::internal::PrintfParser<Char>::ParseHeader(
|
|||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
// Parse an argument index (if followed by '$') or a width possibly
|
// Parse an argument index (if followed by '$') or a width possibly
|
||||||
// preceded with '0' flag(s).
|
// preceded with '0' flag(s).
|
||||||
unsigned value = internal::ParseNonnegativeInt(s, error);
|
unsigned value = ParseNonnegativeInt(s, error);
|
||||||
if (*s == '$') { // value is an argument index
|
if (*s == '$') { // value is an argument index
|
||||||
++s;
|
++s;
|
||||||
arg_index = value;
|
arg_index = value;
|
||||||
@@ -648,7 +647,7 @@ unsigned fmt::internal::PrintfParser<Char>::ParseHeader(
|
|||||||
ParseFlags(spec, s);
|
ParseFlags(spec, s);
|
||||||
// Parse width.
|
// Parse width.
|
||||||
if (*s >= '0' && *s <= '9') {
|
if (*s >= '0' && *s <= '9') {
|
||||||
spec.width_ = internal::ParseNonnegativeInt(s, error);
|
spec.width_ = ParseNonnegativeInt(s, error);
|
||||||
} else if (*s == '*') {
|
} else if (*s == '*') {
|
||||||
++s;
|
++s;
|
||||||
const Arg &arg = HandleArgIndex(UINT_MAX, error);
|
const Arg &arg = HandleArgIndex(UINT_MAX, error);
|
||||||
@@ -689,8 +688,7 @@ unsigned fmt::internal::PrintfParser<Char>::ParseHeader(
|
|||||||
|
|
||||||
// TODO: move to a base class that doesn't depend on template argument
|
// TODO: move to a base class that doesn't depend on template argument
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
const fmt::internal::ArgInfo
|
const Arg &fmt::internal::PrintfParser<Char>::HandleArgIndex(
|
||||||
&fmt::internal::PrintfParser<Char>::HandleArgIndex(
|
|
||||||
unsigned arg_index, const char *&error) {
|
unsigned arg_index, const char *&error) {
|
||||||
if (arg_index != UINT_MAX) {
|
if (arg_index != UINT_MAX) {
|
||||||
if (next_arg_index_ <= 0) {
|
if (next_arg_index_ <= 0) {
|
||||||
@@ -751,7 +749,7 @@ void fmt::internal::PrintfParser<Char>::Format(
|
|||||||
if (*s == '.') {
|
if (*s == '.') {
|
||||||
++s;
|
++s;
|
||||||
if ('0' <= *s && *s <= '9') {
|
if ('0' <= *s && *s <= '9') {
|
||||||
spec.precision_ = internal::ParseNonnegativeInt(s, error);
|
spec.precision_ = ParseNonnegativeInt(s, error);
|
||||||
} else if (*s == '*') {
|
} else if (*s == '*') {
|
||||||
++s;
|
++s;
|
||||||
const Arg &arg = HandleArgIndex(UINT_MAX, error);
|
const Arg &arg = HandleArgIndex(UINT_MAX, error);
|
||||||
@@ -957,7 +955,7 @@ void fmt::BasicWriter<Char>::FormatParser::Format(
|
|||||||
}
|
}
|
||||||
// Zero may be parsed again as a part of the width, but it is simpler
|
// Zero may be parsed again as a part of the width, but it is simpler
|
||||||
// and more efficient than checking if the next char is a digit.
|
// and more efficient than checking if the next char is a digit.
|
||||||
spec.width_ = internal::ParseNonnegativeInt(s, error);
|
spec.width_ = ParseNonnegativeInt(s, error);
|
||||||
if (error)
|
if (error)
|
||||||
report_error_(s, error);
|
report_error_(s, error);
|
||||||
}
|
}
|
||||||
@@ -967,7 +965,7 @@ void fmt::BasicWriter<Char>::FormatParser::Format(
|
|||||||
++s;
|
++s;
|
||||||
spec.precision_ = 0;
|
spec.precision_ = 0;
|
||||||
if ('0' <= *s && *s <= '9') {
|
if ('0' <= *s && *s <= '9') {
|
||||||
spec.precision_ = internal::ParseNonnegativeInt(s, error);
|
spec.precision_ = ParseNonnegativeInt(s, error);
|
||||||
if (error)
|
if (error)
|
||||||
report_error_(s, error);
|
report_error_(s, error);
|
||||||
} else if (*s == '{') {
|
} else if (*s == '{') {
|
||||||
|
49
format.h
49
format.h
@@ -562,12 +562,6 @@ struct FormatErrorReporter {
|
|||||||
void operator()(const Char *s, fmt::StringRef message) const;
|
void operator()(const Char *s, fmt::StringRef message) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parses a nonnegative integer advancing s to the end of the parsed input.
|
|
||||||
// This function assumes that the first character of s is a digit.
|
|
||||||
template <typename Char>
|
|
||||||
int ParseNonnegativeInt(
|
|
||||||
const Char *&s, const char *&error) FMT_NOEXCEPT(true);
|
|
||||||
|
|
||||||
// Computes max(Arg, 1) at compile time. It is used to avoid errors about
|
// Computes max(Arg, 1) at compile time. It is used to avoid errors about
|
||||||
// allocating an array of 0 size.
|
// allocating an array of 0 size.
|
||||||
template <unsigned Arg>
|
template <unsigned Arg>
|
||||||
@@ -580,9 +574,8 @@ struct NonZero<0> {
|
|||||||
enum { VALUE = 1 };
|
enum { VALUE = 1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information about a format argument. It is a POD type to allow
|
// A formatting argument. It is a POD type to allow storage in internal::Array.
|
||||||
// storage in internal::Array.
|
struct Arg {
|
||||||
struct ArgInfo {
|
|
||||||
enum Type {
|
enum Type {
|
||||||
// Integer types should go first,
|
// Integer types should go first,
|
||||||
INT, UINT, LONG_LONG, ULONG_LONG, LAST_INTEGER_TYPE = ULONG_LONG,
|
INT, UINT, LONG_LONG, ULONG_LONG, LAST_INTEGER_TYPE = ULONG_LONG,
|
||||||
@@ -614,9 +607,9 @@ struct ArgInfo {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Makes an ArgInfo object from any type.
|
// Makes an Arg object from any type.
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class MakeArg : public internal::ArgInfo {
|
class MakeArg : public Arg {
|
||||||
private:
|
private:
|
||||||
// This method is private to disallow formatting of arbitrary pointers.
|
// This method is private to disallow formatting of arbitrary pointers.
|
||||||
// If you want to output a pointer cast it to const void*. Do not implement!
|
// If you want to output a pointer cast it to const void*. Do not implement!
|
||||||
@@ -629,8 +622,6 @@ class MakeArg : public internal::ArgInfo {
|
|||||||
MakeArg(T *value);
|
MakeArg(T *value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using internal::ArgInfo::type;
|
|
||||||
|
|
||||||
MakeArg() {}
|
MakeArg() {}
|
||||||
// TODO: unsigned char & signed char
|
// TODO: unsigned char & signed char
|
||||||
MakeArg(short value) { type = INT; int_value = value; }
|
MakeArg(short value) { type = INT; int_value = value; }
|
||||||
@@ -718,12 +709,12 @@ class RuntimeError : public std::runtime_error {
|
|||||||
*/
|
*/
|
||||||
class ArgList {
|
class ArgList {
|
||||||
private:
|
private:
|
||||||
const internal::ArgInfo *args_;
|
const internal::Arg *args_;
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ArgList() : size_(0) {}
|
ArgList() : size_(0) {}
|
||||||
ArgList(const internal::ArgInfo *args, std::size_t size)
|
ArgList(const internal::Arg *args, std::size_t size)
|
||||||
: args_(args), size_(size) {}
|
: args_(args), size_(size) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -734,7 +725,7 @@ class ArgList {
|
|||||||
/**
|
/**
|
||||||
Returns the argument at specified index.
|
Returns the argument at specified index.
|
||||||
*/
|
*/
|
||||||
const internal::ArgInfo &operator[](std::size_t index) const {
|
const internal::Arg &operator[](std::size_t index) const {
|
||||||
return args_[index];
|
return args_[index];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -747,15 +738,13 @@ class PrintfParser {
|
|||||||
ArgList args_;
|
ArgList args_;
|
||||||
int next_arg_index_;
|
int next_arg_index_;
|
||||||
|
|
||||||
typedef ArgInfo Arg;
|
|
||||||
|
|
||||||
void ParseFlags(FormatSpec &spec, const Char *&s);
|
void ParseFlags(FormatSpec &spec, const Char *&s);
|
||||||
|
|
||||||
// Parses argument index, flags and width and returns the parsed
|
// Parses argument index, flags and width and returns the parsed
|
||||||
// argument index.
|
// argument index.
|
||||||
unsigned ParseHeader(const Char *&s, FormatSpec &spec, const char *&error);
|
unsigned ParseHeader(const Char *&s, FormatSpec &spec, const char *&error);
|
||||||
|
|
||||||
const ArgInfo &HandleArgIndex(unsigned arg_index, const char *&error);
|
const internal::Arg &HandleArgIndex(unsigned arg_index, const char *&error);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Format(BasicWriter<Char> &writer,
|
void Format(BasicWriter<Char> &writer,
|
||||||
@@ -1012,7 +1001,8 @@ inline StrFormatSpec<wchar_t> pad(
|
|||||||
# define FMT_VARIADIC_VOID(func, arg_type) \
|
# define FMT_VARIADIC_VOID(func, arg_type) \
|
||||||
template<typename... Args> \
|
template<typename... Args> \
|
||||||
void func(arg_type arg1, const Args & ... args) { \
|
void func(arg_type arg1, const Args & ... args) { \
|
||||||
const internal::ArgInfo arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
|
using fmt::internal::Arg; \
|
||||||
|
const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
|
||||||
fmt::internal::MakeArg<Char>(args)... \
|
fmt::internal::MakeArg<Char>(args)... \
|
||||||
}; \
|
}; \
|
||||||
func(arg1, ArgList(arg_array, sizeof...(Args))); \
|
func(arg1, ArgList(arg_array, sizeof...(Args))); \
|
||||||
@@ -1022,7 +1012,8 @@ inline StrFormatSpec<wchar_t> pad(
|
|||||||
# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
|
# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
|
||||||
template<typename... Args> \
|
template<typename... Args> \
|
||||||
ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
|
ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
|
||||||
const internal::ArgInfo arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
|
using fmt::internal::Arg; \
|
||||||
|
const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
|
||||||
fmt::internal::MakeArg<Char>(args)... \
|
fmt::internal::MakeArg<Char>(args)... \
|
||||||
}; \
|
}; \
|
||||||
func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \
|
func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \
|
||||||
@@ -1036,7 +1027,7 @@ inline StrFormatSpec<wchar_t> pad(
|
|||||||
# define FMT_WRAP1(func, arg_type, n) \
|
# define FMT_WRAP1(func, arg_type, n) \
|
||||||
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
|
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
|
||||||
inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
|
inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
|
||||||
const fmt::internal::ArgInfo args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
|
const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
|
||||||
func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
|
func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1051,7 +1042,7 @@ inline StrFormatSpec<wchar_t> pad(
|
|||||||
# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
|
# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
|
||||||
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
|
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
|
||||||
ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
|
ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
|
||||||
const fmt::internal::ArgInfo args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
|
const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
|
||||||
func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
|
func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1165,8 +1156,6 @@ class BasicWriter {
|
|||||||
|
|
||||||
typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
|
typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
|
||||||
|
|
||||||
typedef internal::ArgInfo Arg;
|
|
||||||
|
|
||||||
#if _SECURE_SCL
|
#if _SECURE_SCL
|
||||||
static Char *GetBase(CharPtr p) { return p.base(); }
|
static Char *GetBase(CharPtr p) { return p.base(); }
|
||||||
#else
|
#else
|
||||||
@@ -1228,9 +1217,9 @@ class BasicWriter {
|
|||||||
fmt::internal::FormatErrorReporter<Char> report_error_;
|
fmt::internal::FormatErrorReporter<Char> report_error_;
|
||||||
|
|
||||||
// Parses argument index and returns an argument with this index.
|
// Parses argument index and returns an argument with this index.
|
||||||
const Arg &ParseArgIndex(const Char *&s);
|
const internal::Arg &ParseArgIndex(const Char *&s);
|
||||||
|
|
||||||
void CheckSign(const Char *&s, const Arg &arg);
|
void CheckSign(const Char *&s, const internal::Arg &arg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Format(BasicWriter<Char> &writer,
|
void Format(BasicWriter<Char> &writer,
|
||||||
@@ -1834,8 +1823,8 @@ inline void FormatDec(char *&buffer, T value) {
|
|||||||
template<typename... Args> \
|
template<typename... Args> \
|
||||||
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
|
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
|
||||||
const Args & ... args) { \
|
const Args & ... args) { \
|
||||||
enum {N = fmt::internal::NonZero<sizeof...(Args)>::VALUE}; \
|
using fmt::internal::Arg; \
|
||||||
const fmt::internal::ArgInfo array[N] = { \
|
const Arg array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
|
||||||
fmt::internal::MakeArg<Char>(args)... \
|
fmt::internal::MakeArg<Char>(args)... \
|
||||||
}; \
|
}; \
|
||||||
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
|
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
|
||||||
@@ -1848,7 +1837,7 @@ inline void FormatDec(char *&buffer, T value) {
|
|||||||
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
|
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \
|
||||||
inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
|
inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
|
||||||
FMT_GEN(n, FMT_MAKE_ARG)) { \
|
FMT_GEN(n, FMT_MAKE_ARG)) { \
|
||||||
const fmt::internal::ArgInfo args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \
|
const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \
|
||||||
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
|
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
|
||||||
fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
|
fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user