diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 0009ca43c7c9..ea702f58b230 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -19,6 +19,8 @@ FMT_BEGIN_NAMESPACE +enum class range_format { disabled, map, set, sequence, string, debug_string }; + namespace detail { template class is_map { @@ -248,6 +250,18 @@ FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set) template FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {} +template +struct range_format_kind_ + : std::integral_constant, T>::value + ? range_format::disabled + : is_map::value ? range_format::map + : is_set::value ? range_format::set + : range_format::sequence> {}; + +template +using range_format_constant = std::integral_constant; + // These are not generic lambdas for compatibility with C++11. template struct parse_empty_specs { template FMT_CONSTEXPR void operator()(Formatter& f) { @@ -487,82 +501,59 @@ struct range_formatter< } }; -enum class range_format { disabled, map, set, sequence, string, debug_string }; - -namespace detail { -template -struct range_format_kind_ - : std::integral_constant, T>::value - ? range_format::disabled - : is_map::value ? range_format::map - : is_set::value ? range_format::set - : range_format::sequence> {}; - -template -struct range_default_formatter; - -template -using range_format_constant = std::integral_constant; +template +struct range_format_kind + : conditional_t< + is_range::value, detail::range_format_kind_, + std::integral_constant> {}; -template -struct range_default_formatter< - K, R, Char, - enable_if_t<(K == range_format::sequence || K == range_format::map || - K == range_format::set)>> { +template +struct formatter< + R, Char, + enable_if_t::value != + range_format::disabled> +// Workaround a bug in MSVC 2015 and earlier. +#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910 + , + detail::is_formattable_delayed +#endif + >::value>> { + private: using range_type = detail::maybe_const_range; - range_formatter, Char> underlying_; - - FMT_CONSTEXPR range_default_formatter() { init(range_format_constant()); } + range_formatter, Char> range_formatter_; - FMT_CONSTEXPR void init(range_format_constant) { - underlying_.set_brackets(detail::string_literal{}, - detail::string_literal{}); + FMT_CONSTEXPR void init(detail::range_format_constant) { + range_formatter_.set_brackets(detail::string_literal{}, + detail::string_literal{}); } - FMT_CONSTEXPR void init(range_format_constant) { - underlying_.set_brackets(detail::string_literal{}, - detail::string_literal{}); - underlying_.underlying().set_brackets({}, {}); - underlying_.underlying().set_separator( + FMT_CONSTEXPR void init(detail::range_format_constant) { + range_formatter_.set_brackets(detail::string_literal{}, + detail::string_literal{}); + range_formatter_.underlying().set_brackets({}, {}); + range_formatter_.underlying().set_separator( detail::string_literal{}); } - FMT_CONSTEXPR void init(range_format_constant) {} + FMT_CONSTEXPR void init( + detail::range_format_constant) {} + + public: + FMT_CONSTEXPR formatter() { + init(detail::range_format_constant::value>()); + } template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return underlying_.parse(ctx); + return range_formatter_.parse(ctx); } template auto format(range_type& range, FormatContext& ctx) const -> decltype(ctx.out()) { - return underlying_.format(range, ctx); + return range_formatter_.format(range, ctx); } }; -} // namespace detail - -template -struct range_format_kind - : conditional_t< - is_range::value, detail::range_format_kind_, - std::integral_constant> {}; - -template -struct formatter< - R, Char, - enable_if_t::value != - range_format::disabled> -// Workaround a bug in MSVC 2015 and earlier. -#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910 - , - detail::is_formattable_delayed -#endif - >::value>> - : detail::range_default_formatter::value, R, - Char> { -}; template struct join_view : detail::view {