diff --git a/include/papilio/core.hpp b/include/papilio/core.hpp index 40b5488..dab6955 100755 --- a/include/papilio/core.hpp +++ b/include/papilio/core.hpp @@ -1338,34 +1338,65 @@ class streamable_formatter namespace detail { - template - concept is_formatter_disabled = std::is_base_of_v< - disabled_formatter, - formatter>; + enum class formatter_tag + { + disabled = 0, + ordinary = 1, + adl_func = 2, + stream = 3 + }; - template - struct select_formatter + template < + typename T, + typename Context, + typename CharT = typename Context::char_type> + consteval formatter_tag get_formatter_tag() + { + using fmt_t = formatter; + constexpr bool fmt_semiregular = std::semiregular; + + if constexpr(std::is_base_of_v) + { + return formatter_tag::disabled; + } + else if constexpr(!fmt_semiregular) + { + if constexpr(has_adl_format_v) + return formatter_tag::adl_func; + else if constexpr(streamable) + return formatter_tag::stream; + } + + return formatter_tag::ordinary; + } + + // For formatter_tag::ordinary and formatter_tag::disabled. + // Because a disabled formatter class is derived from papilio::disabled_formatter, + // so we can directly use the ordinary formatter to trigger an error. + template + struct select_formatter_impl { using type = formatter; }; template - requires(!is_formatter_disabled && !std::semiregular> && has_adl_format_v) - struct select_formatter + struct select_formatter_impl { using type = adl_format_adaptor; }; template - requires(!is_formatter_disabled && !std::semiregular> && !has_adl_format_v && streamable) - struct select_formatter + struct select_formatter_impl { using type = streamable_formatter; }; template - using select_formatter_t = - typename select_formatter::type; + using select_formatter_t = typename select_formatter_impl< + get_formatter_tag(), + T, + Context, + typename Context::char_type>::type; } // namespace detail PAPILIO_EXPORT template