From 21d0cef2cbdd691659811a036ba05401056bfa83 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 19 Jun 2023 23:43:46 +0800 Subject: [PATCH] Move the major part of `visit_format_arg` into a member function... of `basic_format_arg` Also fix a small bug on an `int` rvalue. --- stl/inc/format | 75 ++++++++++--------- .../P0645R10_text_formatting_args/test.cpp | 16 ++++ 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 56f5b11bb6..3f673b2f8a 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -745,10 +745,45 @@ public: } } -private: - template - friend decltype(auto) visit_format_arg(_Visitor&&, basic_format_arg<_Ctx>); + template + decltype(auto) _Visit(_Visitor&& _Vis) { + switch (_Active_state) { + case _Basic_format_arg_type::_None: + return _STD forward<_Visitor>(_Vis)(_No_state); + case _Basic_format_arg_type::_Int_type: + return _STD forward<_Visitor>(_Vis)(_Int_state); + case _Basic_format_arg_type::_UInt_type: + return _STD forward<_Visitor>(_Vis)(_UInt_state); + case _Basic_format_arg_type::_Long_long_type: + return _STD forward<_Visitor>(_Vis)(_Long_long_state); + case _Basic_format_arg_type::_ULong_long_type: + return _STD forward<_Visitor>(_Vis)(_ULong_long_state); + case _Basic_format_arg_type::_Bool_type: + return _STD forward<_Visitor>(_Vis)(_Bool_state); + case _Basic_format_arg_type::_Char_type: + return _STD forward<_Visitor>(_Vis)(_Char_state); + case _Basic_format_arg_type::_Float_type: + return _STD forward<_Visitor>(_Vis)(_Float_state); + case _Basic_format_arg_type::_Double_type: + return _STD forward<_Visitor>(_Vis)(_Double_state); + case _Basic_format_arg_type::_Long_double_type: + return _STD forward<_Visitor>(_Vis)(_Long_double_state); + case _Basic_format_arg_type::_Pointer_type: + return _STD forward<_Visitor>(_Vis)(_Pointer_state); + case _Basic_format_arg_type::_CString_type: + return _STD forward<_Visitor>(_Vis)(_CString_state); + case _Basic_format_arg_type::_String_type: + return _STD forward<_Visitor>(_Vis)(_String_state); + case _Basic_format_arg_type::_Custom_type: + return _STD forward<_Visitor>(_Vis)(_Custom_state); + default: + _STL_VERIFY(false, "basic_format_arg is in impossible state"); + int _Dummy{}; + return _STD forward<_Visitor>(_Vis)(_Dummy); + } + } +private: friend basic_format_args<_Context>; friend _Format_handler<_CharType>; friend _Format_arg_traits<_Context>; @@ -838,39 +873,7 @@ auto _Format_arg_traits<_Context>::_Type_eraser() { _EXPORT_STD template decltype(auto) visit_format_arg(_Visitor&& _Vis, basic_format_arg<_Context> _Arg) { - switch (_Arg._Active_state) { - case _Basic_format_arg_type::_None: - return _STD forward<_Visitor>(_Vis)(_Arg._No_state); - case _Basic_format_arg_type::_Int_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Int_state); - case _Basic_format_arg_type::_UInt_type: - return _STD forward<_Visitor>(_Vis)(_Arg._UInt_state); - case _Basic_format_arg_type::_Long_long_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Long_long_state); - case _Basic_format_arg_type::_ULong_long_type: - return _STD forward<_Visitor>(_Vis)(_Arg._ULong_long_state); - case _Basic_format_arg_type::_Bool_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Bool_state); - case _Basic_format_arg_type::_Char_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Char_state); - case _Basic_format_arg_type::_Float_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Float_state); - case _Basic_format_arg_type::_Double_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Double_state); - case _Basic_format_arg_type::_Long_double_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Long_double_state); - case _Basic_format_arg_type::_Pointer_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Pointer_state); - case _Basic_format_arg_type::_CString_type: - return _STD forward<_Visitor>(_Vis)(_Arg._CString_state); - case _Basic_format_arg_type::_String_type: - return _STD forward<_Visitor>(_Vis)(_Arg._String_state); - case _Basic_format_arg_type::_Custom_type: - return _STD forward<_Visitor>(_Vis)(_Arg._Custom_state); - default: - _STL_VERIFY(false, "basic_format_arg is in impossible state"); - return _STD forward<_Visitor>(_Vis)(0); - } + return _Arg._Visit(_STD forward<_Visitor>(_Vis)); } // we need to implement this ourselves because from_chars does not work with wide characters and isn't constexpr diff --git a/tests/std/tests/P0645R10_text_formatting_args/test.cpp b/tests/std/tests/P0645R10_text_formatting_args/test.cpp index 98802790b3..24ceead553 100644 --- a/tests/std/tests/P0645R10_text_formatting_args/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_args/test.cpp @@ -252,6 +252,18 @@ void test_lwg3810() { static_assert(same_as>); } +struct lvalue_only_visitor { + template + void operator()(T&&) const = delete; + template + void operator()(T&) const noexcept {} +}; + +template +void test_lvalue_only_visitation() { + visit_format_arg(lvalue_only_visitor{}, basic_format_arg{}); +} + int main() { test_basic_format_arg(); test_basic_format_arg(); @@ -259,6 +271,10 @@ int main() { test_format_arg_store(); test_visit_monostate(); test_visit_monostate(); + test_lwg3810(); test_lwg3810(); + + test_lvalue_only_visitation(); + test_lvalue_only_visitation(); }