fmtlib / fmt

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

support Literal-based API for custom data structure #2872

Closed xiamr closed 2 years ago

xiamr commented 2 years ago

Support custom data structure, for example:

using namespace fmt::literals;
fmt::print("current directory: {path}", "path"_a=boost::filesystem::current_path());
vitaut commented 2 years ago

The _a UDL supports user-defined types, e.g. (https://godbolt.org/z/51MxavqrP):

#include <fmt/format.h>

enum class color {red, green, blue};

template <> struct fmt::formatter<color>: formatter<string_view> {
  // parse is inherited from formatter<string_view>.
  template <typename FormatContext>
  auto format(color c, FormatContext& ctx) {
    string_view name = "unknown";
    switch (c) {
    case color::red:   name = "red"; break;
    case color::green: name = "green"; break;
    case color::blue:  name = "blue"; break;
    }
    return formatter<string_view>::format(name, ctx);
  }
};

int main() {
  using namespace fmt::literals;
  fmt::print("{color}", "color"_a=color::blue);
}
xiamr commented 2 years ago

In C++17 mode, the code is fine. But (gcc 11.3)... what's wrong with me.

g++ -std=c++20 a.cpp -I /data/software/fmt-8.1.1/include -L /data/software/fmt-8.1.1/lib64/ -lfmt 
In file included from /data/software/fmt-8.1.1/include/fmt/format.h:48,
                 from a.cpp:1:
/data/software/fmt-8.1.1/include/fmt/core.h: In instantiation of ‘constexpr decltype (ctx.begin()) fmt::v8::detail::parse_format_specs(ParseContext&) [with T = fmt::v8::detail::statically_named_arg<color, char, 6, fmt::v8::detail_exported::fixed_string<char, 6>{"color"}>; ParseContext = fmt::v8::detail::compile_parse_context<char, fmt::v8::detail::error_handler>; decltype (ctx.begin()) = const char*]’:
/data/software/fmt-8.1.1/include/fmt/core.h:2906:9:   required from ‘constexpr fmt::v8::detail::format_string_checker<Char, ErrorHandler, Args>::format_string_checker(fmt::v8::basic_string_view<Char>, ErrorHandler) [with Char = char; ErrorHandler = fmt::v8::detail::error_handler; Args = {fmt::v8::detail::statically_named_arg<color, char, 6, fmt::v8::detail_exported::fixed_string<char, 6>{"color"}>}’
a.cpp:21:12:   required from here
a.cpp:21:12:   in ‘constexpr’ expansion of ‘fmt::v8::basic_format_string<char, fmt::v8::detail::statically_named_arg<color, char, 6, fmt::v8::detail_exported::fixed_string<char, 6>{"color"}> >("{color}")’
/data/software/fmt-8.1.1/include/fmt/core.h:2672:12: error: use of deleted function ‘fmt::v8::detail::fallback_formatter<T, Char, Enable>::fallback_formatter() [with T = fmt::v8::detail::statically_named_arg<color, char, 6, fmt::v8::detail_exported::fixed_string<char, 6>{"color"}>; Char = char; Enable = void]’
 2672 |   auto f = conditional_t<has_formatter<mapped_type, context>::value,
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2673 |                          formatter<mapped_type, char_type>,
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2674 |                          fallback_formatter<T, char_type>>();
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/data/software/fmt-8.1.1/include/fmt/core.h:1041:3: note: declared here
 1041 |   fallback_formatter() = delete;
      |   ^~~~~~~~~~~~~~~~~~
xiamr commented 2 years ago

version 8.1.1 has this bug, but the trunk version is ok

企业微信截图_16511935716034