Skip to content

Commit

Permalink
Support compile-time format string compilation (module)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielaE committed Jun 5, 2021
1 parent bf07456 commit 929f2ba
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
23 changes: 13 additions & 10 deletions include/fmt/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@
#include "format.h"

FMT_BEGIN_NAMESPACE
namespace detail {
FMT_MODULE_EXPORT_BEGIN

// compile-time support
namespace ct {
// A compile-time string which is compiled into fast formatting code.
class compiled_string {};
} // namespace ct

FMT_BEGIN_DETAIL_NAMESPACE

// An output iterator that counts the number of objects written to it and
// discards them.
Expand Down Expand Up @@ -137,11 +145,8 @@ class truncating_iterator<OutputIt, std::true_type>
truncating_iterator& operator*() { return *this; }
};

// A compile-time string which is compiled into fast formatting code.
class compiled_string {};

template <typename S>
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
struct is_compiled_string : std::is_base_of<fmt::ct::compiled_string, S> {};

/**
\rst
Expand All @@ -157,15 +162,14 @@ struct is_compiled_string : std::is_base_of<compiled_string, S> {};
\endrst
*/
#ifdef __cpp_if_constexpr
# define FMT_COMPILE(s) \
FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit)
# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::ct::compiled_string, explicit)
#else
# define FMT_COMPILE(s) FMT_STRING(s)
#endif

#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
template <typename Char, size_t N, fmt::ct::str<Char, N> Str>
struct udl_compiled_string : compiled_string {
struct udl_compiled_string : fmt::ct::compiled_string {
using char_type = Char;
constexpr operator basic_string_view<char_type>() const {
return {Str.data, N - 1};
Expand Down Expand Up @@ -527,9 +531,8 @@ constexpr auto compile(S format_str) {
}
}
#endif // __cpp_if_constexpr
} // namespace detail

FMT_MODULE_EXPORT_BEGIN
FMT_END_DETAIL_NAMESPACE

#ifdef __cpp_if_constexpr

Expand Down
1 change: 1 addition & 0 deletions include/fmt/fmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
}()

#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, )
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::ct::compiled_string, explicit)

import fmt;

Expand Down
10 changes: 10 additions & 0 deletions test/module-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ TEST(module_test, literals) {
EXPECT_EQ("42", "{}"_format(42));
EXPECT_EQ(L"42", fmt::format(L"{answer}", L"answer"_a = 42));
EXPECT_EQ(L"42", L"{}"_format(42));
EXPECT_EQ("", fmt::format(""_cf));
EXPECT_EQ("42", fmt::format("{}"_cf, 42));
}

TEST(module_test, locale) {
Expand Down Expand Up @@ -565,3 +567,11 @@ TEST(module_test, compile_time_string) {
fmt::vformat_to(wbuffer, FMT_STRING(L"{:}"), fmt::make_wformat_args(42));
EXPECT_EQ(L"42", std::wstring_view(wbuffer));
}

TEST(module_test, compile_format_string) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{0:x}"), 0x42));
EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{:}"), 42));
using namespace fmt::literals;
EXPECT_EQ("4.2", fmt::format(FMT_COMPILE("{arg:3.1f}"), "arg"_a = 4.2));
EXPECT_EQ(L" 42", fmt::format(FMT_COMPILE(L"{arg:>3}"), L"arg"_a = L"42"));
}

0 comments on commit 929f2ba

Please sign in to comment.