Commit beb00edf authored by Victor Zverovich's avatar Victor Zverovich

Store types in ArgList instead of Arg

parent 49222dc0
...@@ -579,38 +579,38 @@ void fmt::BasicWriter<Char, Allocator>::write_str( ...@@ -579,38 +579,38 @@ void fmt::BasicWriter<Char, Allocator>::write_str(
} }
template <typename Char> template <typename Char>
inline const Arg &fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) { inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) {
const char *error = 0; const char *error = 0;
const Arg *arg = *s < '0' || *s > '9' ? Arg arg = *s < '0' || *s > '9' ?
next_arg(error) : get_arg(parse_nonnegative_int(s), error); next_arg(error) : get_arg(parse_nonnegative_int(s), error);
if (error) if (error)
throw FormatError(*s != '}' && *s != ':' ? "invalid format string" : error); throw FormatError(*s != '}' && *s != ':' ? "invalid format string" : error);
return *arg; return arg;
} }
const Arg *fmt::internal::FormatterBase::do_get_arg( Arg fmt::internal::FormatterBase::do_get_arg(
unsigned arg_index, const char *&error) { unsigned arg_index, const char *&error) {
if (arg_index < args_.size()) Arg arg = args_[arg_index];
return &args_[arg_index]; if (arg.type == Arg::NONE)
error = "argument index out of range"; error = "argument index out of range";
return 0; return arg;
} }
inline const Arg *fmt::internal::FormatterBase::next_arg(const char *&error) { inline Arg fmt::internal::FormatterBase::next_arg(const char *&error) {
if (next_arg_index_ >= 0) if (next_arg_index_ >= 0)
return do_get_arg(next_arg_index_++, error); return do_get_arg(next_arg_index_++, error);
error = "cannot switch from manual to automatic argument indexing"; error = "cannot switch from manual to automatic argument indexing";
return 0; return Arg();
} }
inline const Arg *fmt::internal::FormatterBase::get_arg( inline Arg fmt::internal::FormatterBase::get_arg(
unsigned arg_index, const char *&error) { unsigned arg_index, const char *&error) {
if (next_arg_index_ <= 0) { if (next_arg_index_ <= 0) {
next_arg_index_ = -1; next_arg_index_ = -1;
return do_get_arg(arg_index, error); return do_get_arg(arg_index, error);
} }
error = "cannot switch from automatic to manual argument indexing"; error = "cannot switch from automatic to manual argument indexing";
return 0; return Arg();
} }
template <typename Char> template <typename Char>
...@@ -641,14 +641,14 @@ void fmt::internal::PrintfFormatter<Char>::parse_flags( ...@@ -641,14 +641,14 @@ void fmt::internal::PrintfFormatter<Char>::parse_flags(
} }
template <typename Char> template <typename Char>
const Arg &fmt::internal::PrintfFormatter<Char>::get_arg( Arg fmt::internal::PrintfFormatter<Char>::get_arg(
const Char *s, unsigned arg_index) { const Char *s, unsigned arg_index) {
const char *error = 0; const char *error = 0;
const Arg *arg = arg_index == UINT_MAX ? Arg arg = arg_index == UINT_MAX ?
next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
if (error) if (error)
throw FormatError(!*s ? "invalid format string" : error); throw FormatError(!*s ? "invalid format string" : error);
return *arg; return arg;
} }
template <typename Char> template <typename Char>
......
This diff is collapsed.
...@@ -67,7 +67,7 @@ int result; ...@@ -67,7 +67,7 @@ int result;
#define MAKE_TEST(func) \ #define MAKE_TEST(func) \
void func(const char *format, const fmt::ArgList &args) { \ void func(const char *format, const fmt::ArgList &args) { \
result = 0; \ result = 0; \
for (std::size_t i = 0, n = args.size(); i < n; ++i) \ for (unsigned i = 0; args[i].type; ++i) \
result += args[i].int_value; \ result += args[i].int_value; \
} }
...@@ -98,7 +98,7 @@ struct S {}; ...@@ -98,7 +98,7 @@ struct S {};
int test_variadic(FMT_GEN(10, GET_TYPE), const fmt::ArgList &args) { \ int test_variadic(FMT_GEN(10, GET_TYPE), const fmt::ArgList &args) { \
int result = 0; \ int result = 0; \
for (std::size_t i = 0, n = args.size(); i < n; ++i) \ for (std::size_t i = 0; args[i].type; ++i) \
result += args[i].int_value; \ result += args[i].int_value; \
return result; return result;
} }
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
#undef max #undef max
using fmt::StringRef; using fmt::StringRef;
using fmt::internal::ArgBase;
using fmt::internal::Arg; using fmt::internal::Arg;
using fmt::internal::MakeArg;
namespace { namespace {
...@@ -52,6 +52,16 @@ template <typename Char> ...@@ -52,6 +52,16 @@ template <typename Char>
std::basic_ostream<Char> &operator<<(std::basic_ostream<Char> &os, Test) { std::basic_ostream<Char> &operator<<(std::basic_ostream<Char> &os, Test) {
return os << "test"; return os << "test";
} }
template <typename Char, typename T>
Arg make_arg(const T &value) {
Arg arg = Arg();
ArgBase &base = arg;
base = fmt::internal::MakeArg<Char>(value);
arg.type = static_cast<Arg::Type>(fmt::internal::ArgType<1, T>::TYPE);
return arg;
}
} // namespace } // namespace
TEST(UtilTest, Increment) { TEST(UtilTest, Increment) {
...@@ -74,7 +84,7 @@ struct ArgInfo; ...@@ -74,7 +84,7 @@ struct ArgInfo;
#define ARG_INFO(type_code, Type, field) \ #define ARG_INFO(type_code, Type, field) \
template <> \ template <> \
struct ArgInfo<Arg::type_code> { \ struct ArgInfo<Arg::type_code> { \
static Type get(const Arg &arg) { return arg.field; } \ static Type get(const ArgBase &arg) { return arg.field; } \
}; };
ARG_INFO(INT, int, int_value); ARG_INFO(INT, int, int_value);
...@@ -90,7 +100,7 @@ ARG_INFO(POINTER, const void *, pointer_value); ...@@ -90,7 +100,7 @@ ARG_INFO(POINTER, const void *, pointer_value);
ARG_INFO(CUSTOM, Arg::CustomValue, custom); ARG_INFO(CUSTOM, Arg::CustomValue, custom);
#define CHECK_ARG_INFO(Type, field, value) { \ #define CHECK_ARG_INFO(Type, field, value) { \
Arg arg = {Arg::Type}; \ ArgBase arg = {}; \
arg.field = value; \ arg.field = value; \
EXPECT_EQ(value, ArgInfo<Arg::Type>::get(arg)); \ EXPECT_EQ(value, ArgInfo<Arg::Type>::get(arg)); \
} }
...@@ -109,14 +119,14 @@ TEST(ArgTest, ArgInfo) { ...@@ -109,14 +119,14 @@ TEST(ArgTest, ArgInfo) {
CHECK_ARG_INFO(WSTRING, wstring.value, WSTR); CHECK_ARG_INFO(WSTRING, wstring.value, WSTR);
int p = 0; int p = 0;
CHECK_ARG_INFO(POINTER, pointer_value, &p); CHECK_ARG_INFO(POINTER, pointer_value, &p);
Arg arg = {Arg::CUSTOM}; ArgBase arg = {};
arg.custom.value = &p; arg.custom.value = &p;
EXPECT_EQ(&p, ArgInfo<Arg::CUSTOM>::get(arg).value); EXPECT_EQ(&p, ArgInfo<Arg::CUSTOM>::get(arg).value);
} }
#define EXPECT_ARG_(Char, type_code, MakeArgType, ExpectedType, value) { \ #define EXPECT_ARG_(Char, type_code, MakeArgType, ExpectedType, value) { \
MakeArgType input = static_cast<MakeArgType>(value); \ MakeArgType input = static_cast<MakeArgType>(value); \
Arg arg = MakeArg<Char>(input); \ Arg arg = make_arg<Char>(input); \
EXPECT_EQ(Arg::type_code, arg.type); \ EXPECT_EQ(Arg::type_code, arg.type); \
ExpectedType expected_value = static_cast<ExpectedType>(value); \ ExpectedType expected_value = static_cast<ExpectedType>(value); \
EXPECT_EQ(expected_value, ArgInfo<Arg::type_code>::get(arg)); \ EXPECT_EQ(expected_value, ArgInfo<Arg::type_code>::get(arg)); \
...@@ -221,7 +231,7 @@ TEST(ArgTest, MakeArg) { ...@@ -221,7 +231,7 @@ TEST(ArgTest, MakeArg) {
EXPECT_ARG(POINTER, const void*, &n); EXPECT_ARG(POINTER, const void*, &n);
::Test t; ::Test t;
fmt::internal::Arg arg = MakeArg<char>(t); Arg arg = make_arg<char>(t);
EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type); EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type);
EXPECT_EQ(&t, arg.custom.value); EXPECT_EQ(&t, arg.custom.value);
fmt::Writer w; fmt::Writer w;
...@@ -232,13 +242,13 @@ TEST(ArgTest, MakeArg) { ...@@ -232,13 +242,13 @@ TEST(ArgTest, MakeArg) {
} }
struct Result { struct Result {
fmt::internal::Arg arg; Arg arg;
Result() : arg(MakeArg<char>(0xdeadbeef)) {} Result() : arg(make_arg<char>(0xdeadbeef)) {}
template <typename T> template <typename T>
Result(const T& value) : arg(MakeArg<char>(value)) {} Result(const T& value) : arg(make_arg<char>(value)) {}
Result(const wchar_t *s) : arg(MakeArg<wchar_t>(s)) {} Result(const wchar_t *s) : arg(make_arg<wchar_t>(s)) {}
}; };
struct TestVisitor : fmt::internal::ArgVisitor<TestVisitor, Result> { struct TestVisitor : fmt::internal::ArgVisitor<TestVisitor, Result> {
...@@ -258,7 +268,8 @@ struct TestVisitor : fmt::internal::ArgVisitor<TestVisitor, Result> { ...@@ -258,7 +268,8 @@ struct TestVisitor : fmt::internal::ArgVisitor<TestVisitor, Result> {
}; };
#define EXPECT_RESULT_(Char, type_code, value) { \ #define EXPECT_RESULT_(Char, type_code, value) { \
Result result = TestVisitor().visit(MakeArg<Char>(value)); \ Arg arg = make_arg<Char>(value); \
Result result = TestVisitor().visit(arg); \
EXPECT_EQ(Arg::type_code, result.arg.type); \ EXPECT_EQ(Arg::type_code, result.arg.type); \
EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \ EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
} }
...@@ -283,7 +294,7 @@ TEST(ArgVisitorTest, VisitAll) { ...@@ -283,7 +294,7 @@ TEST(ArgVisitorTest, VisitAll) {
const void *p = STR; const void *p = STR;
EXPECT_RESULT(POINTER, p); EXPECT_RESULT(POINTER, p);
::Test t; ::Test t;
Result result = TestVisitor().visit(MakeArg<char>(t)); Result result = TestVisitor().visit(make_arg<char>(t));
EXPECT_EQ(Arg::CUSTOM, result.arg.type); EXPECT_EQ(Arg::CUSTOM, result.arg.type);
EXPECT_EQ(&t, result.arg.custom.value); EXPECT_EQ(&t, result.arg.custom.value);
} }
...@@ -298,7 +309,7 @@ struct TestAnyVisitor : fmt::internal::ArgVisitor<TestAnyVisitor, Result> { ...@@ -298,7 +309,7 @@ struct TestAnyVisitor : fmt::internal::ArgVisitor<TestAnyVisitor, Result> {
#undef EXPECT_RESULT #undef EXPECT_RESULT
#define EXPECT_RESULT(type_code, value) { \ #define EXPECT_RESULT(type_code, value) { \
Result result = TestAnyVisitor().visit(MakeArg<char>(value)); \ Result result = TestAnyVisitor().visit(make_arg<char>(value)); \
EXPECT_EQ(Arg::type_code, result.arg.type); \ EXPECT_EQ(Arg::type_code, result.arg.type); \
EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \ EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
} }
...@@ -318,7 +329,7 @@ struct TestUnhandledVisitor : ...@@ -318,7 +329,7 @@ struct TestUnhandledVisitor :
}; };
#define EXPECT_UNHANDLED(value) \ #define EXPECT_UNHANDLED(value) \
EXPECT_STREQ("test", TestUnhandledVisitor().visit(MakeArg<wchar_t>(value))); EXPECT_STREQ("test", TestUnhandledVisitor().visit(make_arg<wchar_t>(value)));
TEST(ArgVisitorTest, VisitUnhandledArg) { TEST(ArgVisitorTest, VisitUnhandledArg) {
EXPECT_UNHANDLED(42); EXPECT_UNHANDLED(42);
...@@ -338,7 +349,8 @@ TEST(ArgVisitorTest, VisitUnhandledArg) { ...@@ -338,7 +349,8 @@ TEST(ArgVisitorTest, VisitUnhandledArg) {
} }
TEST(ArgVisitorTest, VisitInvalidArg) { TEST(ArgVisitorTest, VisitInvalidArg) {
Arg arg = {static_cast<Arg::Type>(Arg::CUSTOM + 1)}; Arg arg = Arg();
arg.type = static_cast<Arg::Type>(Arg::CUSTOM + 1);
EXPECT_DEBUG_DEATH(TestVisitor().visit(arg), "Assertion"); EXPECT_DEBUG_DEATH(TestVisitor().visit(arg), "Assertion");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment