Skip to content

Commit

Permalink
Simplify has_formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Sep 17, 2024
1 parent 7ce0139 commit e20407f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 23 deletions.
33 changes: 13 additions & 20 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -1107,27 +1107,20 @@ struct use_formatter
!has_to_string_view<T>::value && !is_named_arg<T>::value &&
!use_format_as<T>::value> {};

template <typename Char, typename T>
constexpr auto has_const_formatter_impl(T*)
-> decltype(formatter<T, Char>().format(
std::declval<const T&>(),
std::declval<buffered_context<Char>&>()),
true) {
return true;
}
template <typename Char> constexpr auto has_const_formatter_impl(...) -> bool {
return false;
}
template <typename T, typename Char>
constexpr auto has_const_formatter() -> bool {
return has_const_formatter_impl<Char>(static_cast<T*>(nullptr));
template <typename Char, typename T,
FMT_ENABLE_IF(sizeof(formatter<remove_const_t<T>, Char>().format(
std::declval<T&>(),
std::declval<buffered_context<Char>&>())) != 0)>
auto has_formatter_impl(T*) -> std::true_type;
template <typename> auto has_formatter_impl(...) -> std::false_type;

// T can be const-qualified to check if it is const-formattable.
template <typename T, typename Char> constexpr auto has_formatter() -> bool {
return decltype(has_formatter_impl<Char>(static_cast<T*>(nullptr)))::value;
}

template <typename T, typename Char, typename U = remove_const_t<T>>
struct formattable
: bool_constant<has_const_formatter<U, Char>() ||
(std::is_constructible<formatter<U, Char>>::value &&
!std::is_const<T>::value)> {};
template <typename T, typename Char>
struct formattable : bool_constant<has_formatter<T, Char>()> {};

// Maps formatting argument types to natively supported types or user-defined
// types with formatters. Returns void on errors to be SFINAE-friendly.
Expand Down Expand Up @@ -2223,7 +2216,7 @@ template <typename Context> class value {
auto f = Formatter();
parse_ctx.advance_to(f.parse(parse_ctx));
using qualified_type =
conditional_t<has_const_formatter<T, char_type>(), const T, T>;
conditional_t<has_formatter<const T, char_type>(), const T, T>;
// format must be const for compatibility with std::format and compilation.
const auto& cf = f;
ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));
Expand Down
6 changes: 3 additions & 3 deletions test/base-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -784,10 +784,10 @@ TEST(base_test, format_explicitly_convertible_to_std_string_view) {
# endif
#endif

TEST(base_test, has_const_formatter) {
EXPECT_TRUE((fmt::detail::has_const_formatter<const_formattable, char>()));
TEST(base_test, has_formatter) {
EXPECT_TRUE((fmt::detail::has_formatter<const const_formattable, char>()));
EXPECT_FALSE(
(fmt::detail::has_const_formatter<nonconst_formattable, char>()));
(fmt::detail::has_formatter<const nonconst_formattable, char>()));
}

TEST(base_test, format_nonconst) {
Expand Down

0 comments on commit e20407f

Please sign in to comment.