mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-26 09:28:21 +00:00
Use named argument emulation instead of nested functions
This commit is contained in:
parent
ec15ef7b7b
commit
8485027710
103
fmt/format.h
103
fmt/format.h
@ -1639,6 +1639,52 @@ enum {
|
|||||||
CHAR_FLAG = 0x10 // Argument has char type - used in error reporting.
|
CHAR_FLAG = 0x10 // Argument has char type - used in error reporting.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum format_spec_tag {fill_tag, align_tag, width_tag, type_tag};
|
||||||
|
|
||||||
|
// Format specifier.
|
||||||
|
template <typename T, format_spec_tag>
|
||||||
|
class format_spec {
|
||||||
|
private:
|
||||||
|
T value_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
explicit format_spec(T value) : value_(value) {}
|
||||||
|
|
||||||
|
T value() const { return value_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
using fill_spec = format_spec<Char, fill_tag>;
|
||||||
|
|
||||||
|
using width_spec = format_spec<unsigned, width_tag>;
|
||||||
|
using type_spec = format_spec<char, type_tag>;
|
||||||
|
|
||||||
|
class fill_spec_factory {
|
||||||
|
public:
|
||||||
|
constexpr fill_spec_factory() {}
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
fill_spec<Char> operator=(Char value) const {
|
||||||
|
return fill_spec<Char>(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FormatSpec>
|
||||||
|
class format_spec_factory {
|
||||||
|
public:
|
||||||
|
constexpr format_spec_factory() {}
|
||||||
|
|
||||||
|
FormatSpec operator=(typename FormatSpec::value_type value) const {
|
||||||
|
return FormatSpec(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr fill_spec_factory fill;
|
||||||
|
constexpr format_spec_factory<width_spec> width;
|
||||||
|
constexpr format_spec_factory<type_spec> type;
|
||||||
|
|
||||||
// An empty format specifier.
|
// An empty format specifier.
|
||||||
struct EmptySpec {};
|
struct EmptySpec {};
|
||||||
|
|
||||||
@ -1688,15 +1734,40 @@ struct AlignTypeSpec : AlignSpec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A full format specifier.
|
// A full format specifier.
|
||||||
struct FormatSpec : AlignSpec {
|
class FormatSpec : public AlignSpec {
|
||||||
|
private:
|
||||||
|
void set(fill_spec<char> fill) {
|
||||||
|
fill_ = fill.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(width_spec width) {
|
||||||
|
width_ = width.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(type_spec type) {
|
||||||
|
type_ = type.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Spec, typename... Specs>
|
||||||
|
void set(Spec spec, Specs... tail) {
|
||||||
|
set(spec);
|
||||||
|
set(tail...);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
unsigned flags_;
|
unsigned flags_;
|
||||||
int precision_;
|
int precision_;
|
||||||
char type_;
|
char type_;
|
||||||
|
|
||||||
FormatSpec(
|
FormatSpec(unsigned width = 0, char type = 0, wchar_t fill = ' ')
|
||||||
unsigned width = 0, char type = 0, wchar_t fill = ' ')
|
|
||||||
: AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
|
: AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
|
||||||
|
|
||||||
|
template <typename... FormatSpecs>
|
||||||
|
explicit FormatSpec(FormatSpecs... specs)
|
||||||
|
: AlignSpec(0, ' '), flags_(0), precision_(-1), type_(0){
|
||||||
|
set(specs...);
|
||||||
|
}
|
||||||
|
|
||||||
bool flag(unsigned f) const { return (flags_ & f) != 0; }
|
bool flag(unsigned f) const { return (flags_ & f) != 0; }
|
||||||
int precision() const { return precision_; }
|
int precision() const { return precision_; }
|
||||||
char type() const { return type_; }
|
char type() const { return type_; }
|
||||||
@ -1811,13 +1882,6 @@ inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
|
|||||||
TYPE value, unsigned width) { \
|
TYPE value, unsigned width) { \
|
||||||
return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
|
return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
|
||||||
value, AlignTypeSpec<0>(width, ' ')); \
|
value, AlignTypeSpec<0>(width, ' ')); \
|
||||||
} \
|
|
||||||
\
|
|
||||||
template <typename Char> \
|
|
||||||
inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
|
|
||||||
TYPE value, unsigned width, Char fill) { \
|
|
||||||
return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
|
|
||||||
value, AlignTypeSpec<0>(width, fill)); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_DEFINE_INT_FORMATTERS(int)
|
FMT_DEFINE_INT_FORMATTERS(int)
|
||||||
@ -2226,6 +2290,17 @@ class SystemError : public internal::RuntimeError {
|
|||||||
FMT_API void format_system_error(fmt::writer &out, int error_code,
|
FMT_API void format_system_error(fmt::writer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT;
|
fmt::StringRef message) FMT_NOEXCEPT;
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
// Named format specifier.
|
||||||
|
template <typename T>
|
||||||
|
class named_format_spec {
|
||||||
|
public:
|
||||||
|
constexpr named_format_spec() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr named_format_spec<unsigned> width;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
This template provides operations for formatting and writing data into
|
This template provides operations for formatting and writing data into
|
||||||
@ -2309,7 +2384,7 @@ class basic_writer {
|
|||||||
CharPtr prepare_int_buffer(unsigned num_digits,
|
CharPtr prepare_int_buffer(unsigned num_digits,
|
||||||
const Spec &spec, const char *prefix, unsigned prefix_size);
|
const Spec &spec, const char *prefix, unsigned prefix_size);
|
||||||
|
|
||||||
// Formats an integer.
|
// Writes a formatted integer.
|
||||||
template <typename T, typename Spec>
|
template <typename T, typename Spec>
|
||||||
void write_int(T value, Spec spec);
|
void write_int(T value, Spec spec);
|
||||||
|
|
||||||
@ -2449,6 +2524,12 @@ class basic_writer {
|
|||||||
*this << IntFormatSpec<ULongLong>(value);
|
*this << IntFormatSpec<ULongLong>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... FormatSpecs>
|
||||||
|
typename std::enable_if<std::is_integral<T>::value, void>::type
|
||||||
|
write(T value, FormatSpecs... specs) {
|
||||||
|
write_int(value, FormatSpec(specs...));
|
||||||
|
}
|
||||||
|
|
||||||
void write(double value) {
|
void write(double value) {
|
||||||
write_double(value, FormatSpec());
|
write_double(value, FormatSpec());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user