Skip to content

Commit 0ff59ad

Browse files
committed
Remove dependency on fmt in favour of std::format
1 parent 196aae3 commit 0ff59ad

15 files changed

Lines changed: 84 additions & 101 deletions

File tree

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ Using [vcpkg](https://github.com/microsoft/vcpkg):
6868
Manual installation:
6969

7070
- Install CMake 3.14 or higher.
71-
- For the library, install the following packages so that CMake's `find_package` can find them:
72-
* [fmt](https://github.com/fmtlib/fmt)
71+
- The library itself has no third party dependencies. Earlier versions required [fmt](https://github.com/fmtlib/fmt).
7372
- For the tests, install the following packages so that CMake's `find_package` can find them:
7473
* [cairo](https://www.cairographics.org)
7574
* [doctest](https://github.com/onqtam/doctest)
@@ -141,7 +140,7 @@ the principles behind the layout of most formula elements.
141140
Many thanks to the authors and contributors of the following third party libraries, fonts,
142141
tools and services with which *mfl* is developed, built and tested:
143142

144-
- [**fmt**](https://github.com/fmtlib/fmt) for text formatting
143+
- [**fmt**](https://github.com/fmtlib/fmt) for text formatting (used in earlier versions, but now no longer needed)
145144
- [**Clang**](https://clang.llvm.org) for compilation, standard library, static analysis, sanitizers and code formatting
146145
- [**GCC**](https://gcc.gnu.org) for compilation, standard library
147146
- [**CMake**](https://cmake.org) for build automation

include/mfl/detail/quantity.hpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

3-
#include <fmt/format.h>
4-
3+
#include <format>
54
#include <iostream>
65

76
namespace mfl::detail
@@ -41,33 +40,38 @@ namespace mfl::detail
4140
friend constexpr quantity operator+(const quantity x0, const quantity x1)
4241
{
4342
auto result = x0;
44-
return result += x1;
43+
result += x1;
44+
return result;
4545
}
4646

4747
friend constexpr quantity operator-(const quantity x0, const quantity x1)
4848
{
4949
auto result = x0;
50-
return result -= x1;
50+
result -= x1;
51+
return result;
5152
}
5253

5354
friend constexpr quantity operator-(const quantity x) { return quantity(-x.value()); }
5455

5556
friend constexpr quantity operator*(const quantity x, const double scalar)
5657
{
5758
auto result = x;
58-
return result *= scalar;
59+
result *= scalar;
60+
return result;
5961
}
6062

6163
friend constexpr quantity operator*(const double scalar, const quantity x)
6264
{
6365
auto result = x;
64-
return result *= scalar;
66+
result *= scalar;
67+
return result;
6568
}
6669

6770
friend constexpr quantity operator/(const quantity x, const double scalar)
6871
{
6972
auto result = x;
70-
return result /= scalar;
73+
result /= scalar;
74+
return result;
7175
}
7276

7377
friend constexpr double operator/(const quantity x0, const quantity x1) { return x0.value_ / x1.value_; }
@@ -81,7 +85,5 @@ namespace mfl::detail
8185

8286
template <typename Tag>
8387
std::ostream& operator<<(std::ostream& os, const quantity<Tag>& p)
84-
{
85-
return os << fmt::format("{}", p);
86-
}
88+
{ return os << std::format("{}", p); }
8789
}

include/mfl/units.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
#include "mfl/detail/quantity.hpp"
44

5-
#include <fmt/core.h>
6-
75
#include <array>
6+
#include <format>
87

98
namespace mfl
109
{
@@ -36,18 +35,18 @@ namespace mfl
3635
template <typename Unit, char c0 = 0, char c1 = 0, char c2 = 0>
3736
struct unit_formatter
3837
{
39-
constexpr auto parse(const fmt::format_parse_context& ctx) { return ctx.begin(); }
38+
constexpr auto parse(const std::format_parse_context& ctx) { return ctx.begin(); }
4039

4140
template <typename FormatContext>
4241
constexpr auto format(const Unit x, FormatContext& ctx) const
4342
{
4443
constexpr auto suffix = std::array{c0, c1, c2, '\0'};
45-
return fmt::format_to(ctx.out(), "{}{}", x.value(), suffix.data());
44+
return std::format_to(ctx.out(), "{}{}", x.value(), suffix.data());
4645
}
4746
};
4847
}
4948

50-
namespace fmt
49+
namespace std
5150
{
5251
template <>
5352
struct [[maybe_unused]] formatter<mfl::inches> : mfl::unit_formatter<mfl::inches, '\"'>

src/CMakeLists.txt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
cmake_minimum_required (VERSION 3.14)
1+
cmake_minimum_required(VERSION 3.14)
22

3-
find_package(fmt REQUIRED)
43
find_package(Threads)
54

65
add_library(mfl
@@ -45,18 +44,17 @@ add_library(mfl
4544
parser/utf8.cpp
4645
settings.cpp
4746
units.cpp
48-
)
47+
)
4948

5049
target_include_directories(mfl PUBLIC
5150
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
5251
$<INSTALL_INTERFACE:include>
53-
)
52+
)
5453
target_include_directories(mfl PRIVATE ${PROJECT_SOURCE_DIR}/src)
5554

5655
target_link_libraries(mfl
5756
PUBLIC
5857
mfl_options
5958
mfl_warnings
60-
fmt::fmt
6159
${CMAKE_THREAD_LIBS_INIT}
62-
)
60+
)

src/parser/left_right.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
#include "parser/parser_state.hpp"
44
#include "parser/parser_utilities.hpp"
55

6-
#include <fmt/format.h>
7-
86
#include <algorithm>
7+
#include <format>
98
#include <string>
109

1110
namespace mfl::parser
@@ -61,7 +60,7 @@ namespace mfl::parser
6160
const auto full_name = ((tok == tokens::command) ? "\\"s : ""s) + name;
6261
if (const auto type = get_delimiter_type(full_name); !is_valid_token or (type == delimiter_type::none))
6362
{
64-
state.set_error(fmt::format("'{}' is not a valid delimiter.", full_name));
63+
state.set_error(std::format("'{}' is not a valid delimiter.", full_name));
6564
return 0;
6665
}
6766

src/parser/parser_state.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "parser/parser_state.hpp"
22

3-
#include <fmt/format.h>
3+
#include <format>
44

55
namespace mfl::parser
66
{
@@ -17,7 +17,7 @@ namespace mfl::parser
1717
if (lexer_token() == tokens::eof)
1818
set_error("unexpected end of input.");
1919
else if (lexer_token() != tok)
20-
set_error(fmt::format("unexpected {} while expecting {}.", to_string(lexer_token()), to_string(tok)));
20+
set_error(std::format("unexpected {} while expecting {}.", to_string(lexer_token()), to_string(tok)));
2121
else
2222
lexer_.move_to_next_token();
2323
}
@@ -43,7 +43,7 @@ namespace mfl::parser
4343

4444
void parser_state::set_error(const std::string& error_text)
4545
{
46-
error_ = fmt::format("Syntax error: {}", error_text);
46+
error_ = std::format("Syntax error: {}", error_text);
4747

4848
while (lexer_token() != tokens::eof)
4949
lexer_.move_to_next_token();

src/parser/parser_utilities.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55
#include "parser/parser_state.hpp"
66
#include "parser/script.hpp"
77

8-
#include <fmt/format.h>
9-
108
#include <algorithm>
11-
#include <charconv>
12-
#include <cstdlib>
9+
#include <format>
1310

1411
namespace mfl::parser
1512
{
@@ -27,7 +24,7 @@ namespace mfl::parser
2724
}
2825

2926
auto noads = create_script(state);
30-
std::move(noads.begin(), noads.end(), std::back_inserter(result.noads));
27+
std::ranges::move(noads, std::back_inserter(result.noads));
3128
tok = state.lexer_token();
3229
}
3330

@@ -42,7 +39,7 @@ namespace mfl::parser
4239
{
4340
if (state.lexer_token() == tokens::eof)
4441
{
45-
state.set_error(fmt::format("expected token not found: '{}'.", value));
42+
state.set_error(std::format("expected token not found: '{}'.", value));
4643
return {};
4744
}
4845

@@ -114,17 +111,12 @@ namespace mfl::parser
114111

115112
state.consume_token(tokens::close_brace);
116113

117-
char* str_end = nullptr;
118-
const auto value = std::strtod(number_string.c_str(), &str_end);
119-
// using the C function std::strtod until from_chars is available, so we have to do some pointer arithmetic
120-
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
121-
if (str_end != number_string.data() + number_string.size())
122-
state.set_error(fmt::format("'{}' does not represent a valid floating point value.", number_string));
123-
124-
// TODO - do this instead when from_chars becomes available ...
125-
// const auto result = std::from_chars(number_string.data(), number_string.data() + number_string.size(),
126-
// &value); if (result.ec == std::errc::invalid_argument)
127-
// state.set_error(fmt::format("'{}' does not represent a valid floating point value.", number_string));
114+
double value = 0.0;
115+
const auto [remaining, ec] =
116+
std::from_chars(number_string.data(), number_string.data() + number_string.size(), value);
117+
118+
if ((ec == std::errc::invalid_argument) || !std::string(remaining).empty())
119+
state.set_error(std::format("'{}' does not represent a valid floating point value.", number_string));
128120

129121
return value;
130122
}

src/parser/scanner.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#pragma once
22

3-
#include <fmt/format.h>
4-
53
#include <concepts>
6-
#include <iostream>
74
#include <istream>
85
#include <string>
96

src/parser/unicode_index.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
#include "parser/symbols/relational_operators.hpp"
1414
#include "parser/utf8.hpp"
1515

16-
#include <fmt/format.h>
17-
1816
#include <array>
17+
#include <format>
1918
#include <span>
2019
#include <tuple>
2120
#include <utility>
@@ -67,7 +66,7 @@ namespace mfl::parser
6766
if (const auto result = check(negations, tex_name)) return result;
6867
if (const auto result = check(additional_negations, tex_name)) return result;
6968

70-
state.set_error(fmt::format("Unknown symbol name '\\{}'.", tex_name));
69+
state.set_error(std::format("Unknown symbol name '\\{}'.", tex_name));
7170
return 0;
7271
}
7372

@@ -212,7 +211,7 @@ namespace mfl::parser
212211
const auto result = utf8::to_ucs4(name);
213212
if (!result)
214213
{
215-
state.set_error(fmt::format("'{}' does not represent a valid utf8 character.", name));
214+
state.set_error(std::format("'{}' does not represent a valid utf8 character.", name));
216215
return 0;
217216
}
218217

tests/approval_tests/docs.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include "parser/symbols/relational_operators.hpp"
1515

1616
#include <doctest/doctest.h>
17-
#include <fmt/format.h>
1817

18+
#include <format>
1919
#include <ranges>
2020

2121
namespace mfl
@@ -34,14 +34,15 @@ namespace mfl
3434

3535
auto render_symbols(const symbol_render_config& config, const std::ranges::range auto& symbols)
3636
{
37-
const auto d = std::div(long(std::ranges::distance(symbols)), long(config.num_columns));
38-
const auto num_rows = size_t(d.quot + ((d.rem > 0) ? 1 : 0));
39-
const auto width = 720_px;
40-
const auto height = double(num_rows) * config.line_height + 40_px;
37+
const auto num_symbols = static_cast<long>(std::ranges::distance(symbols));
38+
const auto [quot, rem] = std::div(num_symbols, static_cast<long>(config.num_columns));
39+
const auto num_rows = static_cast<size_t>(quot + ((rem > 0) ? 1 : 0));
40+
constexpr auto width = 720_px;
41+
const auto height = static_cast<double>(num_rows) * config.line_height + 40_px;
4142
auto columns = std::vector<column_config>(config.num_columns);
4243
for (auto&& [i, col] : std::views::enumerate(columns))
4344
{
44-
col.x = (double(i) * (width / double(config.num_columns))) + 10_px;
45+
col.x = (static_cast<double>(i) * (width / static_cast<double>(config.num_columns))) + 10_px;
4546
col.line_height = config.line_height;
4647
col.num_rows = num_rows;
4748
}
@@ -183,9 +184,10 @@ namespace mfl
183184

184185
TEST_CASE("accents")
185186
{
186-
const auto formulas = parser::accents //
187-
| std::views::keys //
188-
| std::views::transform([](const char* name) { return fmt::format("{}{{a}}", name); });
187+
constexpr auto formulas =
188+
parser::accents //
189+
| std::views::keys //
190+
| std::views::transform([](const char* name) { return std::format("{}{{a}}", name); });
189191
const auto result = render_symbols({.num_columns = 5}, formulas);
190192

191193
approve_svg(result);
@@ -213,9 +215,10 @@ namespace mfl
213215
TEST_CASE("additional_accents")
214216
{
215217
// TODO - some additional accents are set in the wrong place
216-
const auto formulas = parser::additional_accents //
217-
| std::views::keys //
218-
| std::views::transform([](const char* name) { return fmt::format("{}{{a}}", name); });
218+
constexpr auto formulas =
219+
parser::additional_accents //
220+
| std::views::keys //
221+
| std::views::transform([](const char* name) { return std::format("{}{{a}}", name); });
219222
const auto result = render_symbols({.num_columns = 3}, formulas);
220223

221224
approve_svg(result);
@@ -310,10 +313,10 @@ namespace mfl
310313

311314
TEST_CASE("delimiters")
312315
{
313-
const auto formulas =
316+
constexpr auto formulas =
314317
std::views::zip(parser::left_delimiters | std::views::keys, parser::right_delimiters | std::views::keys)
315318
| std::views::transform(
316-
[](const auto delims) { return fmt::format("{} x \\{}", std::get<0>(delims), std::get<1>(delims)); });
319+
[](const auto delims) { return std::format("{} x \\{}", std::get<0>(delims), std::get<1>(delims)); });
317320
const auto result = render_symbols({.num_columns = 2, .input_offset = 40_px}, formulas);
318321

319322
approve_svg(result);
@@ -420,9 +423,9 @@ namespace mfl
420423

421424
TEST_CASE("combining_symbols")
422425
{
423-
const auto formulas = parser::combining_symbols //
424-
| std::views::keys //
425-
| std::views::transform([](const char* name) { return fmt::format("c \\{}", name); });
426+
constexpr auto formulas = parser::combining_symbols //
427+
| std::views::keys //
428+
| std::views::transform([](const char* name) { return std::format("c \\{}", name); });
426429
const auto result = render_formulas({.width = 720_px,
427430
.height = 100_px,
428431
.render_input = true,

0 commit comments

Comments
 (0)