From f6ae3619fa41ad1f637402c8facb8d2e067e09d4 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 9 Jul 2024 07:39:55 +0800 Subject: [PATCH] [libc++][format] Implement LWG4061 Effectively reverts commit 36ce0c3b1e581ca310ae7d0cbc6af002cc5d0251. --- libcxx/docs/Status/Cxx2cIssues.csv | 2 +- libcxx/include/__format/format_context.h | 3 +++ .../format.context/ctor.pass.cpp | 20 +++++++++++++------ .../bug_81590.compile.pass.cpp | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index 18cbe8f8b738a7..d567823e566983 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -64,7 +64,7 @@ "","","","","","" "`3944 `__","Formatters converting sequences of ``char`` to sequences of ``wchar_t``","St. Louis June 2024","","","|format|" "`4060 `__","``submdspan`` preconditions do not forbid creating invalid pointer","St. Louis June 2024","","","" -"`4061 `__","Should ``std::basic_format_context`` be default-constructible/copyable/movable?","St. Louis June 2024","","","|format|" +"`4061 `__","Should ``std::basic_format_context`` be default-constructible/copyable/movable?","St. Louis June 2024","|Complete|","19.0","|format|" "`4071 `__","``reference_wrapper`` comparisons are not SFINAE-friendly","St. Louis June 2024","|Complete|","19.0","" "`4074 `__","``compatible-joinable-ranges`` is underconstrained","St. Louis June 2024","","","|ranges|" "`4076 `__","``concat_view`` should be freestanding","St. Louis June 2024","","","" diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h index 087d4bf289b878..20c07559eae448 100644 --- a/libcxx/include/__format/format_context.h +++ b/libcxx/include/__format/format_context.h @@ -131,6 +131,9 @@ class _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(_OutIt __out_it, basic_format_args __args) : __out_it_(std::move(__out_it)), __args_(__args) {} # endif + + basic_format_context(const basic_format_context&) = delete; + basic_format_context& operator=(const basic_format_context&) = delete; }; // A specialization for __retarget_buffer diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp index 40720105060f0d..83ece7da73ad30 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp @@ -112,19 +112,27 @@ void test() { #endif } +// The default constructor is suppressed by the deleted copy operations. +// The move operations are implicitly deleted due to the deleted copy operations. + // std::back_insert_iterator, copyable -static_assert(std::is_copy_constructible_v, char>>); -static_assert(std::is_copy_assignable_v, char>>); +static_assert( + !std::is_default_constructible_v, char>>); + +static_assert(!std::is_copy_constructible_v, char>>); +static_assert(!std::is_copy_assignable_v, char>>); -static_assert(std::is_move_constructible_v, char>>); -static_assert(std::is_move_assignable_v, char>>); +static_assert(!std::is_move_constructible_v, char>>); +static_assert(!std::is_move_assignable_v, char>>); // cpp20_output_iterator, move only +static_assert(!std::is_default_constructible_v, char>>); + static_assert(!std::is_copy_constructible_v, char>>); static_assert(!std::is_copy_assignable_v, char>>); -static_assert(std::is_move_constructible_v, char>>); -static_assert(std::is_move_assignable_v, char>>); +static_assert(!std::is_move_constructible_v, char>>); +static_assert(!std::is_move_assignable_v, char>>); int main(int, char**) { test>, char>(); diff --git a/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp b/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp index 127f6546ccbe71..5f248f88582d00 100644 --- a/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp +++ b/libcxx/test/std/utilities/format/format.functions/bug_81590.compile.pass.cpp @@ -25,7 +25,7 @@ struct X : std::variant { template <> struct std::formatter : std::formatter { - static constexpr auto format(const X& x, auto ctx) { + static constexpr auto format(const X& x, auto& ctx) { if (!x.p) return ctx.out(); auto m = [&](const X* t) { return std::format_to(ctx.out(), "{}", *t); };