fmtlib / fmt

A modern formatting library
https://fmt.dev
Other
19.83k stars 2.42k forks source link

Export `compiled_string` so that user can customize one #3999

Closed yujincheng08 closed 3 weeks ago

vitaut commented 3 weeks ago

Thanks for the PR. Could you elaborate what you mean by customizing a compile string?

yujincheng08 commented 3 weeks ago

@vitaut

Hi, I would like to do something like the following:


template <size_t N> struct FixedString {
  constexpr inline FixedString(const char (&str)[N]) {
    std::copy_n(str, N, data);
  }
  constexpr inline FixedString() {}
  char data[N] = {};
};

template <FixedString Str>
struct CompiledString : fmt::detail::compiled_string {
  using char_type = char;
  explicit constexpr inline operator fmt::basic_string_view<char_type>() const {
    return {Str.data, sizeof(Str.data) - 1};
  }
};

template <FixedString Str, typename... T>
constexpr inline void LOG(T &&...args)
{
  std::array<char, 1024> buf{};
  auto s = fmt::format_to_n(buf.data(), buf.size(), CompiledString<Str>{},
                            std::forward<T>(args)...)
               .size;
  buf[s] = '\0';
  write_log(buf.data());
}

LOG<"hello {}">("world");

Since there's a FMT_ENABLE_IF(detail::is_compiled_string<S>::value) requirement from fmt::format_to_n, I have to derive fmt::detail::compiled_string to call the compiled version of format_to_n.

vitaut commented 3 weeks ago

I think it would be better to move detail::udl_compiled_string to the public namespace (fmt) and drop the udl_ prefix. Then you won't need to reimplement it.

yujincheng08 commented 3 weeks ago

@vitaut In fact, I aslo want to add std::source_location to my FixedString, and in this case the udl_compiled_string which only accepts fmt::exported_detail::fixed_string may not be enough (I need to use my own FixedString).

vitaut commented 3 weeks ago

Merged, thanks!