ArgInfo -> Arg

This commit is contained in:
Victor Zverovich 2014-07-02 06:33:25 -07:00
parent c494c980b6
commit 6e5551e77a
2 changed files with 49 additions and 62 deletions

View File

@ -51,6 +51,7 @@
#endif
using fmt::ULongLong;
using fmt::internal::Arg;
#if _MSC_VER
# pragma warning(push)
@ -118,10 +119,9 @@ void ReportError(FormatFunc func,
} 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) {
typedef fmt::internal::ArgInfo Arg;
fmt::ULongLong GetIntValue(const Arg &arg) {
switch (arg.type) {
case Arg::INT:
return arg.int_value;
@ -135,6 +135,25 @@ fmt::ULongLong GetIntValue(const fmt::internal::ArgInfo &arg) {
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
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");
}
// 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
// content area.
template <typename Char>
@ -553,7 +552,7 @@ void fmt::BasicWriter<Char>::write_str(
}
template <typename Char>
inline const typename fmt::BasicWriter<Char>::Arg
inline const Arg
&fmt::BasicWriter<Char>::FormatParser::ParseArgIndex(const Char *&s) {
unsigned arg_index = 0;
if (*s < '0' || *s > '9') {
@ -571,7 +570,7 @@ inline const typename fmt::BasicWriter<Char>::Arg
}
next_arg_index_ = -1;
const char *error = 0;
arg_index = internal::ParseNonnegativeInt(s, error);
arg_index = ParseNonnegativeInt(s, error);
if (error)
report_error_(s, error); // TODO
}
@ -630,7 +629,7 @@ unsigned fmt::internal::PrintfParser<Char>::ParseHeader(
if (c >= '0' && c <= '9') {
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
unsigned value = internal::ParseNonnegativeInt(s, error);
unsigned value = ParseNonnegativeInt(s, error);
if (*s == '$') { // value is an argument index
++s;
arg_index = value;
@ -648,7 +647,7 @@ unsigned fmt::internal::PrintfParser<Char>::ParseHeader(
ParseFlags(spec, s);
// Parse width.
if (*s >= '0' && *s <= '9') {
spec.width_ = internal::ParseNonnegativeInt(s, error);
spec.width_ = ParseNonnegativeInt(s, error);
} else if (*s == '*') {
++s;
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
template <typename Char>
const fmt::internal::ArgInfo
&fmt::internal::PrintfParser<Char>::HandleArgIndex(
const Arg &fmt::internal::PrintfParser<Char>::HandleArgIndex(
unsigned arg_index, const char *&error) {
if (arg_index != UINT_MAX) {
if (next_arg_index_ <= 0) {
@ -751,7 +749,7 @@ void fmt::internal::PrintfParser<Char>::Format(
if (*s == '.') {
++s;
if ('0' <= *s && *s <= '9') {
spec.precision_ = internal::ParseNonnegativeInt(s, error);
spec.precision_ = ParseNonnegativeInt(s, error);
} else if (*s == '*') {
++s;
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
// 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)
report_error_(s, error);
}
@ -967,7 +965,7 @@ void fmt::BasicWriter<Char>::FormatParser::Format(
++s;
spec.precision_ = 0;
if ('0' <= *s && *s <= '9') {
spec.precision_ = internal::ParseNonnegativeInt(s, error);
spec.precision_ = ParseNonnegativeInt(s, error);
if (error)
report_error_(s, error);
} else if (*s == '{') {

View File

@ -562,12 +562,6 @@ struct FormatErrorReporter {
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
// allocating an array of 0 size.
template <unsigned Arg>
@ -580,9 +574,8 @@ struct NonZero<0> {
enum { VALUE = 1 };
};
// Information about a format argument. It is a POD type to allow
// storage in internal::Array.
struct ArgInfo {
// A formatting argument. It is a POD type to allow storage in internal::Array.
struct Arg {
enum Type {
// Integer types should go first,
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>
class MakeArg : public internal::ArgInfo {
class MakeArg : public Arg {
private:
// 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!
@ -629,8 +622,6 @@ class MakeArg : public internal::ArgInfo {
MakeArg(T *value);
public:
using internal::ArgInfo::type;
MakeArg() {}
// TODO: unsigned char & signed char
MakeArg(short value) { type = INT; int_value = value; }
@ -718,12 +709,12 @@ class RuntimeError : public std::runtime_error {
*/
class ArgList {
private:
const internal::ArgInfo *args_;
const internal::Arg *args_;
std::size_t size_;
public:
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) {}
/**
@ -734,7 +725,7 @@ class ArgList {
/**
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];
}
};
@ -747,15 +738,13 @@ class PrintfParser {
ArgList args_;
int next_arg_index_;
typedef ArgInfo Arg;
void ParseFlags(FormatSpec &spec, const Char *&s);
// Parses argument index, flags and width and returns the parsed
// argument index.
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:
void Format(BasicWriter<Char> &writer,
@ -1012,7 +1001,8 @@ inline StrFormatSpec<wchar_t> pad(
# define FMT_VARIADIC_VOID(func, arg_type) \
template<typename... 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)... \
}; \
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) \
template<typename... 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)... \
}; \
func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \
@ -1036,7 +1027,7 @@ inline StrFormatSpec<wchar_t> pad(
# define FMT_WRAP1(func, arg_type, n) \
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_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))); \
}
@ -1051,7 +1042,7 @@ inline StrFormatSpec<wchar_t> pad(
# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
template <FMT_GEN(n, FMT_MAKE_TEMPLATE_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))); \
}
@ -1165,8 +1156,6 @@ class BasicWriter {
typedef typename internal::CharTraits<Char>::CharPtr CharPtr;
typedef internal::ArgInfo Arg;
#if _SECURE_SCL
static Char *GetBase(CharPtr p) { return p.base(); }
#else
@ -1228,9 +1217,9 @@ class BasicWriter {
fmt::internal::FormatErrorReporter<Char> report_error_;
// 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:
void Format(BasicWriter<Char> &writer,
@ -1834,8 +1823,8 @@ inline void FormatDec(char *&buffer, T value) {
template<typename... Args> \
ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
const Args & ... args) { \
enum {N = fmt::internal::NonZero<sizeof...(Args)>::VALUE}; \
const fmt::internal::ArgInfo array[N] = { \
using fmt::internal::Arg; \
const Arg array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
fmt::internal::MakeArg<Char>(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)> \
inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
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__), \
fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
}