Fix constness

This commit is contained in:
Victor Zverovich 2024-01-14 06:34:25 -08:00
parent 362b40c1a3
commit d70729215f
11 changed files with 67 additions and 51 deletions

View File

@ -12,6 +12,7 @@
#include <stdio.h> // FILE
#include <string.h> // strlen
// <cstddef> is also included transitively from <type_traits>.
#include <cstddef> // std::byte
#include <type_traits> // std::enable_if
@ -1332,8 +1333,9 @@ template <typename Context> class value {
parse_ctx.advance_to(f.parse(parse_ctx));
using qualified_type =
conditional_t<has_const_formatter<T, Context>(), const T, T>;
// Calling format through a mutable reference is deprecated.
ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx));
// 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));
}
};

View File

@ -4121,12 +4121,13 @@ template <> struct formatter<bytes> {
}
template <typename FormatContext>
auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
specs_.width_ref, ctx);
auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) {
auto specs = specs_;
detail::handle_dynamic_spec<detail::width_checker>(specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx);
return detail::write_bytes(ctx.out(), b.data_, specs_);
specs.precision, specs.precision_ref, ctx);
return detail::write_bytes(ctx.out(), b.data_, specs);
}
};
@ -4162,15 +4163,16 @@ template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
}
template <typename FormatContext>
auto format(group_digits_view<T> t, FormatContext& ctx)
auto format(group_digits_view<T> t, FormatContext& ctx) const
-> decltype(ctx.out()) {
detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
specs_.width_ref, ctx);
auto specs = specs_;
detail::handle_dynamic_spec<detail::width_checker>(specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx);
return detail::write_int(
ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_,
detail::digit_grouping<char>("\3", ","));
specs.precision, specs.precision_ref, ctx);
return detail::write_int(ctx.out(),
static_cast<detail::uint64_or_128_t<T>>(t.value),
0, specs, detail::digit_grouping<char>("\3", ","));
}
};

View File

@ -35,7 +35,7 @@ struct type_with_get {
FMT_BEGIN_NAMESPACE
template <> struct formatter<type_with_get> : formatter<int> {
template <typename FormatContext>
auto format(type_with_get, FormatContext& ctx) -> decltype(ctx.out()) {
auto format(type_with_get, FormatContext& ctx) const -> decltype(ctx.out()) {
return formatter<int>::format(42, ctx);
}
};

View File

@ -9,8 +9,6 @@
#include "test-assert.h"
// clang-format on
#include "fmt/base.h"
#include <climits> // INT_MAX
#include <cstring> // std::strlen
#include <functional> // std::equal_to
@ -19,6 +17,7 @@
#include <string> // std::string
#include <type_traits> // std::is_same
#include "fmt/base.h"
#include "gmock/gmock.h"
using fmt::string_view;
@ -280,7 +279,7 @@ struct custom_context {
return ctx.begin();
}
const char* format(const T&, custom_context& ctx) {
const char* format(const T&, custom_context& ctx) const {
ctx.called = true;
return nullptr;
}
@ -602,7 +601,7 @@ template <> struct formatter<const_formattable> {
return ctx.begin();
}
auto format(const const_formattable&, format_context& ctx)
auto format(const const_formattable&, format_context& ctx) const
-> decltype(ctx.out()) {
return copy("test", ctx.out());
}
@ -613,7 +612,7 @@ template <> struct formatter<nonconst_formattable> {
return ctx.begin();
}
auto format(nonconst_formattable&, format_context& ctx)
auto format(nonconst_formattable&, format_context& ctx) const
-> decltype(ctx.out()) {
return copy("test", ctx.out());
}
@ -807,7 +806,8 @@ template <> struct formatter<its_a_trap> {
return ctx.begin();
}
auto format(its_a_trap, format_context& ctx) const -> decltype(ctx.out()) {
auto format(its_a_trap, format_context& ctx) const
-> decltype(ctx.out()) const {
auto out = ctx.out();
*out++ = 'x';
return out;

View File

@ -1590,7 +1590,8 @@ struct string_viewable {};
FMT_BEGIN_NAMESPACE
template <> struct formatter<string_viewable> : formatter<std::string_view> {
auto format(string_viewable, format_context& ctx) -> decltype(ctx.out()) {
auto format(string_viewable, format_context& ctx) const
-> decltype(ctx.out()) {
return formatter<std::string_view>::format("foo", ctx);
}
};
@ -1608,8 +1609,8 @@ struct explicitly_convertible_to_std_string_view {
template <>
struct fmt::formatter<explicitly_convertible_to_std_string_view>
: formatter<std::string_view> {
auto format(explicitly_convertible_to_std_string_view v, format_context& ctx)
-> decltype(ctx.out()) {
auto format(explicitly_convertible_to_std_string_view v,
format_context& ctx) const -> decltype(ctx.out()) {
return fmt::format_to(ctx.out(), "'{}'", std::string_view(v));
}
};
@ -1631,7 +1632,7 @@ template <> struct formatter<date> {
return it;
}
auto format(const date& d, format_context& ctx) -> decltype(ctx.out()) {
auto format(const date& d, format_context& ctx) const -> decltype(ctx.out()) {
// Namespace-qualify to avoid ambiguity with std::format_to.
fmt::format_to(ctx.out(), "{}-{}-{}", d.year(), d.month(), d.day());
return ctx.out();
@ -1640,7 +1641,7 @@ template <> struct formatter<date> {
template <> struct formatter<Answer> : formatter<int> {
template <typename FormatContext>
auto format(Answer, FormatContext& ctx) -> decltype(ctx.out()) {
auto format(Answer, FormatContext& ctx) const -> decltype(ctx.out()) {
return formatter<int>::format(42, ctx);
}
};
@ -1903,7 +1904,7 @@ template <typename, typename OutputIt> void write(OutputIt, foo) = delete;
FMT_BEGIN_NAMESPACE
template <>
struct formatter<adl_test::fmt::detail::foo> : formatter<std::string> {
auto format(adl_test::fmt::detail::foo, format_context& ctx)
auto format(adl_test::fmt::detail::foo, format_context& ctx) const
-> decltype(ctx.out()) {
return formatter<std::string>::format("foo", ctx);
}
@ -2072,7 +2073,7 @@ template <> struct formatter<check_back_appender> {
}
template <typename Context>
auto format(check_back_appender, Context& ctx) -> decltype(ctx.out()) {
auto format(check_back_appender, Context& ctx) const -> decltype(ctx.out()) {
auto out = ctx.out();
static_assert(std::is_same<decltype(++out), decltype(out)&>::value,
"needs to satisfy weakly_incrementable");

View File

@ -201,7 +201,8 @@ auto operator<<(std::ostream& os, test_template<T>) -> std::ostream& {
namespace fmt {
template <typename T> struct formatter<test_template<T>> : formatter<int> {
auto format(test_template<T>, format_context& ctx) -> decltype(ctx.out()) {
auto format(test_template<T>, format_context& ctx) const
-> decltype(ctx.out()) {
return formatter<int>::format(2, ctx);
}
};

View File

@ -393,7 +393,8 @@ TEST(buffered_file_test, open_retry) {
TEST(buffered_file_test, close_no_retry_in_dtor) {
auto pipe = fmt::pipe();
std::unique_ptr<buffered_file> f(new buffered_file(pipe.read_end.fdopen("r")));
std::unique_ptr<buffered_file> f(
new buffered_file(pipe.read_end.fdopen("r")));
int saved_fclose_count = 0;
EXPECT_WRITE(
stderr,

View File

@ -310,10 +310,14 @@ TEST(printf_test, dynamic_precision) {
}
}
template <typename T> struct make_signed { using type = T; };
template <typename T> struct make_signed {
using type = T;
};
#define SPECIALIZE_MAKE_SIGNED(T, S) \
template <> struct make_signed<T> { using type = S; }
template <> struct make_signed<T> { \
using type = S; \
}
SPECIALIZE_MAKE_SIGNED(char, signed char);
SPECIALIZE_MAKE_SIGNED(unsigned char, signed char);

View File

@ -182,6 +182,5 @@ TEST(scan_test, lock) {
consumer1.join();
consumer2.join();
EXPECT_EQ(count, 1000);
}
#endif // FMT_USE_FCNTL

View File

@ -45,10 +45,12 @@ TYPED_TEST(has_to_string_view_test, has_to_string_view) {
EXPECT_TRUE(fmt::detail::has_to_string_view<const TypeParam*>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<TypeParam[2]>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<const TypeParam[2]>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<std::basic_string<TypeParam>>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<fmt::basic_string_view<TypeParam>>::value);
EXPECT_TRUE(
fmt::detail::has_to_string_view<derived_from_string_view<TypeParam>>::value);
fmt::detail::has_to_string_view<std::basic_string<TypeParam>>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<
fmt::basic_string_view<TypeParam>>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<
derived_from_string_view<TypeParam>>::value);
using fmt_string_view = fmt::detail::std_string_view<TypeParam>;
EXPECT_TRUE(std::is_empty<fmt_string_view>::value !=
fmt::detail::has_to_string_view<fmt_string_view>::value);
@ -576,18 +578,19 @@ template <class charT> struct formatter<std::complex<double>, charT> {
template <class FormatContext>
typename FormatContext::iterator format(const std::complex<double>& c,
FormatContext& ctx) {
FormatContext& ctx) const {
auto specs = specs_;
detail::handle_dynamic_spec<detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx);
auto specs = std::string();
if (specs_.precision > 0) specs = fmt::format(".{}", specs_.precision);
if (specs_.type == presentation_type::fixed_lower) specs += 'f';
specs.precision, specs.precision_ref, ctx);
auto fspecs = std::string();
if (specs.precision > 0) fspecs = fmt::format(".{}", specs.precision);
if (specs.type == presentation_type::fixed_lower) fspecs += 'f';
auto real = fmt::format(ctx.locale().template get<std::locale>(),
fmt::runtime("{:" + specs + "}"), c.real());
fmt::runtime("{:" + fspecs + "}"), c.real());
auto imag = fmt::format(ctx.locale().template get<std::locale>(),
fmt::runtime("{:" + specs + "}"), c.imag());
fmt::runtime("{:" + fspecs + "}"), c.imag());
auto fill_align_width = std::string();
if (specs_.width > 0) fill_align_width = fmt::format(">{}", specs_.width);
if (specs.width > 0) fill_align_width = fmt::format(">{}", specs.width);
return fmt::format_to(ctx.out(), runtime("{:" + fill_align_width + "}"),
c.real() != 0 ? fmt::format("({}+{}i)", real, imag)
: fmt::format("{}i", imag));
@ -609,7 +612,10 @@ TEST(locale_test, chrono_weekday) {
EXPECT_EQ(fmt::format(L"{}", sat), L"Sat");
if (loc != std::locale::classic()) {
// L'\xE1' is 'á'.
auto saturdays = std::vector<std::wstring>{L"s\xE1""b", L"s\xE1."};
auto saturdays = std::vector<std::wstring>{
L"s\xE1"
"b",
L"s\xE1."};
EXPECT_THAT(saturdays, Contains(fmt::format(loc, L"{:L}", sat)));
}
std::locale::global(loc_old);