mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-24 12:14:26 +00:00
Disable problematic implicit conversions
This commit is contained in:
parent
02bf4d1c1c
commit
fce74caa15
@ -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& {
|
||||
@ -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));
|
||||
|
@ -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, "");
|
||||
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
@ -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;
|
||||
}
|
||||
@ -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> {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user