basic_format_specs -> format_specs

This commit is contained in:
Victor Zverovich 2022-12-24 14:34:50 -08:00
parent 3cf9794755
commit 407e7b7b6d
8 changed files with 67 additions and 81 deletions

View File

@ -1655,7 +1655,7 @@ OutputIt format_duration_value(OutputIt out, Rep val, int) {
template <typename Char, typename Rep, typename OutputIt, template <typename Char, typename Rep, typename OutputIt,
FMT_ENABLE_IF(std::is_floating_point<Rep>::value)> FMT_ENABLE_IF(std::is_floating_point<Rep>::value)>
OutputIt format_duration_value(OutputIt out, Rep val, int precision) { OutputIt format_duration_value(OutputIt out, Rep val, int precision) {
auto specs = basic_format_specs<Char>(); auto specs = format_specs<Char>();
specs.precision = precision; specs.precision = precision;
specs.type = precision >= 0 ? presentation_type::fixed_lower specs.type = precision >= 0 ? presentation_type::fixed_lower
: presentation_type::general_lower; : presentation_type::general_lower;
@ -1991,7 +1991,7 @@ template <typename Char> struct formatter<weekday, Char> {
template <typename Rep, typename Period, typename Char> template <typename Rep, typename Period, typename Char>
struct formatter<std::chrono::duration<Rep, Period>, Char> { struct formatter<std::chrono::duration<Rep, Period>, Char> {
private: private:
basic_format_specs<Char> specs; format_specs<Char> specs;
int precision = -1; int precision = -1;
using arg_ref_type = detail::arg_ref<Char>; using arg_ref_type = detail::arg_ref<Char>;
arg_ref_type width_ref; arg_ref_type width_ref;

View File

@ -2146,7 +2146,7 @@ enum class presentation_type : unsigned char {
}; };
// Format specifiers for built-in and string types. // Format specifiers for built-in and string types.
template <typename Char> struct basic_format_specs { template <typename Char = char> struct format_specs {
int width; int width;
int precision; int precision;
presentation_type type; presentation_type type;
@ -2156,7 +2156,7 @@ template <typename Char> struct basic_format_specs {
bool localized : 1; bool localized : 1;
detail::fill_t<Char> fill; detail::fill_t<Char> fill;
constexpr basic_format_specs() constexpr format_specs()
: width(0), : width(0),
precision(-1), precision(-1),
type(presentation_type::none), type(presentation_type::none),
@ -2166,8 +2166,6 @@ template <typename Char> struct basic_format_specs {
localized(false) {} localized(false) {}
}; };
using format_specs = basic_format_specs<char>;
FMT_BEGIN_DETAIL_NAMESPACE FMT_BEGIN_DETAIL_NAMESPACE
enum class arg_id_kind { none, index, name }; enum class arg_id_kind { none, index, name };
@ -2200,8 +2198,7 @@ template <typename Char> struct arg_ref {
// Format specifiers with width and precision resolved at formatting rather // Format specifiers with width and precision resolved at formatting rather
// than parsing time to allow re-using the same parsed specifiers with // than parsing time to allow re-using the same parsed specifiers with
// different sets of arguments (precompilation of format strings). // different sets of arguments (precompilation of format strings).
template <typename Char> template <typename Char> struct dynamic_format_specs : format_specs<Char> {
struct dynamic_format_specs : basic_format_specs<Char> {
arg_ref<Char> width_ref; arg_ref<Char> width_ref;
arg_ref<Char> precision_ref; arg_ref<Char> precision_ref;
}; };
@ -2217,13 +2214,13 @@ template <typename Char> struct dynamic_spec {
}; };
}; };
// A format specifier handler that sets fields in basic_format_specs. // A format specifier handler that sets fields in format_specs.
template <typename Char> class specs_setter { template <typename Char> class specs_setter {
protected: protected:
basic_format_specs<Char>& specs_; format_specs<Char>& specs_;
public: public:
explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs) explicit FMT_CONSTEXPR specs_setter(format_specs<Char>& specs)
: specs_(specs) {} : specs_(specs) {}
FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; }
@ -2783,7 +2780,7 @@ FMT_CONSTEXPR void check_int_type_spec(presentation_type type,
// Checks char specs and returns true if the type spec is char (and not int). // Checks char specs and returns true if the type spec is char (and not int).
template <typename Char, typename ErrorHandler = error_handler> template <typename Char, typename ErrorHandler = error_handler>
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs<Char>& specs, FMT_CONSTEXPR auto check_char_specs(const format_specs<Char>& specs,
ErrorHandler&& eh = {}) -> bool { ErrorHandler&& eh = {}) -> bool {
if (specs.type != presentation_type::none && if (specs.type != presentation_type::none &&
specs.type != presentation_type::chr && specs.type != presentation_type::chr &&
@ -2815,7 +2812,7 @@ struct float_specs {
}; };
template <typename ErrorHandler = error_handler, typename Char> template <typename ErrorHandler = error_handler, typename Char>
FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs, FMT_CONSTEXPR auto parse_float_type_spec(const format_specs<Char>& specs,
ErrorHandler&& eh = {}) ErrorHandler&& eh = {})
-> float_specs { -> float_specs {
auto result = float_specs(); auto result = float_specs();

View File

@ -117,7 +117,7 @@ template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
#endif #endif
FMT_FUNC auto write_loc(appender out, loc_value value, FMT_FUNC auto write_loc(appender out, loc_value value,
const format_specs& specs, locale_ref loc) -> bool { const format_specs<>& specs, locale_ref loc) -> bool {
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
auto locale = loc.get<std::locale>(); auto locale = loc.get<std::locale>();
// We cannot use the num_put<char> facet because it may produce output in // We cannot use the num_put<char> facet because it may produce output in
@ -142,7 +142,7 @@ template <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {
template <> template <>
FMT_API FMT_FUNC auto format_facet<std::locale>::do_put( FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
appender out, loc_value val, const format_specs& specs) const -> bool { appender out, loc_value val, const format_specs<>& specs) const -> bool {
return val.visit( return val.visit(
detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_}); detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_});
} }

View File

@ -1043,7 +1043,7 @@ template <typename Locale> class format_facet : public Locale::facet {
protected: protected:
virtual auto do_put(appender out, loc_value val, virtual auto do_put(appender out, loc_value val,
const format_specs& specs) const -> bool; const format_specs<>& specs) const -> bool;
public: public:
static FMT_API typename Locale::id id; static FMT_API typename Locale::id id;
@ -1056,7 +1056,7 @@ template <typename Locale> class format_facet : public Locale::facet {
grouping_(g.begin(), g.end()), grouping_(g.begin(), g.end()),
decimal_point_(decimal_point) {} decimal_point_(decimal_point) {}
auto put(appender out, loc_value val, const format_specs& specs) const auto put(appender out, loc_value val, const format_specs<>& specs) const
-> bool { -> bool {
return do_put(out, val, specs); return do_put(out, val, specs);
} }
@ -1664,8 +1664,7 @@ FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
// width: output display width in (terminal) column positions. // width: output display width in (terminal) column positions.
template <align::type align = align::left, typename OutputIt, typename Char, template <align::type align = align::left, typename OutputIt, typename Char,
typename F> typename F>
FMT_CONSTEXPR auto write_padded(OutputIt out, FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs<Char>& specs,
const basic_format_specs<Char>& specs,
size_t size, size_t width, F&& f) -> OutputIt { size_t size, size_t width, F&& f) -> OutputIt {
static_assert(align == align::left || align == align::right, ""); static_assert(align == align::left || align == align::right, "");
unsigned spec_width = to_unsigned(specs.width); unsigned spec_width = to_unsigned(specs.width);
@ -1684,15 +1683,14 @@ FMT_CONSTEXPR auto write_padded(OutputIt out,
template <align::type align = align::left, typename OutputIt, typename Char, template <align::type align = align::left, typename OutputIt, typename Char,
typename F> typename F>
constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs, constexpr auto write_padded(OutputIt out, const format_specs<Char>& specs,
size_t size, F&& f) -> OutputIt { size_t size, F&& f) -> OutputIt {
return write_padded<align>(out, specs, size, size, f); return write_padded<align>(out, specs, size, size, f);
} }
template <align::type align = align::left, typename Char, typename OutputIt> template <align::type align = align::left, typename Char, typename OutputIt>
FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
const basic_format_specs<Char>& specs) const format_specs<Char>& specs) -> OutputIt {
-> OutputIt {
return write_padded<align>( return write_padded<align>(
out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) { out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
const char* data = bytes.data(); const char* data = bytes.data();
@ -1701,8 +1699,8 @@ FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
} }
template <typename Char, typename OutputIt, typename UIntPtr> template <typename Char, typename OutputIt, typename UIntPtr>
auto write_ptr(OutputIt out, UIntPtr value, auto write_ptr(OutputIt out, UIntPtr value, const format_specs<Char>* specs)
const basic_format_specs<Char>* specs) -> OutputIt { -> OutputIt {
int num_digits = count_digits<4>(value); int num_digits = count_digits<4>(value);
auto size = to_unsigned(num_digits) + size_t(2); auto size = to_unsigned(num_digits) + size_t(2);
auto write = [=](reserve_iterator<OutputIt> it) { auto write = [=](reserve_iterator<OutputIt> it) {
@ -1875,8 +1873,7 @@ auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR auto write_char(OutputIt out, Char value, FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
const basic_format_specs<Char>& specs) const format_specs<Char>& specs) -> OutputIt {
-> OutputIt {
bool is_debug = specs.type == presentation_type::debug; bool is_debug = specs.type == presentation_type::debug;
return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) { return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
if (is_debug) return write_escaped_char(it, value); if (is_debug) return write_escaped_char(it, value);
@ -1886,8 +1883,8 @@ FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
} }
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR auto write(OutputIt out, Char value, FMT_CONSTEXPR auto write(OutputIt out, Char value,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs, locale_ref loc = {})
locale_ref loc = {}) -> OutputIt { -> OutputIt {
return check_char_specs(specs) return check_char_specs(specs)
? write_char(out, value, specs) ? write_char(out, value, specs)
: write(out, static_cast<int>(value), specs, loc); : write(out, static_cast<int>(value), specs, loc);
@ -1900,7 +1897,7 @@ template <typename Char> struct write_int_data {
size_t padding; size_t padding;
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
const basic_format_specs<Char>& specs) const format_specs<Char>& specs)
: size((prefix >> 24) + to_unsigned(num_digits)), padding(0) { : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
if (specs.align == align::numeric) { if (specs.align == align::numeric) {
auto width = to_unsigned(specs.width); auto width = to_unsigned(specs.width);
@ -1922,7 +1919,7 @@ template <typename Char> struct write_int_data {
template <typename OutputIt, typename Char, typename W> template <typename OutputIt, typename Char, typename W>
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
unsigned prefix, unsigned prefix,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
W write_digits) -> OutputIt { W write_digits) -> OutputIt {
// Slightly faster check for specs.width == 0 && specs.precision == -1. // Slightly faster check for specs.width == 0 && specs.precision == -1.
if ((specs.width | (specs.precision + 1)) == 0) { if ((specs.width | (specs.precision + 1)) == 0) {
@ -2011,7 +2008,7 @@ template <typename Char> class digit_grouping {
// Writes a decimal integer with digit grouping. // Writes a decimal integer with digit grouping.
template <typename OutputIt, typename UInt, typename Char> template <typename OutputIt, typename UInt, typename Char>
auto write_int(OutputIt out, UInt value, unsigned prefix, auto write_int(OutputIt out, UInt value, unsigned prefix,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
const digit_grouping<Char>& grouping) -> OutputIt { const digit_grouping<Char>& grouping) -> OutputIt {
static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, ""); static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
int num_digits = count_digits(value); int num_digits = count_digits(value);
@ -2030,10 +2027,10 @@ auto write_int(OutputIt out, UInt value, unsigned prefix,
} }
// Writes a localized value. // Writes a localized value.
FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs, FMT_API auto write_loc(appender out, loc_value value,
locale_ref loc) -> bool; const format_specs<>& specs, locale_ref loc) -> bool;
template <typename OutputIt, typename Char> template <typename OutputIt, typename Char>
inline auto write_loc(OutputIt, loc_value, const basic_format_specs<Char>&, inline auto write_loc(OutputIt, loc_value, const format_specs<Char>&,
locale_ref) -> bool { locale_ref) -> bool {
return false; return false;
} }
@ -2066,7 +2063,7 @@ FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign)
template <typename Char = char> struct loc_writer { template <typename Char = char> struct loc_writer {
buffer_appender<Char> out; buffer_appender<Char> out;
const basic_format_specs<Char>& specs; const format_specs<Char>& specs;
std::basic_string<Char> sep; std::basic_string<Char> sep;
std::string grouping; std::string grouping;
std::basic_string<Char> decimal_point; std::basic_string<Char> decimal_point;
@ -2087,7 +2084,7 @@ template <typename Char = char> struct loc_writer {
template <typename Char, typename OutputIt, typename T> template <typename Char, typename OutputIt, typename T>
FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg, FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
locale_ref) -> OutputIt { locale_ref) -> OutputIt {
static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, ""); static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
auto abs_value = arg.abs_value; auto abs_value = arg.abs_value;
@ -2143,7 +2140,7 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
} }
template <typename Char, typename OutputIt, typename T> template <typename Char, typename OutputIt, typename T>
FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline( FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(
OutputIt out, write_int_arg<T> arg, const basic_format_specs<Char>& specs, OutputIt out, write_int_arg<T> arg, const format_specs<Char>& specs,
locale_ref loc) -> OutputIt { locale_ref loc) -> OutputIt {
return write_int(out, arg, specs, loc); return write_int(out, arg, specs, loc);
} }
@ -2152,7 +2149,7 @@ template <typename Char, typename OutputIt, typename T,
!std::is_same<T, bool>::value && !std::is_same<T, bool>::value &&
std::is_same<OutputIt, buffer_appender<Char>>::value)> std::is_same<OutputIt, buffer_appender<Char>>::value)>
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
locale_ref loc) -> OutputIt { locale_ref loc) -> OutputIt {
if (specs.localized && write_loc(out, value, specs, loc)) return out; if (specs.localized && write_loc(out, value, specs, loc)) return out;
return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs, return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
@ -2164,7 +2161,7 @@ template <typename Char, typename OutputIt, typename T,
!std::is_same<T, bool>::value && !std::is_same<T, bool>::value &&
!std::is_same<OutputIt, buffer_appender<Char>>::value)> !std::is_same<OutputIt, buffer_appender<Char>>::value)>
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
locale_ref loc) -> OutputIt { locale_ref loc) -> OutputIt {
if (specs.localized && write_loc(out, value, specs, loc)) return out; if (specs.localized && write_loc(out, value, specs, loc)) return out;
return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
@ -2212,7 +2209,7 @@ class counting_iterator {
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s, FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
const basic_format_specs<Char>& specs) -> OutputIt { const format_specs<Char>& specs) -> OutputIt {
auto data = s.data(); auto data = s.data();
auto size = s.size(); auto size = s.size();
if (specs.precision >= 0 && to_unsigned(specs.precision) < size) if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
@ -2234,14 +2231,14 @@ FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR auto write(OutputIt out, FMT_CONSTEXPR auto write(OutputIt out,
basic_string_view<type_identity_t<Char>> s, basic_string_view<type_identity_t<Char>> s,
const basic_format_specs<Char>& specs, locale_ref) const format_specs<Char>& specs, locale_ref)
-> OutputIt { -> OutputIt {
check_string_type_spec(specs.type); check_string_type_spec(specs.type);
return write(out, s, specs); return write(out, s, specs);
} }
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR auto write(OutputIt out, const Char* s, FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
const basic_format_specs<Char>& specs, locale_ref) const format_specs<Char>& specs, locale_ref)
-> OutputIt { -> OutputIt {
return check_cstring_type_spec(specs.type) return check_cstring_type_spec(specs.type)
? write(out, basic_string_view<Char>(s), specs, {}) ? write(out, basic_string_view<Char>(s), specs, {})
@ -2272,7 +2269,7 @@ FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan, FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
basic_format_specs<Char> specs, format_specs<Char> specs,
const float_specs& fspecs) -> OutputIt { const float_specs& fspecs) -> OutputIt {
auto str = auto str =
isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf"); isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf");
@ -2396,7 +2393,7 @@ FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
template <typename OutputIt, typename DecimalFP, typename Char, template <typename OutputIt, typename DecimalFP, typename Char,
typename Grouping = digit_grouping<Char>> typename Grouping = digit_grouping<Char>>
FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f, FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
float_specs fspecs, locale_ref loc) float_specs fspecs, locale_ref loc)
-> OutputIt { -> OutputIt {
auto significand = f.significand; auto significand = f.significand;
@ -2515,7 +2512,7 @@ template <typename Char> class fallback_digit_grouping {
template <typename OutputIt, typename DecimalFP, typename Char> template <typename OutputIt, typename DecimalFP, typename Char>
FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f, FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,
const basic_format_specs<Char>& specs, const format_specs<Char>& specs,
float_specs fspecs, locale_ref loc) float_specs fspecs, locale_ref loc)
-> OutputIt { -> OutputIt {
if (is_constant_evaluated()) { if (is_constant_evaluated()) {
@ -3302,7 +3299,7 @@ FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
} }
template <typename Char, typename OutputIt, typename T> template <typename Char, typename OutputIt, typename T>
FMT_CONSTEXPR20 auto write_float(OutputIt out, T value, FMT_CONSTEXPR20 auto write_float(OutputIt out, T value,
basic_format_specs<Char> specs, locale_ref loc) format_specs<Char> specs, locale_ref loc)
-> OutputIt { -> OutputIt {
float_specs fspecs = parse_float_type_spec(specs); float_specs fspecs = parse_float_type_spec(specs);
fspecs.sign = specs.sign; fspecs.sign = specs.sign;
@ -3351,9 +3348,8 @@ FMT_CONSTEXPR20 auto write_float(OutputIt out, T value,
template <typename Char, typename OutputIt, typename T, template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(is_floating_point<T>::value)> FMT_ENABLE_IF(is_floating_point<T>::value)>
FMT_CONSTEXPR20 auto write(OutputIt out, T value, FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs<Char> specs,
basic_format_specs<Char> specs, locale_ref loc = {}) locale_ref loc = {}) -> OutputIt {
-> OutputIt {
if (const_check(!is_supported_floating_point(value))) return out; if (const_check(!is_supported_floating_point(value))) return out;
return specs.localized && write_loc(out, value, specs, loc) return specs.localized && write_loc(out, value, specs, loc)
? out ? out
@ -3363,8 +3359,7 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value,
template <typename Char, typename OutputIt, typename T, template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(is_fast_float<T>::value)> FMT_ENABLE_IF(is_fast_float<T>::value)>
FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt { FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
if (is_constant_evaluated()) if (is_constant_evaluated()) return write(out, value, format_specs<Char>());
return write(out, value, basic_format_specs<Char>());
if (const_check(!is_supported_floating_point(value))) return out; if (const_check(!is_supported_floating_point(value))) return out;
auto fspecs = float_specs(); auto fspecs = float_specs();
@ -3373,7 +3368,7 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
value = -value; value = -value;
} }
constexpr auto specs = basic_format_specs<Char>(); constexpr auto specs = format_specs<Char>();
using floaty = conditional_t<std::is_same<T, long double>::value, double, T>; using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
using floaty_uint = typename dragonbox::float_info<floaty>::carrier_uint; using floaty_uint = typename dragonbox::float_info<floaty>::carrier_uint;
floaty_uint mask = exponent_mask<floaty>(); floaty_uint mask = exponent_mask<floaty>();
@ -3388,12 +3383,12 @@ template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(is_floating_point<T>::value && FMT_ENABLE_IF(is_floating_point<T>::value &&
!is_fast_float<T>::value)> !is_fast_float<T>::value)>
inline auto write(OutputIt out, T value) -> OutputIt { inline auto write(OutputIt out, T value) -> OutputIt {
return write(out, value, basic_format_specs<Char>()); return write(out, value, format_specs<Char>());
} }
template <typename Char, typename OutputIt> template <typename Char, typename OutputIt>
auto write(OutputIt out, monostate, basic_format_specs<Char> = {}, auto write(OutputIt out, monostate, format_specs<Char> = {}, locale_ref = {})
locale_ref = {}) -> OutputIt { -> OutputIt {
FMT_ASSERT(false, ""); FMT_ASSERT(false, "");
return out; return out;
} }
@ -3427,8 +3422,8 @@ FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
template <typename Char, typename OutputIt, typename T, template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(std::is_same<T, bool>::value)> FMT_ENABLE_IF(std::is_same<T, bool>::value)>
FMT_CONSTEXPR auto write(OutputIt out, T value, FMT_CONSTEXPR auto write(OutputIt out, T value,
const basic_format_specs<Char>& specs = {}, const format_specs<Char>& specs = {}, locale_ref = {})
locale_ref = {}) -> OutputIt { -> OutputIt {
return specs.type != presentation_type::none && return specs.type != presentation_type::none &&
specs.type != presentation_type::string specs.type != presentation_type::string
? write(out, value ? 1 : 0, specs, {}) ? write(out, value ? 1 : 0, specs, {})
@ -3455,9 +3450,8 @@ FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
template <typename Char, typename OutputIt, typename T, template <typename Char, typename OutputIt, typename T,
FMT_ENABLE_IF(std::is_same<T, void>::value)> FMT_ENABLE_IF(std::is_same<T, void>::value)>
auto write(OutputIt out, const T* value, auto write(OutputIt out, const T* value, const format_specs<Char>& specs = {},
const basic_format_specs<Char>& specs = {}, locale_ref = {}) locale_ref = {}) -> OutputIt {
-> OutputIt {
check_pointer_type_spec(specs.type, error_handler()); check_pointer_type_spec(specs.type, error_handler());
return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs); return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
} }
@ -3513,7 +3507,7 @@ template <typename Char> struct arg_formatter {
using context = buffer_context<Char>; using context = buffer_context<Char>;
iterator out; iterator out;
const basic_format_specs<Char>& specs; const format_specs<Char>& specs;
locale_ref locale; locale_ref locale;
template <typename T> template <typename T>
@ -3604,7 +3598,7 @@ template <typename Char> class specs_handler : public specs_setter<Char> {
using format_arg = basic_format_arg<buffer_context<Char>>; using format_arg = basic_format_arg<buffer_context<Char>>;
public: public:
FMT_CONSTEXPR specs_handler(basic_format_specs<Char>& specs, FMT_CONSTEXPR specs_handler(format_specs<Char>& specs,
basic_format_parse_context<Char>& parse_ctx, basic_format_parse_context<Char>& parse_ctx,
buffer_context<Char>& ctx) buffer_context<Char>& ctx)
: specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {} : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {}
@ -4261,7 +4255,7 @@ void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
visit_format_arg(custom_formatter<Char>{parse_context, context}, arg); visit_format_arg(custom_formatter<Char>{parse_context, context}, arg);
return parse_context.begin(); return parse_context.begin();
} }
auto specs = basic_format_specs<Char>(); auto specs = format_specs<Char>();
specs_checker<specs_handler<Char>> handler( specs_checker<specs_handler<Char>> handler(
specs_handler<Char>(specs, parse_context, context), arg.type()); specs_handler<Char>(specs, parse_context, context), arg.type());
begin = parse_format_specs(begin, end, handler); begin = parse_format_specs(begin, end, handler);

View File

@ -194,12 +194,10 @@ template <typename Char> struct get_cstring {
// left alignment if it is negative. // left alignment if it is negative.
template <typename Char> class printf_width_handler { template <typename Char> class printf_width_handler {
private: private:
using format_specs = basic_format_specs<Char>; format_specs<Char>& specs_;
format_specs& specs_;
public: public:
explicit printf_width_handler(format_specs& specs) : specs_(specs) {} explicit printf_width_handler(format_specs<Char>& specs) : specs_(specs) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
unsigned operator()(T value) { unsigned operator()(T value) {
@ -226,7 +224,6 @@ class printf_arg_formatter : public arg_formatter<Char> {
private: private:
using base = arg_formatter<Char>; using base = arg_formatter<Char>;
using context_type = basic_printf_context<OutputIt, Char>; using context_type = basic_printf_context<OutputIt, Char>;
using format_specs = basic_format_specs<Char>;
context_type& context_; context_type& context_;
@ -237,7 +234,7 @@ class printf_arg_formatter : public arg_formatter<Char> {
} }
public: public:
printf_arg_formatter(OutputIt iter, format_specs& s, context_type& ctx) printf_arg_formatter(OutputIt iter, format_specs<Char>& s, context_type& ctx)
: base{iter, s, locale_ref()}, context_(ctx) {} : base{iter, s, locale_ref()}, context_(ctx) {}
OutputIt operator()(monostate value) { return base::operator()(value); } OutputIt operator()(monostate value) { return base::operator()(value); }
@ -247,7 +244,7 @@ class printf_arg_formatter : public arg_formatter<Char> {
// MSVC2013 fails to compile separate overloads for bool and Char so use // MSVC2013 fails to compile separate overloads for bool and Char so use
// std::is_same instead. // std::is_same instead.
if (std::is_same<T, Char>::value) { if (std::is_same<T, Char>::value) {
format_specs fmt_specs = this->specs; format_specs<Char> fmt_specs = this->specs;
if (fmt_specs.type != presentation_type::none && if (fmt_specs.type != presentation_type::none &&
fmt_specs.type != presentation_type::chr) { fmt_specs.type != presentation_type::chr) {
return (*this)(static_cast<int>(value)); return (*this)(static_cast<int>(value));
@ -300,8 +297,7 @@ class printf_arg_formatter : public arg_formatter<Char> {
}; };
template <typename Char> template <typename Char>
void parse_flags(basic_format_specs<Char>& specs, const Char*& it, void parse_flags(format_specs<Char>& specs, const Char*& it, const Char* end) {
const Char* end) {
for (; it != end; ++it) { for (; it != end; ++it) {
switch (*it) { switch (*it) {
case '-': case '-':
@ -328,8 +324,8 @@ void parse_flags(basic_format_specs<Char>& specs, const Char*& it,
} }
template <typename Char, typename GetArg> template <typename Char, typename GetArg>
int parse_header(const Char*& it, const Char* end, int parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
basic_format_specs<Char>& specs, GetArg get_arg) { GetArg get_arg) {
int arg_index = -1; int arg_index = -1;
Char c = *it; Char c = *it;
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
@ -401,7 +397,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
out = detail::write(out, basic_string_view<Char>( out = detail::write(out, basic_string_view<Char>(
start, detail::to_unsigned(it - 1 - start))); start, detail::to_unsigned(it - 1 - start)));
basic_format_specs<Char> specs; auto specs = format_specs<Char>();
specs.align = align::right; specs.align = align::right;
// Parse argument index, flags and width. // Parse argument index, flags and width.

View File

@ -191,8 +191,7 @@ template <typename Char> struct formatter<std::error_code, Char> {
FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
-> decltype(ctx.out()) { -> decltype(ctx.out()) {
auto out = ctx.out(); auto out = ctx.out();
out = detail::write_bytes(out, ec.category().name(), out = detail::write_bytes(out, ec.category().name(), format_specs<Char>());
basic_format_specs<Char>());
out = detail::write<Char>(out, Char(':')); out = detail::write<Char>(out, Char(':'));
out = detail::write<Char>(out, ec.value()); out = detail::write<Char>(out, ec.value());
return out; return out;
@ -222,7 +221,7 @@ struct formatter<
template <typename OutputIt> template <typename OutputIt>
auto format(const std::exception& ex, auto format(const std::exception& ex,
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt { basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
basic_format_specs<Char> spec; format_specs<Char> spec;
auto out = ctx.out(); auto out = ctx.out();
if (!with_typename_) if (!with_typename_)
return detail::write_bytes(out, string_view(ex.what()), spec); return detail::write_bytes(out, string_view(ex.what()), spec);

View File

@ -23,7 +23,7 @@ template <typename T>
using is_exotic_char = bool_constant<!std::is_same<T, char>::value>; using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out, inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out,
loc_value value, const basic_format_specs<wchar_t>& specs, loc_value value, const format_specs<wchar_t>& specs,
locale_ref loc) -> bool { locale_ref loc) -> bool {
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
auto& numpunct = auto& numpunct =

View File

@ -2290,11 +2290,11 @@ class format_facet : public fmt::format_facet<std::locale> {
}; };
auto do_put(fmt::appender out, fmt::loc_value val, auto do_put(fmt::appender out, fmt::loc_value val,
const fmt::format_specs&) const -> bool override; const fmt::format_specs<>&) const -> bool override;
}; };
auto format_facet::do_put(fmt::appender out, fmt::loc_value val, auto format_facet::do_put(fmt::appender out, fmt::loc_value val,
const fmt::format_specs&) const -> bool { const fmt::format_specs<>&) const -> bool {
return val.visit(int_formatter{out}); return val.visit(int_formatter{out});
} }