aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-07-16 10:14:45 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2024-07-31 17:07:11 +0100
commit08782a5d92bacc3af947caf79d19bf25eae02e7b (patch)
treefd6e8f0affde9be31f87ef8822d58c08e53e97c7
parentf6f2c78d9db37228baa9d1f9926b0c120e24016f (diff)
downloadgcc-08782a5d92bacc3af947caf79d19bf25eae02e7b.zip
gcc-08782a5d92bacc3af947caf79d19bf25eae02e7b.tar.gz
gcc-08782a5d92bacc3af947caf79d19bf25eae02e7b.tar.bz2
libstdc++: Define C++26 member visit for std::basic_format_arg [PR110356]
Implement the std::format changes from P2637R3. This adds visit member functions to std::basic_format_arg and deprecates the non-member function std::visit_format_arg. libstdc++-v3/ChangeLog: PR libstdc++/110356 * include/bits/c++config (_GLIBCXX26_DEPRECATED): Define. (_GLIBCXX26_DEPRECATED_SUGGEST): Define. * include/bits/version.def (format): Update for C++26. * include/bits/version.h: Regenerate. * include/std/format (basic_format_arg::visit): New member functions. (visit_format_arg): Add deprecated attribute. * testsuite/std/format/arguments/args.cc: Expect deprecated warnings. Check member visit. * testsuite/std/format/functions/format.cc: Update expected value for __cpp_lib_format macro. * testsuite/std/format/parse_ctx.cc: Add dg-warning for deprecation.
-rw-r--r--libstdc++-v3/include/bits/c++config10
-rw-r--r--libstdc++-v3/include/bits/version.def2
-rw-r--r--libstdc++-v3/include/bits/version.h4
-rw-r--r--libstdc++-v3/include/std/format16
-rw-r--r--libstdc++-v3/testsuite/std/format/arguments/args.cc43
-rw-r--r--libstdc++-v3/testsuite/std/format/functions/format.cc4
-rw-r--r--libstdc++-v3/testsuite/std/format/parse_ctx.cc2
7 files changed, 75 insertions, 6 deletions
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 6dca2d9..0f0cc7c 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -90,6 +90,8 @@
// _GLIBCXX20_DEPRECATED_SUGGEST( string-literal )
// _GLIBCXX23_DEPRECATED
// _GLIBCXX23_DEPRECATED_SUGGEST( string-literal )
+// _GLIBCXX26_DEPRECATED
+// _GLIBCXX26_DEPRECATED_SUGGEST( string-literal )
#ifndef _GLIBCXX_USE_DEPRECATED
# define _GLIBCXX_USE_DEPRECATED 1
#endif
@@ -143,6 +145,14 @@
# define _GLIBCXX23_DEPRECATED_SUGGEST(ALT)
#endif
+#if defined(__DEPRECATED) && (__cplusplus >= 202400L)
+# define _GLIBCXX26_DEPRECATED [[__deprecated__]]
+# define _GLIBCXX26_DEPRECATED_SUGGEST(ALT) _GLIBCXX_DEPRECATED_SUGGEST(ALT)
+#else
+# define _GLIBCXX26_DEPRECATED
+# define _GLIBCXX26_DEPRECATED_SUGGEST(ALT)
+#endif
+
// Macros for ABI tag attributes.
#ifndef _GLIBCXX_ABI_TAG_CXX11
# define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11")))
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 806f1e9..ec33091 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1171,7 +1171,7 @@ ftms = {
// 202306 P2637R3 Member visit
// 202311 P2918R2 Runtime format strings II
values = {
- v = 202305;
+ v = 202306;
cxxmin = 26;
hosted = yes;
};
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index e8ca0fa..148ee87 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1310,9 +1310,9 @@
#if !defined(__cpp_lib_format)
# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED
-# define __glibcxx_format 202305L
+# define __glibcxx_format 202306L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_format)
-# define __cpp_lib_format 202305L
+# define __cpp_lib_format 202306L
# endif
# elif (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
# define __glibcxx_format 202304L
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 6a88705..715fdf9 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3346,6 +3346,18 @@ namespace __format
explicit operator bool() const noexcept
{ return _M_type != __format::_Arg_none; }
+#if __cpp_lib_format >= 202306L // >= C++26
+ template<typename _Visitor>
+ decltype(auto)
+ visit(this basic_format_arg __arg, _Visitor&& __vis)
+ { return __arg._M_visit(std::forward<_Visitor>(__vis), __arg._M_type); }
+
+ template<typename _Res, typename _Visitor>
+ _Res
+ visit(this basic_format_arg __arg, _Visitor&& __vis)
+ { return __arg._M_visit(std::forward<_Visitor>(__vis), __arg._M_type); }
+#endif
+
private:
template<typename _Ctx>
friend class basic_format_args;
@@ -3631,6 +3643,7 @@ namespace __format
};
template<typename _Visitor, typename _Context>
+ _GLIBCXX26_DEPRECATED_SUGGEST("std::basic_format_arg::visit")
inline decltype(auto)
visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg)
{
@@ -3666,6 +3679,8 @@ namespace __format
}
};
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
template<typename _Context>
inline size_t
__int_from_arg(const basic_format_arg<_Context>& __arg)
@@ -4297,6 +4312,7 @@ namespace __format
else
return std::move(__sink)._M_finish().out;
}
+#pragma GCC diagnostic pop
} // namespace __format
/// @endcond
diff --git a/libstdc++-v3/testsuite/std/format/arguments/args.cc b/libstdc++-v3/testsuite/std/format/arguments/args.cc
index 16ca71c..2cea0a1 100644
--- a/libstdc++-v3/testsuite/std/format/arguments/args.cc
+++ b/libstdc++-v3/testsuite/std/format/arguments/args.cc
@@ -1,5 +1,7 @@
// { dg-do run { target c++20 } }
+// { dg-warning "deprecated" "std::visit_format_arg" { target c++26 } 0 }
+
#include <format>
#include <testsuite_hooks.h>
@@ -55,6 +57,9 @@ test_args()
char c = '2';
double d = 3.4;
+ // We need an lvalue of type format-arg-store<Context, Args...> for the
+ // lvalue args to point to, otherwise it will have a dangling pointer.
+ // This is not how you're supposed to use format args, just for testing.
auto store = std::make_format_args(b, i, c, d);
std::format_args args = store;
VERIFY(equals(args.get(0), false));
@@ -106,8 +111,46 @@ test_args()
VERIFY(std::visit_format_arg(is_handle, args.get(1)));
}
+void
+test_member_visit()
+{
+#if __cpp_lib_format >= 202306L // C++26 adds std::basic_format_arg::visit
+ int one = 1;
+ float two = 2.0;
+ std::string_view three = "three";
+ auto store = std::make_format_args(one, two, three); // See comment above.
+ std::format_args args = store;
+ auto a1 = args.get(0).visit([=](auto a) {
+ if constexpr (std::is_same_v<decltype(a), int>)
+ return a == one;
+ return false;
+ });
+ VERIFY( a1 );
+ auto a2 = args.get(1).visit([=](auto a) {
+ if constexpr (std::is_same_v<decltype(a), float>)
+ return a == two;
+ return false;
+ });
+ VERIFY( a2 );
+ auto a3 = args.get(2).visit([=](auto a) {
+ if constexpr (std::is_same_v<decltype(a), std::string_view>)
+ return a == three;
+ return false;
+ });
+ VERIFY( a3 );
+
+ auto a4 = args.get(0).visit<std::string_view>([](auto) { return "str"; });
+ static_assert( std::is_same_v<decltype(a4), std::string_view> );
+ VERIFY( a4 == "str" );
+ args.get(0).visit<void>([](auto){});
+ using V = decltype(args.get(0).visit<void>([](auto){}));
+ static_assert( std::is_same_v<V, void> );
+#endif
+}
+
int main()
{
test_empty();
test_args();
+ test_member_visit();
}
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc
index 3c441d7..0549d17 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -8,7 +8,7 @@
# error "Feature test macro for std::format is missing in <format>"
#elif __cpp_lib_format < 202110L
# error "Feature test macro for std::format has wrong value in <format>"
-#elif __cplusplus > 202302L && __cpp_lib_format < 202305L
+#elif __cplusplus > 202302L && __cpp_lib_format < 202306L
# error "Feature test macro for std::format has wrong value in <format>"
#endif
@@ -24,7 +24,7 @@
# error "Feature test macro for std::format is missing in <version>"
#elif __cpp_lib_format < 202110L
# error "Feature test macro for std::format has wrong value in <version>"
-#elif __cplusplus > 202302L && __cpp_lib_format < 202305L
+#elif __cplusplus > 202302L && __cpp_lib_format < 202306L
# error "Feature test macro for std::format has wrong value in <version>"
#endif
diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx.cc b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
index b0cef2d..88ffd77 100644
--- a/libstdc++-v3/testsuite/std/format/parse_ctx.cc
+++ b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
@@ -473,7 +473,7 @@ struct std::formatter<X, char>
std::format_context::iterator
format(X, std::format_context& c) const
{
- std::visit_format_arg([this]<typename T>(T) {
+ std::visit_format_arg([this]<typename T>(T) { // { dg-warning "deprecated" "" { target c++26 } }
if (is_integral_v<T> != this->integer)
throw std::format_error("invalid argument type");
}, c.arg(1));