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 <stdio.h> // FILE
#include <string.h> // strlen #include <string.h> // strlen
// <cstddef> is also included transitively from <type_traits>.
#include <cstddef> // std::byte #include <cstddef> // std::byte
#include <type_traits> // std::enable_if #include <type_traits> // std::enable_if
@ -1332,8 +1333,9 @@ template <typename Context> class value {
parse_ctx.advance_to(f.parse(parse_ctx)); parse_ctx.advance_to(f.parse(parse_ctx));
using qualified_type = using qualified_type =
conditional_t<has_const_formatter<T, Context>(), const T, T>; conditional_t<has_const_formatter<T, Context>(), const T, T>;
// Calling format through a mutable reference is deprecated. // format must be const for compatibility with std::format and compilation.
ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx)); 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> template <typename FormatContext>
auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) { auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) {
detail::handle_dynamic_spec<detail::width_checker>(specs_.width, auto specs = specs_;
specs_.width_ref, ctx); detail::handle_dynamic_spec<detail::width_checker>(specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>( detail::handle_dynamic_spec<detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx); specs.precision, specs.precision_ref, ctx);
return detail::write_bytes(ctx.out(), b.data_, specs_); 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> 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()) { -> decltype(ctx.out()) {
detail::handle_dynamic_spec<detail::width_checker>(specs_.width, auto specs = specs_;
specs_.width_ref, ctx); detail::handle_dynamic_spec<detail::width_checker>(specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>( detail::handle_dynamic_spec<detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx); specs.precision, specs.precision_ref, ctx);
return detail::write_int( return detail::write_int(ctx.out(),
ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_, static_cast<detail::uint64_or_128_t<T>>(t.value),
detail::digit_grouping<char>("\3", ",")); 0, specs, detail::digit_grouping<char>("\3", ","));
} }
}; };

View File

@ -58,4 +58,4 @@ TEST(compile_time_formatting_test, floating_point) {
EXPECT_EQ("-inf", test_format<5>(FMT_COMPILE("{}"), -inf)); EXPECT_EQ("-inf", test_format<5>(FMT_COMPILE("{}"), -inf));
} }
#endif // FMT_USE_CONSTEVAL #endif // FMT_USE_CONSTEVAL

View File

@ -35,7 +35,7 @@ struct type_with_get {
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
template <> struct formatter<type_with_get> : formatter<int> { template <> struct formatter<type_with_get> : formatter<int> {
template <typename FormatContext> 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); return formatter<int>::format(42, ctx);
} }
}; };
@ -296,8 +296,8 @@ TEST(compile_test, compile_format_string_literal) {
// (compiler file // (compiler file
// 'D:\a\_work\1\s\src\vctools\Compiler\CxxFE\sl\p1\c\constexpr\constexpr.cpp', // 'D:\a\_work\1\s\src\vctools\Compiler\CxxFE\sl\p1\c\constexpr\constexpr.cpp',
// line 8635) // line 8635)
#if FMT_USE_CONSTEVAL && \ #if FMT_USE_CONSTEVAL && \
(!FMT_MSC_VERSION || \ (!FMT_MSC_VERSION || \
(FMT_MSC_VERSION >= 1928 && FMT_MSC_VERSION < 1930)) && \ (FMT_MSC_VERSION >= 1928 && FMT_MSC_VERSION < 1930)) && \
defined(__cpp_lib_is_constant_evaluated) defined(__cpp_lib_is_constant_evaluated)
template <size_t max_string_length, typename Char = char> struct test_string { template <size_t max_string_length, typename Char = char> struct test_string {

View File

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

View File

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

View File

@ -201,7 +201,8 @@ auto operator<<(std::ostream& os, test_template<T>) -> std::ostream& {
namespace fmt { namespace fmt {
template <typename T> struct formatter<test_template<T>> : formatter<int> { 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); 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) { TEST(buffered_file_test, close_no_retry_in_dtor) {
auto pipe = fmt::pipe(); 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; int saved_fclose_count = 0;
EXPECT_WRITE( EXPECT_WRITE(
stderr, stderr,
@ -428,7 +429,7 @@ TEST(buffered_file_test, fileno_no_retry) {
struct test_mock { struct test_mock {
static test_mock* instance; static test_mock* instance;
} * test_mock::instance; }* test_mock::instance;
TEST(scoped_mock, scope) { TEST(scoped_mock, scope) {
{ {

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) \ #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(char, signed char);
SPECIALIZE_MAKE_SIGNED(unsigned char, signed char); SPECIALIZE_MAKE_SIGNED(unsigned char, signed char);

View File

@ -182,6 +182,5 @@ TEST(scan_test, lock) {
consumer1.join(); consumer1.join();
consumer2.join(); consumer2.join();
EXPECT_EQ(count, 1000); EXPECT_EQ(count, 1000);
} }
#endif // FMT_USE_FCNTL #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<const TypeParam*>::value);
EXPECT_TRUE(fmt::detail::has_to_string_view<TypeParam[2]>::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<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( 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>; using fmt_string_view = fmt::detail::std_string_view<TypeParam>;
EXPECT_TRUE(std::is_empty<fmt_string_view>::value != EXPECT_TRUE(std::is_empty<fmt_string_view>::value !=
fmt::detail::has_to_string_view<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> template <class FormatContext>
typename FormatContext::iterator format(const std::complex<double>& c, typename FormatContext::iterator format(const std::complex<double>& c,
FormatContext& ctx) { FormatContext& ctx) const {
auto specs = specs_;
detail::handle_dynamic_spec<detail::precision_checker>( detail::handle_dynamic_spec<detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx); specs.precision, specs.precision_ref, ctx);
auto specs = std::string(); auto fspecs = std::string();
if (specs_.precision > 0) specs = fmt::format(".{}", specs_.precision); if (specs.precision > 0) fspecs = fmt::format(".{}", specs.precision);
if (specs_.type == presentation_type::fixed_lower) specs += 'f'; if (specs.type == presentation_type::fixed_lower) fspecs += 'f';
auto real = fmt::format(ctx.locale().template get<std::locale>(), 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>(), 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(); 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 + "}"), return fmt::format_to(ctx.out(), runtime("{:" + fill_align_width + "}"),
c.real() != 0 ? fmt::format("({}+{}i)", real, imag) c.real() != 0 ? fmt::format("({}+{}i)", real, imag)
: fmt::format("{}i", imag)); : fmt::format("{}i", imag));
@ -609,7 +612,10 @@ TEST(locale_test, chrono_weekday) {
EXPECT_EQ(fmt::format(L"{}", sat), L"Sat"); EXPECT_EQ(fmt::format(L"{}", sat), L"Sat");
if (loc != std::locale::classic()) { if (loc != std::locale::classic()) {
// L'\xE1' is 'á'. // 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))); EXPECT_THAT(saturdays, Contains(fmt::format(loc, L"{:L}", sat)));
} }
std::locale::global(loc_old); std::locale::global(loc_old);