Refactor format_specs for #1109 and #940

Refactor `format_specs` and related APIs to support variable-width fill
(#1109), improve naming consistency, remove legacy setters (#940), and
optimize layout.
This commit is contained in:
Victor Zverovich
2019-07-06 17:57:57 -07:00
parent 8e0dcd20b3
commit e4f84ee1c6
8 changed files with 195 additions and 176 deletions

View File

@@ -690,7 +690,7 @@ struct formatter {
template <typename FormatContext>
auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
fmt::internal::handle_dynamic_spec<fmt::internal::width_checker>(
specs_.width_, specs_.width_ref, ctx, nullptr);
specs_.width, specs_.width_ref, ctx, nullptr);
fmt::internal::handle_dynamic_spec<fmt::internal::precision_checker>(
specs_.precision, specs_.precision_ref, ctx, nullptr);
using range_type = fmt::internal::output_range<typename FormatContext::iterator,

View File

@@ -2103,7 +2103,7 @@ struct test_format_specs_handler {
enum Result { NONE, PLUS, MINUS, SPACE, HASH, ZERO, ERROR };
Result res = NONE;
fmt::alignment align_ = fmt::ALIGN_DEFAULT;
fmt::align_t align = fmt::align::none;
char fill = 0;
unsigned width = 0;
fmt::internal::arg_ref<char> width_ref;
@@ -2117,7 +2117,7 @@ struct test_format_specs_handler {
FMT_CONSTEXPR test_format_specs_handler(
const test_format_specs_handler& other)
: res(other.res),
align_(other.align_),
align(other.align),
fill(other.fill),
width(other.width),
width_ref(other.width_ref),
@@ -2125,7 +2125,7 @@ struct test_format_specs_handler {
precision_ref(other.precision_ref),
type(other.type) {}
FMT_CONSTEXPR void on_align(fmt::alignment a) { align_ = a; }
FMT_CONSTEXPR void on_align(fmt::align_t a) { align = a; }
FMT_CONSTEXPR void on_fill(char f) { fill = f; }
FMT_CONSTEXPR void on_plus() { res = PLUS; }
FMT_CONSTEXPR void on_minus() { res = MINUS; }
@@ -2159,7 +2159,7 @@ FMT_CONSTEXPR test_format_specs_handler parse_test_specs(const char (&s)[N]) {
TEST(FormatTest, ConstexprParseFormatSpecs) {
typedef test_format_specs_handler handler;
static_assert(parse_test_specs("<").align_ == fmt::ALIGN_LEFT, "");
static_assert(parse_test_specs("<").align == fmt::align::left, "");
static_assert(parse_test_specs("*^").fill == '*', "");
static_assert(parse_test_specs("+").res == handler::PLUS, "");
static_assert(parse_test_specs("-").res == handler::MINUS, "");
@@ -2216,16 +2216,16 @@ FMT_CONSTEXPR fmt::format_specs parse_specs(const char (&s)[N]) {
}
TEST(FormatTest, ConstexprSpecsHandler) {
static_assert(parse_specs("<").align() == fmt::ALIGN_LEFT, "");
static_assert(parse_specs("*^").fill() == '*', "");
static_assert(parse_specs("+").has(fmt::PLUS_FLAG), "");
static_assert(parse_specs("-").has(fmt::MINUS_FLAG), "");
static_assert(parse_specs(" ").has(fmt::SIGN_FLAG), "");
static_assert(parse_specs("#").has(fmt::HASH_FLAG), "");
static_assert(parse_specs("0").align() == fmt::ALIGN_NUMERIC, "");
static_assert(parse_specs("42").width() == 42, "");
static_assert(parse_specs("{}").width() == 11, "");
static_assert(parse_specs("{22}").width() == 22, "");
static_assert(parse_specs("<").align == fmt::align::left, "");
static_assert(parse_specs("*^").fill[0] == '*', "");
static_assert(parse_specs("+").sign == fmt::sign::plus, "");
static_assert(parse_specs("-").sign == fmt::sign::minus, "");
static_assert(parse_specs(" ").sign == fmt::sign::space, "");
static_assert(parse_specs("#").alt, "");
static_assert(parse_specs("0").align == fmt::align::numeric, "");
static_assert(parse_specs("42").width == 42, "");
static_assert(parse_specs("{}").width == 11, "");
static_assert(parse_specs("{22}").width == 22, "");
static_assert(parse_specs(".42").precision == 42, "");
static_assert(parse_specs(".{}").precision == 11, "");
static_assert(parse_specs(".{22}").precision == 22, "");
@@ -2243,14 +2243,14 @@ FMT_CONSTEXPR fmt::internal::dynamic_format_specs<char> parse_dynamic_specs(
}
TEST(FormatTest, ConstexprDynamicSpecsHandler) {
static_assert(parse_dynamic_specs("<").align() == fmt::ALIGN_LEFT, "");
static_assert(parse_dynamic_specs("*^").fill() == '*', "");
static_assert(parse_dynamic_specs("+").has(fmt::PLUS_FLAG), "");
static_assert(parse_dynamic_specs("-").has(fmt::MINUS_FLAG), "");
static_assert(parse_dynamic_specs(" ").has(fmt::SIGN_FLAG), "");
static_assert(parse_dynamic_specs("#").has(fmt::HASH_FLAG), "");
static_assert(parse_dynamic_specs("0").align() == fmt::ALIGN_NUMERIC, "");
static_assert(parse_dynamic_specs("42").width() == 42, "");
static_assert(parse_dynamic_specs("<").align == fmt::align::left, "");
static_assert(parse_dynamic_specs("*^").fill[0] == '*', "");
static_assert(parse_dynamic_specs("+").sign == fmt::sign::plus, "");
static_assert(parse_dynamic_specs("-").sign == fmt::sign::minus, "");
static_assert(parse_dynamic_specs(" ").sign == fmt::sign::space, "");
static_assert(parse_dynamic_specs("#").alt, "");
static_assert(parse_dynamic_specs("0").align == fmt::align::numeric, "");
static_assert(parse_dynamic_specs("42").width == 42, "");
static_assert(parse_dynamic_specs("{}").width_ref.val.index == 11, "");
static_assert(parse_dynamic_specs("{42}").width_ref.val.index == 42, "");
static_assert(parse_dynamic_specs(".42").precision == 42, "");
@@ -2269,7 +2269,7 @@ FMT_CONSTEXPR test_format_specs_handler check_specs(const char (&s)[N]) {
TEST(FormatTest, ConstexprSpecsChecker) {
typedef test_format_specs_handler handler;
static_assert(check_specs("<").align_ == fmt::ALIGN_LEFT, "");
static_assert(check_specs("<").align == fmt::align::left, "");
static_assert(check_specs("*^").fill == '*', "");
static_assert(check_specs("+").res == handler::PLUS, "");
static_assert(check_specs("-").res == handler::MINUS, "");

View File

@@ -71,12 +71,12 @@ bool operator==(const format_part<char>::specification& lhs,
} break;
}
return std::tie(lhs.parsed_specs.width_, lhs.parsed_specs.fill_,
lhs.parsed_specs.align_, lhs.parsed_specs.precision,
lhs.parsed_specs.flags, lhs.parsed_specs.type) ==
std::tie(rhs.parsed_specs.width_, rhs.parsed_specs.fill_,
rhs.parsed_specs.align_, rhs.parsed_specs.precision,
rhs.parsed_specs.flags, rhs.parsed_specs.type);
return std::tie(lhs.parsed_specs.width, lhs.parsed_specs.fill[0],
lhs.parsed_specs.align, lhs.parsed_specs.precision,
lhs.parsed_specs.sign, lhs.parsed_specs.type) ==
std::tie(rhs.parsed_specs.width, rhs.parsed_specs.fill[0],
rhs.parsed_specs.align, rhs.parsed_specs.precision,
rhs.parsed_specs.sign, rhs.parsed_specs.type);
}
bool operator!=(const format_part<char>::specification& lhs,
@@ -352,8 +352,8 @@ TEST(
const auto last_part = format_part(0u);
format_part::specification expected_specification(0u);
fmt::internal::dynamic_format_specs<char> specs{};
specs.align_ = fmt::alignment::ALIGN_LEFT;
specs.width_ = 10;
specs.align = fmt::align::left;
specs.width = 10;
expected_specification.parsed_specs = specs;
auto expected_substitution_part = format_part(expected_specification);
@@ -384,8 +384,8 @@ TEST(
const auto last_part = format_part(format_part::named_argument_id(arg_id));
format_part::specification expected_specification(arg_id);
fmt::internal::dynamic_format_specs<char> specs{};
specs.align_ = fmt::alignment::ALIGN_LEFT;
specs.width_ = 10;
specs.align = fmt::align::left;
specs.width = 10;
expected_specification.parsed_specs = specs;
auto expected_substitution_part = format_part(expected_specification);