Skip to content

Commit

Permalink
Disable problematic implicit conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Apr 9, 2023
1 parent 02bf4d1 commit fce74ca
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 60 deletions.
13 changes: 7 additions & 6 deletions include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,8 @@ 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_formatter<U, Context>::value &&
!std::is_const<remove_reference_t<T>>::value)> {};

template <typename T, FMT_ENABLE_IF(formattable<T>::value)>
FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
Expand All @@ -1453,11 +1454,11 @@ template <typename Context> struct arg_mapper {
}

template <typename T, typename U = remove_cvref_t<T>,
FMT_ENABLE_IF(!is_string<U>::value && !is_char<U>::value &&
!std::is_array<U>::value &&
!std::is_pointer<U>::value &&
!std::is_arithmetic<format_as_t<U>>::value &&
has_formatter<U, Context>::value)>
FMT_ENABLE_IF((std::is_class<U>::value || std::is_enum<U>::value ||
std::is_union<U>::value) &&
!is_string<U>::value && !is_char<U>::value &&
!is_named_arg<U>::value &&
!std::is_arithmetic<format_as_t<U>>::value)>
FMT_CONSTEXPR FMT_INLINE auto map(T&& val)
-> decltype(this->do_map(std::forward<T>(val))) {
return do_map(std::forward<T>(val));
Expand Down
22 changes: 2 additions & 20 deletions test/core-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,8 @@ TEST(core_test, is_formattable) {
static_assert(fmt::is_formattable<enabled_formatter>::value, "");
static_assert(!fmt::is_formattable<enabled_ptr_formatter*>::value, "");
static_assert(!fmt::is_formattable<disabled_formatter>::value, "");
static_assert(fmt::is_formattable<disabled_formatter_convertible>::value, "");
static_assert(!fmt::is_formattable<disabled_formatter_convertible>::value,
"");

static_assert(fmt::is_formattable<const_formattable&>::value, "");
static_assert(fmt::is_formattable<const const_formattable&>::value, "");
Expand Down Expand Up @@ -798,25 +799,6 @@ TEST(core_test, format_explicitly_convertible_to_std_string_view) {
# endif
#endif

struct convertible_to_long_long {
operator long long() const { return 1LL << 32; }
};

TEST(core_test, format_convertible_to_long_long) {
EXPECT_EQ("100000000", fmt::format("{:x}", convertible_to_long_long()));
}

struct disabled_rvalue_conversion {
operator const char*() const& { return "foo"; }
operator const char*() & { return "foo"; }
operator const char*() const&& = delete;
operator const char*() && = delete;
};

TEST(core_test, disabled_rvalue_conversion) {
EXPECT_EQ("foo", fmt::format("{}", disabled_rvalue_conversion()));
}

namespace adl_test {
template <typename... T> void make_format_args(const T&...) = delete;

Expand Down
14 changes: 9 additions & 5 deletions test/format-impl-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ TEST(fp_test, dragonbox_max_k) {
floor_log10_pow2(std::numeric_limits<float>::min_exponent -
fmt::detail::num_significand_bits<float>() - 1));
using double_info = fmt::detail::dragonbox::float_info<double>;
EXPECT_EQ(
fmt::detail::const_check(double_info::max_k),
double_info::kappa -
floor_log10_pow2(std::numeric_limits<double>::min_exponent -
2 * fmt::detail::num_significand_bits<double>() - 1));
EXPECT_EQ(fmt::detail::const_check(double_info::max_k),
double_info::kappa -
floor_log10_pow2(
std::numeric_limits<double>::min_exponent -
2 * fmt::detail::num_significand_bits<double>() - 1));
}

TEST(fp_test, get_round_direction) {
Expand Down Expand Up @@ -382,6 +382,8 @@ struct double_double {
auto operator-() const -> double_double { return double_double(-a, -b); }
};

auto format_as(double_double d) -> double { return d; }

bool operator>=(const double_double& lhs, const double_double& rhs) {
return lhs.a + lhs.b >= rhs.a + rhs.b;
}
Expand All @@ -394,6 +396,8 @@ struct slow_float {
auto operator-() const -> slow_float { return slow_float(-value); }
};

auto format_as(slow_float f) -> float { return f; }

namespace std {
template <> struct is_floating_point<double_double> : std::true_type {};
template <> struct numeric_limits<double_double> {
Expand Down
5 changes: 0 additions & 5 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1967,15 +1967,10 @@ struct formatter<adl_test::fmt::detail::foo> : formatter<std::string> {
};
FMT_END_NAMESPACE

struct convertible_to_int {
operator int() const { return 42; }
};

TEST(format_test, to_string) {
EXPECT_EQ(fmt::to_string(42), "42");
EXPECT_EQ(fmt::to_string(reinterpret_cast<void*>(0x1234)), "0x1234");
EXPECT_EQ(fmt::to_string(adl_test::fmt::detail::foo()), "foo");
EXPECT_EQ(fmt::to_string(convertible_to_int()), "42");
EXPECT_EQ(fmt::to_string(foo), "0");

#if FMT_USE_FLOAT128
Expand Down
24 changes: 0 additions & 24 deletions test/ostream-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -226,30 +226,6 @@ TEST(ostream_test, format_to_n) {
EXPECT_EQ("xabx", fmt::string_view(buffer, 4));
}

template <typename T> struct convertible {
T value;
explicit convertible(const T& val) : value(val) {}
operator T() const { return value; }
};

TEST(ostream_test, disable_builtin_ostream_operators) {
EXPECT_EQ("42", fmt::format("{:d}", convertible<unsigned short>(42)));
EXPECT_EQ("foo", fmt::format("{}", convertible<const char*>("foo")));
}

struct streamable_and_convertible_to_bool {
operator bool() const { return true; }
};

std::ostream& operator<<(std::ostream& os, streamable_and_convertible_to_bool) {
return os << "foo";
}

TEST(ostream_test, format_convertible_to_bool) {
// operator<< is intentionally not used because of potential ODR violations.
EXPECT_EQ(fmt::format("{}", streamable_and_convertible_to_bool()), "true");
}

struct copyfmt_test {};

std::ostream& operator<<(std::ostream& os, copyfmt_test) {
Expand Down

0 comments on commit fce74ca

Please sign in to comment.