Simplify format string compilation

This commit is contained in:
Victor Zverovich
2019-08-25 07:48:09 -07:00
parent e2e557e273
commit 4ce006fb6e
2 changed files with 24 additions and 273 deletions

View File

@@ -34,13 +34,6 @@
using testing::Return;
using testing::StrictMock;
class mock_parts_collector {
public:
MOCK_METHOD1(add, void(fmt::internal::format_part<char>));
MOCK_METHOD1(substitute_last, void(fmt::internal::format_part<char>));
MOCK_METHOD0(last, fmt::internal::format_part<char>());
};
FMT_BEGIN_NAMESPACE
namespace internal {
bool operator==(const internal::string_view_metadata& lhs,
@@ -227,179 +220,6 @@ TEST(CompileTest, FormatPart_ComparisonOperators) {
}
}
TEST(CompileTest, FormatPreparationHandler_OnText_AddsPartWithText) {
typedef fmt::internal::format_part<char> format_part;
typedef StrictMock<mock_parts_collector> parts_mock;
parts_mock parts;
const auto format = fmt::internal::to_string_view("text");
fmt::internal::format_preparation_handler<char, parts_mock> handler(format,
parts);
const auto expected_text = fmt::internal::string_view_metadata(
0u, static_cast<unsigned>(format.size()));
EXPECT_CALL(parts, add(format_part(expected_text)));
handler.on_text(format.begin(), format.end());
}
TEST(CompileTest, FormatPreparationHandler_OnArgId_AddsPartWithIncrementedId) {
typedef fmt::internal::format_part<char> format_part;
typedef StrictMock<mock_parts_collector> parts_mock;
parts_mock parts;
const auto format = fmt::internal::to_string_view("");
fmt::internal::format_preparation_handler<char, parts_mock> handler(format,
parts);
const auto expected_first_arg_id = 0u;
const auto expected_second_arg_id = 1u;
EXPECT_CALL(parts, add(format_part(expected_first_arg_id)));
EXPECT_CALL(parts, add(format_part(expected_second_arg_id)));
handler.on_arg_id();
handler.on_arg_id();
}
TEST(CompileTest, FormatPreparationHandler_OnArgId_AddsPartWithPassedId) {
typedef fmt::internal::format_part<char> format_part;
typedef StrictMock<mock_parts_collector> parts_mock;
parts_mock parts;
const auto format = fmt::internal::to_string_view("");
fmt::internal::format_preparation_handler<char, parts_mock> handler(format,
parts);
const auto expected_first_arg_id = 2u;
const auto expected_second_arg_id = 0u;
const auto expected_third_arg_id = 1u;
EXPECT_CALL(parts, add(format_part(expected_first_arg_id)));
EXPECT_CALL(parts, add(format_part(expected_second_arg_id)));
EXPECT_CALL(parts, add(format_part(expected_third_arg_id)));
handler.on_arg_id(expected_first_arg_id);
handler.on_arg_id(expected_second_arg_id);
handler.on_arg_id(expected_third_arg_id);
}
TEST(CompileTest, FormatPreparationHandler_OnArgId_AddsPartWithPassedNamedId) {
typedef fmt::internal::format_part<char> format_part;
typedef format_part::named_argument_id named_argument_id;
typedef StrictMock<mock_parts_collector> parts_mock;
parts_mock parts;
const auto format = fmt::internal::to_string_view("0123456789");
fmt::internal::format_preparation_handler<char, parts_mock> handler(format,
parts);
const auto expected_first_arg_id = fmt::string_view(format.data(), 1);
const auto expected_first_arg_view_metadata =
fmt::internal::string_view_metadata(0, 1);
const auto expected_second_arg_id = fmt::string_view(format.data() + 3, 2);
const auto expected_second_arg_view_metadata =
fmt::internal::string_view_metadata(3, 2);
const auto expected_third_arg_id = fmt::string_view(format.data() + 6, 3);
const auto expected_third_arg_view_metadata =
fmt::internal::string_view_metadata(6, 3);
EXPECT_CALL(
parts,
add(format_part(named_argument_id(expected_first_arg_view_metadata))));
EXPECT_CALL(
parts,
add(format_part(named_argument_id(expected_second_arg_view_metadata))));
EXPECT_CALL(
parts,
add(format_part(named_argument_id(expected_third_arg_view_metadata))));
handler.on_arg_id(expected_first_arg_id);
handler.on_arg_id(expected_second_arg_id);
handler.on_arg_id(expected_third_arg_id);
}
TEST(CompileTest,
FormatPreparationHandler_OnReplacementField_SetsEndOfArgumentId) {
typedef fmt::internal::format_part<char> format_part;
typedef StrictMock<mock_parts_collector> parts_mock;
const auto format = fmt::internal::to_string_view("{:<}");
parts_mock parts;
const auto last_part = format_part(0u);
EXPECT_CALL(parts, last()).WillOnce(Return(last_part));
auto expected_substitution_part = last_part;
expected_substitution_part.end_of_argument_id = 1;
EXPECT_CALL(parts, substitute_last(expected_substitution_part));
fmt::internal::format_preparation_handler<char, parts_mock> handler(format,
parts);
handler.on_replacement_field(format.data() + 1);
}
TEST(
CompileTest,
FormatPreparationHandlerLastPartArgIndex_OnFormatSpecs_UpdatesLastAddedPart) {
typedef fmt::internal::format_part<char> format_part;
typedef StrictMock<mock_parts_collector> parts_mock;
parts_mock parts;
const auto specification_test_text = fmt::internal::to_string_view("{:<10}");
const auto specification_offset = 2u;
const auto specification_begin_it =
specification_test_text.begin() + specification_offset;
fmt::internal::format_preparation_handler<char, parts_mock> handler(
specification_test_text, parts);
const auto last_part = format_part(0u);
format_part::specification expected_specification(0u);
fmt::internal::dynamic_format_specs<char> specs{};
specs.align = fmt::align::left;
specs.width = 10;
expected_specification.parsed_specs = specs;
auto expected_substitution_part = format_part(expected_specification);
expected_substitution_part.end_of_argument_id = specification_offset;
EXPECT_CALL(parts, last()).WillOnce(Return(last_part));
EXPECT_CALL(parts, substitute_last(expected_substitution_part));
handler.on_format_specs(specification_begin_it,
specification_test_text.end());
}
TEST(
CompileTest,
FormatPreparationHandlerLastPartNamedArgIndex_OnFormatSpecs_UpdatesLastAddedPart) {
typedef fmt::internal::format_part<char> format_part;
typedef StrictMock<mock_parts_collector> parts_mock;
parts_mock parts;
const auto specification_test_text = fmt::internal::to_string_view("{:<10}");
const auto specification_offset = 2u;
const auto specification_begin_it =
specification_test_text.begin() + specification_offset;
fmt::internal::format_preparation_handler<char, parts_mock> handler(
specification_test_text, parts);
const auto arg_id = fmt::internal::string_view_metadata(0, 42);
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::align::left;
specs.width = 10;
expected_specification.parsed_specs = specs;
auto expected_substitution_part = format_part(expected_specification);
expected_substitution_part.end_of_argument_id = specification_offset;
EXPECT_CALL(parts, last()).WillOnce(Return(last_part));
EXPECT_CALL(parts, substitute_last(expected_substitution_part));
handler.on_format_specs(specification_begin_it,
specification_test_text.end());
}
// compiletime_prepared_parts_type_provider is useful only with relaxed
// constexpr.
#if FMT_USE_CONSTEXPR