Implement string padding.

This commit is contained in:
Victor Zverovich 2013-12-31 09:43:32 -08:00
parent fb7b11ead0
commit 641df95491
3 changed files with 57 additions and 17 deletions

View File

@ -583,22 +583,22 @@ void fmt::BasicFormatter<Char>::DoFormat() {
// Format argument.
switch (arg.type) {
case INT:
writer.FormatInt(arg.int_value, spec);
FormatInt(arg.int_value, spec);
break;
case UINT:
writer.FormatInt(arg.uint_value, spec);
FormatInt(arg.uint_value, spec);
break;
case LONG:
writer.FormatInt(arg.long_value, spec);
FormatInt(arg.long_value, spec);
break;
case ULONG:
writer.FormatInt(arg.ulong_value, spec);
FormatInt(arg.ulong_value, spec);
break;
case LONG_LONG:
writer.FormatInt(arg.long_long_value, spec);
FormatInt(arg.long_long_value, spec);
break;
case ULONG_LONG:
writer.FormatInt(arg.ulong_long_value, spec);
FormatInt(arg.ulong_long_value, spec);
break;
case DOUBLE:
writer.FormatDouble(arg.double_value, spec, precision);
@ -647,7 +647,7 @@ void fmt::BasicFormatter<Char>::DoFormat() {
internal::ReportUnknownType(spec.type_, "pointer");
spec.flags_= HASH_FLAG;
spec.type_ = 'x';
writer.FormatInt(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
FormatInt(reinterpret_cast<uintptr_t>(arg.pointer_value), spec);
break;
case CUSTOM:
if (spec.type_)

View File

@ -397,6 +397,18 @@ class IntFormatter : public SpecT {
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.
*/
@ -422,7 +434,7 @@ IntFormatter<int, TypeSpec<'X'> > hexu(int value);
/**
\rst
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**::
@ -473,6 +485,23 @@ DEFINE_INT_FORMATTERS(unsigned long)
DEFINE_INT_FORMATTERS(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>
class BasicFormatter;
@ -547,19 +576,13 @@ class BasicWriter {
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).
template <typename T>
void FormatDouble(T value, const FormatSpec &spec, int precision);
template <typename StringChar>
CharPtr FormatString(const StringChar *s,
std::size_t size, const FormatSpec &spec);
CharPtr FormatString(
const StringChar *s, std::size_t size, const AlignSpec &spec);
// 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
@ -680,6 +703,13 @@ class BasicWriter {
template <typename T, typename Spec>
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) {
FormatString(s.data(), s.size(), spec);
}
@ -692,7 +722,7 @@ class BasicWriter {
template <typename Char>
template <typename StringChar>
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();
if (spec.width() > size) {
out = GrowBuffer(spec.width());
@ -987,6 +1017,12 @@ class BasicFormatter {
// writing the output to writer_.
void DoFormat();
// Formats an integer.
template <typename T>
void FormatInt(T value, const FormatSpec &spec) {
*writer_ << IntFormatter<T, FormatSpec>(value, spec);
}
struct Proxy {
BasicWriter<Char> *writer;
const Char *format;

View File

@ -442,6 +442,10 @@ TEST(WriterTest, pad) {
EXPECT_EQ("2012-01-09", f.str());
}
TEST(WriterTest, PadString) {
EXPECT_EQ("test ", str(Writer() << pad("test", 8)));
}
TEST(WriterTest, NoConflictWithIOManip) {
using namespace std;
using namespace fmt;