mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Implement right alignment.
This commit is contained in:
58
format.cc
58
format.cc
@ -119,15 +119,15 @@ char *Formatter::PrepareFilledBuffer(
|
|||||||
*p = sign;
|
*p = sign;
|
||||||
p += size;
|
p += size;
|
||||||
std::fill(p, end, spec.fill);
|
std::fill(p, end, spec.fill);
|
||||||
} else if (spec.align == ALIGN_NUMERIC) {
|
|
||||||
if (sign) {
|
|
||||||
*p++ = sign;
|
|
||||||
--size;
|
|
||||||
}
|
|
||||||
std::fill(p, end - size, spec.fill);
|
|
||||||
p = end;
|
|
||||||
} else {
|
} else {
|
||||||
*(end - size) = sign;
|
if (spec.align == ALIGN_NUMERIC) {
|
||||||
|
if (sign) {
|
||||||
|
*p++ = sign;
|
||||||
|
--size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*(end - size) = sign;
|
||||||
|
}
|
||||||
std::fill(p, end - size, spec.fill);
|
std::fill(p, end - size, spec.fill);
|
||||||
p = end;
|
p = end;
|
||||||
}
|
}
|
||||||
@ -270,6 +270,21 @@ void Formatter::FormatDouble(T value, const FormatSpec &spec, int precision) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Formatter::FormatString(
|
||||||
|
const char *s, std::size_t size, const FormatSpec &spec) {
|
||||||
|
char *out = 0;
|
||||||
|
if (spec.width > size) {
|
||||||
|
out = GrowBuffer(spec.width);
|
||||||
|
if (spec.align == ALIGN_RIGHT)
|
||||||
|
out = std::fill_n(out, spec.width - size, spec.fill);
|
||||||
|
else
|
||||||
|
std::fill_n(out + size, spec.width - size, spec.fill);
|
||||||
|
} else {
|
||||||
|
out = GrowBuffer(size);
|
||||||
|
}
|
||||||
|
std::copy(s, s + size, out);
|
||||||
|
}
|
||||||
|
|
||||||
// Parses an unsigned integer advancing s to the end of the parsed input.
|
// 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.
|
// This function assumes that the first character of s is a digit.
|
||||||
unsigned Formatter::ParseUInt(const char *&s) const {
|
unsigned Formatter::ParseUInt(const char *&s) const {
|
||||||
@ -455,10 +470,17 @@ void Formatter::DoFormat() {
|
|||||||
case CHAR: {
|
case CHAR: {
|
||||||
if (spec.type && spec.type != 'c')
|
if (spec.type && spec.type != 'c')
|
||||||
ReportUnknownType(spec.type, "char");
|
ReportUnknownType(spec.type, "char");
|
||||||
char *out = GrowBuffer(std::max(spec.width, 1u));
|
char *out = 0;
|
||||||
*out++ = arg.int_value;
|
if (spec.width > 1) {
|
||||||
if (spec.width > 1)
|
out = GrowBuffer(spec.width);
|
||||||
std::fill_n(out, spec.width - 1, spec.fill);
|
if (spec.align == ALIGN_RIGHT)
|
||||||
|
out = std::fill_n(out, spec.width - 1, spec.fill);
|
||||||
|
else
|
||||||
|
std::fill_n(out + 1, spec.width - 1, spec.fill);
|
||||||
|
} else {
|
||||||
|
out = GrowBuffer(1);
|
||||||
|
}
|
||||||
|
*out = arg.int_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STRING: {
|
case STRING: {
|
||||||
@ -472,10 +494,7 @@ void Formatter::DoFormat() {
|
|||||||
if (*str)
|
if (*str)
|
||||||
size = std::strlen(str);
|
size = std::strlen(str);
|
||||||
}
|
}
|
||||||
char *out = GrowBuffer(std::max<size_t>(spec.width, size));
|
FormatString(str, size, spec);
|
||||||
out = std::copy(str, str + size, out);
|
|
||||||
if (spec.width > size)
|
|
||||||
std::fill_n(out, spec.width - size, spec.fill);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case POINTER:
|
case POINTER:
|
||||||
@ -498,10 +517,3 @@ void Formatter::DoFormat() {
|
|||||||
buffer_.append(start, s + 1);
|
buffer_.append(start, s + 1);
|
||||||
buffer_.resize(buffer_.size() - 1); // Don't count the terminating zero.
|
buffer_.resize(buffer_.size() - 1); // Don't count the terminating zero.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Formatter::Write(const std::string &s, const FormatSpec &spec) {
|
|
||||||
char *out = GrowBuffer(std::max<std::size_t>(spec.width, s.size()));
|
|
||||||
std::copy(s.begin(), s.end(), out);
|
|
||||||
if (spec.width > s.size())
|
|
||||||
std::fill_n(out + s.size(), spec.width - s.size(), spec.fill);
|
|
||||||
}
|
|
||||||
|
8
format.h
8
format.h
@ -281,6 +281,8 @@ class Formatter {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FormatDouble(T value, const FormatSpec &spec, int precision);
|
void FormatDouble(T value, const FormatSpec &spec, int precision);
|
||||||
|
|
||||||
|
void FormatString(const char *s, std::size_t size, const FormatSpec &spec);
|
||||||
|
|
||||||
// Formats an argument of a custom type, such as a user-defined class.
|
// Formats an argument of a custom type, such as a user-defined class.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void FormatCustomArg(const void *arg, const FormatSpec &spec);
|
void FormatCustomArg(const void *arg, const FormatSpec &spec);
|
||||||
@ -323,10 +325,6 @@ class Formatter {
|
|||||||
const char *c_str() const { return &buffer_[0]; }
|
const char *c_str() const { return &buffer_[0]; }
|
||||||
|
|
||||||
std::string str() const { return std::string(&buffer_[0], buffer_.size()); }
|
std::string str() const { return std::string(&buffer_[0], buffer_.size()); }
|
||||||
|
|
||||||
// Writes a string to the output buffer padding with spaces if
|
|
||||||
// necessary to achieve the desired width.
|
|
||||||
void Write(const std::string &s, const FormatSpec &spec);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A reference to a string. It can be constructed from a C string,
|
// A reference to a string. It can be constructed from a C string,
|
||||||
@ -464,7 +462,7 @@ class ArgFormatter {
|
|||||||
explicit ArgFormatter(Formatter &f) : formatter_(f) {}
|
explicit ArgFormatter(Formatter &f) : formatter_(f) {}
|
||||||
|
|
||||||
void Write(const std::string &s, const FormatSpec &spec) {
|
void Write(const std::string &s, const FormatSpec &spec) {
|
||||||
formatter_.Write(s, spec);
|
formatter_.FormatString(s.data(), s.size(), spec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -276,6 +276,23 @@ TEST(FormatterTest, LeftAlign) {
|
|||||||
EXPECT_EQ("def ", str(Format("{0:<5}") << TestString("def")));
|
EXPECT_EQ("def ", str(Format("{0:<5}") << TestString("def")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatterTest, RightAlign) {
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0:>4}") << 42));
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0:>4o}") << 042));
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0:>4x}") << 0x42));
|
||||||
|
EXPECT_EQ(" -42", str(Format("{0:>5}") << -42));
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0:>5}") << 42u));
|
||||||
|
EXPECT_EQ(" -42", str(Format("{0:>5}") << -42l));
|
||||||
|
EXPECT_EQ(" 42", str(Format("{0:>5}") << 42ul));
|
||||||
|
EXPECT_EQ(" -42", str(Format("{0:>5}") << -42.0));
|
||||||
|
EXPECT_EQ(" -42", str(Format("{0:>5}") << -42.0l));
|
||||||
|
EXPECT_EQ(" c", str(Format("{0:>5}") << 'c'));
|
||||||
|
EXPECT_EQ(" abc", str(Format("{0:>5}") << "abc"));
|
||||||
|
EXPECT_EQ(" 0xface",
|
||||||
|
str(Format("{0:>8}") << reinterpret_cast<void*>(0xface)));
|
||||||
|
EXPECT_EQ(" def", str(Format("{0:>5}") << TestString("def")));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, Fill) {
|
TEST(FormatterTest, Fill) {
|
||||||
EXPECT_EQ("**42", str(Format("{0:*>4}") << 42));
|
EXPECT_EQ("**42", str(Format("{0:*>4}") << 42));
|
||||||
EXPECT_EQ("**-42", str(Format("{0:*>5}") << -42));
|
EXPECT_EQ("**-42", str(Format("{0:*>5}") << -42));
|
||||||
@ -662,20 +679,6 @@ TEST(FormatterTest, FormatString) {
|
|||||||
EXPECT_EQ("test", str(Format("{0}") << std::string("test")));
|
EXPECT_EQ("test", str(Format("{0}") << std::string("test")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, Write) {
|
|
||||||
Formatter format;
|
|
||||||
fmt::FormatSpec spec;
|
|
||||||
spec.width = 2;
|
|
||||||
format.Write("12", spec);
|
|
||||||
EXPECT_EQ("12", format.str());
|
|
||||||
spec.width = 4;
|
|
||||||
format.Write("34", spec);
|
|
||||||
EXPECT_EQ("1234 ", format.str());
|
|
||||||
spec.width = 0;
|
|
||||||
format.Write("56", spec);
|
|
||||||
EXPECT_EQ("1234 56", format.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ArgFormatterTest, Write) {
|
TEST(ArgFormatterTest, Write) {
|
||||||
Formatter formatter;
|
Formatter formatter;
|
||||||
fmt::ArgFormatter format(formatter);
|
fmt::ArgFormatter format(formatter);
|
||||||
|
Reference in New Issue
Block a user