forked from fmtlib/fmt
Implement string padding.
This commit is contained in:
14
format.cc
14
format.cc
@@ -583,22 +583,22 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
// Format argument.
|
// Format argument.
|
||||||
switch (arg.type) {
|
switch (arg.type) {
|
||||||
case INT:
|
case INT:
|
||||||
writer.FormatInt(arg.int_value, spec);
|
FormatInt(arg.int_value, spec);
|
||||||
break;
|
break;
|
||||||
case UINT:
|
case UINT:
|
||||||
writer.FormatInt(arg.uint_value, spec);
|
FormatInt(arg.uint_value, spec);
|
||||||
break;
|
break;
|
||||||
case LONG:
|
case LONG:
|
||||||
writer.FormatInt(arg.long_value, spec);
|
FormatInt(arg.long_value, spec);
|
||||||
break;
|
break;
|
||||||
case ULONG:
|
case ULONG:
|
||||||
writer.FormatInt(arg.ulong_value, spec);
|
FormatInt(arg.ulong_value, spec);
|
||||||
break;
|
break;
|
||||||
case LONG_LONG:
|
case LONG_LONG:
|
||||||
writer.FormatInt(arg.long_long_value, spec);
|
FormatInt(arg.long_long_value, spec);
|
||||||
break;
|
break;
|
||||||
case ULONG_LONG:
|
case ULONG_LONG:
|
||||||
writer.FormatInt(arg.ulong_long_value, spec);
|
FormatInt(arg.ulong_long_value, spec);
|
||||||
break;
|
break;
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
writer.FormatDouble(arg.double_value, spec, precision);
|
writer.FormatDouble(arg.double_value, spec, precision);
|
||||||
@@ -647,7 +647,7 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
internal::ReportUnknownType(spec.type_, "pointer");
|
internal::ReportUnknownType(spec.type_, "pointer");
|
||||||
spec.flags_= HASH_FLAG;
|
spec.flags_= HASH_FLAG;
|
||||||
spec.type_ = 'x';
|
spec.type_ = 'x';
|
||||||
writer.FormatInt(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
|
FormatInt(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
|
||||||
break;
|
break;
|
||||||
case CUSTOM:
|
case CUSTOM:
|
||||||
if (spec.type_)
|
if (spec.type_)
|
||||||
|
56
format.h
56
format.h
@@ -397,6 +397,18 @@ class IntFormatter : public SpecT {
|
|||||||
T value() const { return value_; }
|
T value() const { return value_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class StrFormatter : public AlignSpec {
|
||||||
|
private:
|
||||||
|
const T *str_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StrFormatter(const T *str, const AlignSpec &spec = AlignSpec())
|
||||||
|
: AlignSpec(spec), str_(str) {}
|
||||||
|
|
||||||
|
const T *str() const { return str_; }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns an integer formatter that formats the value in base 2.
|
Returns an integer formatter that formats the value in base 2.
|
||||||
*/
|
*/
|
||||||
@@ -422,7 +434,7 @@ IntFormatter<int, TypeSpec<'X'> > hexu(int value);
|
|||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Returns an integer formatter that pads the formatted argument with the fill
|
Returns an integer formatter that pads the formatted argument with the fill
|
||||||
character to the specified width using the default (right) alignment.
|
character to the specified width using the default (right) numeric alignment.
|
||||||
|
|
||||||
**Example**::
|
**Example**::
|
||||||
|
|
||||||
@@ -473,6 +485,23 @@ DEFINE_INT_FORMATTERS(unsigned long)
|
|||||||
DEFINE_INT_FORMATTERS(long long)
|
DEFINE_INT_FORMATTERS(long long)
|
||||||
DEFINE_INT_FORMATTERS(unsigned long long)
|
DEFINE_INT_FORMATTERS(unsigned long long)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Returns a string formatter that pads the formatted argument with the fill
|
||||||
|
character to the specified width using the default (left) string alignment.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
std::string s = str(Writer() << pad("abc", 8));
|
||||||
|
// s == "abc "
|
||||||
|
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
inline StrFormatter<char> pad(
|
||||||
|
const char *str, unsigned width, wchar_t fill = ' ') {
|
||||||
|
return StrFormatter<char>(str, AlignSpec(width, fill));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class BasicFormatter;
|
class BasicFormatter;
|
||||||
|
|
||||||
@@ -547,19 +576,13 @@ class BasicWriter {
|
|||||||
|
|
||||||
CharPtr PrepareFilledBuffer(unsigned size, const AlignSpec &spec, char sign);
|
CharPtr PrepareFilledBuffer(unsigned size, const AlignSpec &spec, char sign);
|
||||||
|
|
||||||
// Formats an integer.
|
|
||||||
template <typename T>
|
|
||||||
void FormatInt(T value, const FormatSpec &spec) {
|
|
||||||
*this << IntFormatter<T, FormatSpec>(value, spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Formats a floating-point number (double or long double).
|
// Formats a floating-point number (double or long double).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void FormatDouble(T value, const FormatSpec &spec, int precision);
|
void FormatDouble(T value, const FormatSpec &spec, int precision);
|
||||||
|
|
||||||
template <typename StringChar>
|
template <typename StringChar>
|
||||||
CharPtr FormatString(const StringChar *s,
|
CharPtr FormatString(
|
||||||
std::size_t size, const FormatSpec &spec);
|
const StringChar *s, std::size_t size, const AlignSpec &spec);
|
||||||
|
|
||||||
// This method is private to disallow writing a wide string to a
|
// This method is private to disallow writing a wide string to a
|
||||||
// char stream and vice versa. If you want to print a wide string
|
// char stream and vice versa. If you want to print a wide string
|
||||||
@@ -680,6 +703,13 @@ class BasicWriter {
|
|||||||
template <typename T, typename Spec>
|
template <typename T, typename Spec>
|
||||||
BasicWriter &operator<<(const IntFormatter<T, Spec> &f);
|
BasicWriter &operator<<(const IntFormatter<T, Spec> &f);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
BasicWriter &operator<<(const StrFormatter<T> &f) {
|
||||||
|
const char *s = f.str();
|
||||||
|
FormatString(s, std::strlen(s), f);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void Write(const std::basic_string<char> &s, const FormatSpec &spec) {
|
void Write(const std::basic_string<char> &s, const FormatSpec &spec) {
|
||||||
FormatString(s.data(), s.size(), spec);
|
FormatString(s.data(), s.size(), spec);
|
||||||
}
|
}
|
||||||
@@ -692,7 +722,7 @@ class BasicWriter {
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
template <typename StringChar>
|
template <typename StringChar>
|
||||||
typename BasicWriter<Char>::CharPtr BasicWriter<Char>::FormatString(
|
typename BasicWriter<Char>::CharPtr BasicWriter<Char>::FormatString(
|
||||||
const StringChar *s, std::size_t size, const FormatSpec &spec) {
|
const StringChar *s, std::size_t size, const AlignSpec &spec) {
|
||||||
CharPtr out = CharPtr();
|
CharPtr out = CharPtr();
|
||||||
if (spec.width() > size) {
|
if (spec.width() > size) {
|
||||||
out = GrowBuffer(spec.width());
|
out = GrowBuffer(spec.width());
|
||||||
@@ -987,6 +1017,12 @@ class BasicFormatter {
|
|||||||
// writing the output to writer_.
|
// writing the output to writer_.
|
||||||
void DoFormat();
|
void DoFormat();
|
||||||
|
|
||||||
|
// Formats an integer.
|
||||||
|
template <typename T>
|
||||||
|
void FormatInt(T value, const FormatSpec &spec) {
|
||||||
|
*writer_ << IntFormatter<T, FormatSpec>(value, spec);
|
||||||
|
}
|
||||||
|
|
||||||
struct Proxy {
|
struct Proxy {
|
||||||
BasicWriter<Char> *writer;
|
BasicWriter<Char> *writer;
|
||||||
const Char *format;
|
const Char *format;
|
||||||
|
@@ -442,6 +442,10 @@ TEST(WriterTest, pad) {
|
|||||||
EXPECT_EQ("2012-01-09", f.str());
|
EXPECT_EQ("2012-01-09", f.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(WriterTest, PadString) {
|
||||||
|
EXPECT_EQ("test ", str(Writer() << pad("test", 8)));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(WriterTest, NoConflictWithIOManip) {
|
TEST(WriterTest, NoConflictWithIOManip) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
|
Reference in New Issue
Block a user