Remove deprecated fallback formatter

This commit is contained in:
Victor Zverovich 2023-03-26 08:40:12 -07:00
parent 41cfc739fe
commit 19c074e477
4 changed files with 19 additions and 99 deletions

View File

@ -1160,20 +1160,6 @@ auto get_iterator(buffer<T>&, OutputIt out) -> OutputIt {
return out;
}
template <typename T, typename Char = char, typename Enable = void>
struct fallback_formatter {
fallback_formatter() = delete;
};
// Specifies if T has an enabled fallback_formatter specialization.
template <typename T, typename Char>
using has_fallback_formatter =
#ifdef FMT_DEPRECATED_OSTREAM
std::is_constructible<fallback_formatter<T, Char>>;
#else
std::false_type;
#endif
struct view {};
template <typename Char, typename T> struct named_arg : view {
@ -1332,10 +1318,7 @@ template <typename Context> class value {
// have different extension points, e.g. `formatter<T>` for `format` and
// `printf_formatter<T>` for `printf`.
custom.format = format_custom_arg<
value_type,
conditional_t<has_formatter<value_type, Context>::value,
typename Context::template formatter_type<value_type>,
fallback_formatter<value_type, char_type>>>;
value_type, typename Context::template formatter_type<value_type>>;
}
value(unformattable);
value(unformattable_char);
@ -1493,8 +1476,7 @@ template <typename Context> struct arg_mapper {
template <typename T, typename U = remove_cvref_t<T>>
struct formattable
: bool_constant<has_const_formatter<U, Context>() ||
!std::is_const<remove_reference_t<T>>::value ||
has_fallback_formatter<U, char_type>::value> {};
!std::is_const<remove_reference_t<T>>::value> {};
#if (FMT_MSC_VERSION != 0 && FMT_MSC_VERSION < 1910) || \
FMT_ICC_VERSION != 0 || defined(__NVCC__)
@ -1518,8 +1500,7 @@ template <typename Context> struct arg_mapper {
!std::is_array<U>::value &&
!std::is_pointer<U>::value &&
!std::is_arithmetic<format_as_t<U>>::value &&
(has_formatter<U, Context>::value ||
has_fallback_formatter<U, char_type>::value))>
has_formatter<U, Context>::value)>
FMT_CONSTEXPR FMT_INLINE auto map(T&& val)
-> decltype(this->do_map(std::forward<T>(val))) {
return do_map(std::forward<T>(val));
@ -1770,9 +1751,9 @@ FMT_CONSTEXPR auto make_arg(T&& value) -> basic_format_arg<Context> {
return arg;
}
// The type template parameter is there to avoid an ODR violation when using
// a fallback formatter in one translation unit and an implicit conversion in
// another (not recommended).
// The DEPRECATED type template parameter is there to avoid an ODR violation
// when using a fallback formatter in one translation unit and an implicit
// conversion in another (not recommended).
template <bool IS_PACKED, typename Context, type, typename T,
FMT_ENABLE_IF(IS_PACKED)>
FMT_CONSTEXPR FMT_INLINE auto make_arg(T&& val) -> value<Context> {
@ -1843,11 +1824,9 @@ using buffer_context =
using format_context = buffer_context<char>;
template <typename T, typename Char = char>
using is_formattable = bool_constant<
!std::is_base_of<detail::unformattable,
decltype(detail::arg_mapper<buffer_context<Char>>().map(
std::declval<T>()))>::value &&
!detail::has_fallback_formatter<T, Char>::value>;
using is_formattable = bool_constant<!std::is_base_of<
detail::unformattable, decltype(detail::arg_mapper<buffer_context<Char>>()
.map(std::declval<T>()))>::value>;
/**
\rst
@ -2631,10 +2610,7 @@ FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx)
mapped_type_constant<T, context>::value != type::custom_type,
decltype(arg_mapper<context>().map(std::declval<const T&>())),
stripped_type>;
auto f = conditional_t<has_formatter<mapped_type, context>::value,
formatter<mapped_type, char_type>,
fallback_formatter<stripped_type, char_type>>();
return f.parse(ctx);
return formatter<mapped_type, char_type>().parse(ctx);
}
// Checks char specs and returns true iff the presentation type is char-like.

View File

@ -3891,12 +3891,8 @@ template <typename Char, typename OutputIt, typename T,
FMT_CONSTEXPR auto write(OutputIt out, const T& value)
-> enable_if_t<mapped_type_constant<T, Context>::value == type::custom_type,
OutputIt> {
using formatter_type =
conditional_t<has_formatter<T, Context>::value,
typename Context::template formatter_type<T>,
fallback_formatter<T, Char>>;
auto ctx = Context(out, {}, {});
return formatter_type().format(value, ctx);
return typename Context::template formatter_type<T>().format(value, ctx);
}
// An argument visitor that formats the argument and writes it via the output
@ -4382,12 +4378,7 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
#else
typename std::iterator_traits<It>::value_type;
#endif
using formatter_type =
conditional_t<is_formattable<value_type, Char>::value,
formatter<remove_cvref_t<value_type>, Char>,
detail::fallback_formatter<value_type, Char>>;
formatter_type value_formatter_;
formatter<remove_cvref_t<value_type>, Char> value_formatter_;
public:
template <typename ParseContext>

View File

@ -8,8 +8,8 @@
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include <fstream>
#include <ostream>
#include <fstream> // std::filebuf
#if defined(_WIN32) && defined(__GLIBCXX__)
# include <ext/stdio_filebuf.h>
# include <ext/stdio_sync_filebuf.h>
@ -21,42 +21,8 @@
FMT_BEGIN_NAMESPACE
template <typename OutputIt, typename Char> class basic_printf_context;
namespace detail {
// Checks if T has a user-defined operator<<.
template <typename T, typename Char, typename Enable = void>
class is_streamable {
private:
template <typename U>
static auto test(int)
-> bool_constant<sizeof(std::declval<std::basic_ostream<Char>&>()
<< std::declval<U>()) != 0>;
template <typename> static auto test(...) -> std::false_type;
using result = decltype(test<T>(0));
public:
is_streamable() = default;
static const bool value = result::value;
};
// Formatting of built-in types and arrays is intentionally disabled because
// it's handled by standard (non-ostream) formatters.
template <typename T, typename Char>
struct is_streamable<
T, Char,
enable_if_t<
std::is_arithmetic<T>::value || std::is_array<T>::value ||
std::is_pointer<T>::value || std::is_same<T, char8_type>::value ||
std::is_convertible<T, fmt::basic_string_view<Char>>::value ||
std::is_same<T, std_string_view<Char>>::value ||
(std::is_convertible<T, int>::value && !std::is_enum<T>::value)>>
: std::false_type {};
// Generate a unique explicit instantion in every translation unit using a tag
// type in an anonymous namespace.
namespace {
@ -180,13 +146,6 @@ auto streamed(const T& value) -> detail::streamed_view<T> {
namespace detail {
// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
: basic_ostream_formatter<Char> {
using basic_ostream_formatter<Char>::format;
};
inline void vprint_directly(std::ostream& os, string_view format_str,
format_args args) {
auto buffer = memory_buffer();

View File

@ -404,12 +404,10 @@ template <typename Context> struct range_mapper {
};
template <typename Char, typename Element>
using range_formatter_type = conditional_t<
is_formattable<Element, Char>::value,
using range_formatter_type =
formatter<remove_cvref_t<decltype(range_mapper<buffer_context<Char>>{}.map(
std::declval<Element>()))>,
Char>,
fallback_formatter<Element, Char>>;
Char>;
template <typename R>
using maybe_const_range =
@ -419,9 +417,7 @@ using maybe_const_range =
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
template <typename R, typename Char>
struct is_formattable_delayed
: disjunction<
is_formattable<uncvref_type<maybe_const_range<R>>, Char>,
has_fallback_formatter<uncvref_type<maybe_const_range<R>>, Char>> {};
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
#endif
} // namespace detail
@ -431,10 +427,8 @@ struct range_formatter;
template <typename T, typename Char>
struct range_formatter<
T, Char,
enable_if_t<conjunction<
std::is_same<T, remove_cvref_t<T>>,
disjunction<is_formattable<T, Char>,
detail::has_fallback_formatter<T, Char>>>::value>> {
enable_if_t<conjunction<std::is_same<T, remove_cvref_t<T>>,
is_formattable<T, Char>>::value>> {
private:
detail::range_formatter_type<Char, T> underlying_;
basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};