ArgBase -> Value

This commit is contained in:
Victor Zverovich
2014-09-23 08:11:03 -07:00
parent beb00edf73
commit d2973766ea
2 changed files with 38 additions and 39 deletions

View File

@ -607,8 +607,9 @@ struct NonZero<0> {
enum { VALUE = 1 }; enum { VALUE = 1 };
}; };
// A formatting argument. It is a POD type to allow storage in internal::Array. // The value of a formatting argument. It is a POD type to allow storage in
struct ArgBase { // internal::Array.
struct Value {
template <typename Char> template <typename Char>
struct StringValue { struct StringValue {
const Char *value; const Char *value;
@ -637,7 +638,7 @@ struct ArgBase {
}; };
}; };
struct Arg : public ArgBase { struct Arg : Value {
enum Type { enum Type {
NONE, NONE,
// Integer types should go first, // Integer types should go first,
@ -728,7 +729,7 @@ FMT_ARG_TYPE(void*, POINTER);
// Makes an Arg object from any type. // Makes an Arg object from any type.
template <typename Char> template <typename Char>
class MakeArg : public ArgBase { class MakeArg : public Value {
private: private:
// The following two methods are private to disallow formatting of // The following two methods are private to disallow formatting of
// arbitrary pointers. If you want to output a pointer cast it to // arbitrary pointers. If you want to output a pointer cast it to
@ -929,31 +930,31 @@ class ArgFormatter;
class ArgList { class ArgList {
private: private:
fmt::ULongLong types_; fmt::ULongLong types_;
const internal::ArgBase *args_; const internal::Value *values_;
public: public:
// Maximum number of arguments that can be passed in ArgList. // Maximum number of arguments that can be passed in ArgList.
enum { MAX_ARGS = 16 }; enum { MAX_ARGS = 16 };
ArgList() : types_(0) {} ArgList() : types_(0) {}
ArgList(fmt::ULongLong types, const internal::ArgBase *args) ArgList(fmt::ULongLong types, const internal::Value *values)
: types_(types), args_(args) {} : types_(types), values_(values) {}
/** /**
Returns the argument at specified index. Returns the argument at specified index.
*/ */
internal::Arg operator[](unsigned index) const { internal::Arg operator[](unsigned index) const {
if (index >= MAX_ARGS)
return internal::Arg();
fmt::ULongLong shift = index * 4;
using internal::Arg; using internal::Arg;
if (index >= MAX_ARGS)
return Arg();
fmt::ULongLong shift = index * 4;
Arg::Type type = Arg::Type type =
static_cast<Arg::Type>((types_ & (0xfull << shift)) >> shift); static_cast<Arg::Type>((types_ & (0xfull << shift)) >> shift);
Arg arg; Arg arg;
arg.type = type; arg.type = type;
if (type != Arg::NONE) { if (type != Arg::NONE) {
internal::ArgBase &base = arg; internal::Value &value = arg;
base = args_[index]; value = values_[index];
} }
return arg; return arg;
} }
@ -1302,24 +1303,22 @@ FMT_ARG_TYPE(15, 14);
# 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 fmt::internal::ArgBase arg_array[ \ const fmt::internal::Value values[ \
fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
fmt::internal::MakeArg<Char>(args)... \ fmt::internal::MakeArg<Char>(args)... \
}; \ }; \
func(arg1, ArgList( \ func(arg1, ArgList(internal::ArgType<15, Args...>::TYPE, values)); \
internal::ArgType<15, Args...>::TYPE, arg_array)); \
} }
// Defines a variadic constructor. // Defines a variadic constructor.
# 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 fmt::internal::ArgBase arg_array[ \ const fmt::internal::Value values[ \
fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \
fmt::internal::MakeArg<Char>(args)... \ fmt::internal::MakeArg<Char>(args)... \
}; \ }; \
func(arg0, arg1, ArgList( \ func(arg0, arg1, ArgList(internal::ArgType<15, Args...>::TYPE, values)); \
internal::ArgType<15, Args...>::TYPE, arg_array)); \
} }
#else #else
@ -1330,9 +1329,9 @@ FMT_ARG_TYPE(15, 14);
# 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::ArgBase args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ const fmt::internal::Value vals[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
func(arg1, fmt::ArgList( \ func(arg1, fmt::ArgList( \
fmt::internal::ArgType<n, FMT_GEN(n, FMT_MAKE_ARG_TYPE)>::TYPE, args)); \ fmt::internal::ArgType<n, FMT_GEN(n, FMT_MAKE_ARG_TYPE)>::TYPE, vals)); \
} }
// Emulates a variadic function returning void on a pre-C++11 compiler. // Emulates a variadic function returning void on a pre-C++11 compiler.
@ -1346,9 +1345,9 @@ FMT_ARG_TYPE(15, 14);
# 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::ArgBase args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ const fmt::internal::Value vals[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
func(arg0, arg1, fmt::ArgList( \ func(arg0, arg1, fmt::ArgList( \
internal::ArgType<n, FMT_GEN(n, FMT_MAKE_ARG_TYPE)>::TYPE, args)); \ fmt::internal::ArgType<n, FMT_GEN(n, FMT_MAKE_ARG_TYPE)>::TYPE, vals)); \
} }
// Emulates a variadic constructor on a pre-C++11 compiler. // Emulates a variadic constructor on a pre-C++11 compiler.
@ -2022,8 +2021,8 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
std::basic_ostringstream<Char> os; std::basic_ostringstream<Char> os;
os << value; os << value;
internal::Arg arg; internal::Arg arg;
internal::ArgBase &base = arg; internal::Value &arg_value = arg;
base = internal::MakeArg<Char>(os.str()); arg_value = internal::MakeArg<Char>(os.str());
arg.type = internal::Arg::STRING; arg.type = internal::Arg::STRING;
format_str = f.format(format_str, arg); format_str = f.format(format_str, arg);
} }
@ -2308,12 +2307,12 @@ inline void format_decimal(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) { \
using fmt::internal::ArgBase; \ using fmt::internal::Value; \
const ArgBase array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ const Value values[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__), fmt::ArgList( \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
fmt::internal::ArgType<15, Args...>::TYPE, array)); \ fmt::internal::ArgType<15, Args...>::TYPE, values)); \
} }
#else #else
// Defines a wrapper for a function taking __VA_ARGS__ arguments // Defines a wrapper for a function taking __VA_ARGS__ arguments
@ -2322,9 +2321,9 @@ inline void format_decimal(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::ArgBase args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ const fmt::internal::Value vals[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \
fmt::internal::ArgType<n, FMT_GEN(n, FMT_MAKE_ARG_TYPE)>::TYPE, args)); \ fmt::internal::ArgType<n, FMT_GEN(n, FMT_MAKE_ARG_TYPE)>::TYPE, vals)); \
} }
# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \

View File

@ -42,7 +42,7 @@
#undef max #undef max
using fmt::StringRef; using fmt::StringRef;
using fmt::internal::ArgBase; using fmt::internal::Value;
using fmt::internal::Arg; using fmt::internal::Arg;
namespace { namespace {
@ -56,8 +56,8 @@ std::basic_ostream<Char> &operator<<(std::basic_ostream<Char> &os, Test) {
template <typename Char, typename T> template <typename Char, typename T>
Arg make_arg(const T &value) { Arg make_arg(const T &value) {
Arg arg = Arg(); Arg arg = Arg();
ArgBase &base = arg; Value &arg_value = arg;
base = fmt::internal::MakeArg<Char>(value); arg_value = fmt::internal::MakeArg<Char>(value);
arg.type = static_cast<Arg::Type>(fmt::internal::ArgType<1, T>::TYPE); arg.type = static_cast<Arg::Type>(fmt::internal::ArgType<1, T>::TYPE);
return arg; return arg;
} }
@ -84,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 ArgBase &arg) { return arg.field; } \ static Type get(const Value &value) { return value.field; } \
}; };
ARG_INFO(INT, int, int_value); ARG_INFO(INT, int, int_value);
@ -100,9 +100,9 @@ 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) { \
ArgBase arg = {}; \ Value arg_value = {}; \
arg.field = value; \ arg_value.field = value; \
EXPECT_EQ(value, ArgInfo<Arg::Type>::get(arg)); \ EXPECT_EQ(value, ArgInfo<Arg::Type>::get(arg_value)); \
} }
TEST(ArgTest, ArgInfo) { TEST(ArgTest, ArgInfo) {
@ -119,9 +119,9 @@ 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);
ArgBase arg = {}; Value value = {};
arg.custom.value = &p; value.custom.value = &p;
EXPECT_EQ(&p, ArgInfo<Arg::CUSTOM>::get(arg).value); EXPECT_EQ(&p, ArgInfo<Arg::CUSTOM>::get(value).value);
} }
#define EXPECT_ARG_(Char, type_code, MakeArgType, ExpectedType, value) { \ #define EXPECT_ARG_(Char, type_code, MakeArgType, ExpectedType, value) { \