--- libstdc++-v3/include/std/limits.jj	2022-10-18 11:35:55.065871590 +0200
+++ libstdc++-v3/include/std/limits	2022-10-18 18:32:20.701757131 +0200
@@ -1890,7 +1890,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #undef __glibcxx_long_double_traps
 #undef __glibcxx_long_double_tinyness_before
 
-#if __cplusplus > 202202L
+#if __cplusplus > 202002L
 
 #define __glibcxx_concat3_(P,M,S) P ## M ## S
 #define __glibcxx_concat3(P,M,S) __glibcxx_concat3_ (P,M,S)
@@ -1924,8 +1924,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static constexpr bool is_signed = true;				\
       static constexpr bool is_integer = false;				\
       static constexpr bool is_exact = false;				\
-      static constexpr int radix					\
-	= __glibcxx_concat3 (__FLT, BITSIZE, _RADIX__);			\
+      static constexpr int radix = __FLT_RADIX__;			\
 									\
       static constexpr _Float##BITSIZE					\
       epsilon() noexcept						\
@@ -2023,7 +2022,7 @@ __glibcxx_float_n(128)
       static constexpr bool is_signed = true;
       static constexpr bool is_integer = false;
       static constexpr bool is_exact = false;
-      static constexpr int radix = __BFLT16_RADIX__;
+      static constexpr int radix = __FLT_RADIX__;
 
       static constexpr __gnu_cxx::__bfloat16_t
       epsilon() noexcept
--- libstdc++-v3/include/c_global/cmath.jj	2022-10-18 11:35:55.222869455 +0200
+++ libstdc++-v3/include/c_global/cmath	2022-10-18 17:05:50.737347845 +0200
@@ -2755,7 +2755,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   nearbyint(_Float16 __x)
   { return _Float16(__builtin_nearbyintf(__x)); }
 
-  // nextafter not implemented so far.
+  inline _Float16
+  nextafter(_Float16 __x, _Float16 __y)
+  {
+#ifdef __INT16_TYPE__
+    using __float16_int_type = __INT16_TYPE__;
+#else
+    using __float16_int_type = short int;
+#endif
+    __float16_int_type __hx, __hy, __ix, __iy;
+    __builtin_memcpy(&__hx, &__x, sizeof(__x));
+    __builtin_memcpy(&__hy, &__y, sizeof(__x));
+    __ix = __hx & 0x7fff;	// |x|
+    __iy = __hy & 0x7fff;	// |y|
+    if (__ix > 0x7c00 || __iy > 0x7c00) // x or y is NaN
+      return __x + __y;
+    if (__x == __y)
+      return __y;		// x == y, return y
+    if (__ix == 0)		// x == 0
+      {
+	__hy = (__hy & 0x8000) | 1;	// return +-__FLT16_DENORM_MIN__
+	__builtin_memcpy(&__x, &__hy, sizeof(__x));
+	__builtin_nextafterf(0.0f, 1.0f);	// raise underflow
+	return __x;
+      }
+    if (__hx >= 0)		// x > 0
+      {
+	if (__hx > __hy)	// x > y, x -= ulp
+	  --__hx;
+	else			// x < y, x += ulp
+	  ++__hx;
+      }
+    else			// x < 0
+      {
+	if (__hy >= 0 || __hx > __hy)	// x < y, x -= ulp
+	  --__hx;
+	else			// x > y, x += ulp
+	  ++__hx;
+      }
+    __hy = __hx & 0x7c00;
+    if (__hy >= 0x7c00)
+      __builtin_nextafterf(__FLT_MAX__, __builtin_inff());	// overflow
+    else if (__hy < 0x0400)
+      __builtin_nextafterf(__FLT_MIN__, 0.0f);	// underflow
+    __builtin_memcpy(&__x, &__hx, sizeof(__x));
+    return __x;
+  }
 
   constexpr _Float16
   remainder(_Float16 __x, _Float16 __y)
@@ -3426,7 +3471,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   nearbyint(__gnu_cxx::__bfloat16_t __x)
   { return __gnu_cxx::__bfloat16_t(__builtin_nearbyintf(__x)); }
 
-  // nextafter not implemented so far.
+  inline __gnu_cxx::__bfloat16_t
+  nextafter(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  {
+#ifdef __INT16_TYPE__
+    using __bfloat16_int_type = __INT16_TYPE__;
+#else
+    using __bfloat16_int_type = short int;
+#endif
+    __bfloat16_int_type __hx, __hy, __ix, __iy;
+    __builtin_memcpy(&__hx, &__x, sizeof(__x));
+    __builtin_memcpy(&__hy, &__y, sizeof(__x));
+    __ix = __hx & 0x7fff;	// |x|
+    __iy = __hy & 0x7fff;	// |y|
+    if (__ix > 0x7f80 || __iy > 0x7f80) // x or y is NaN
+      return __x + __y;
+    if (__x == __y)
+      return __y;		// x == y, return y
+    if (__ix == 0)		// x == 0
+      {
+	__hy = (__hy & 0x8000) | 1;	// return +-__BFLT16_DENORM_MIN__
+	__builtin_memcpy(&__x, &__hy, sizeof(__x));
+	__builtin_nextafterf(0.0f, 1.0f);	// raise underflow
+	return __x;
+      }
+    if (__hx >= 0)		// x > 0
+      {
+	if (__hx > __hy)	// x > y, x -= ulp
+	  --__hx;
+	else			// x < y, x += ulp
+	  ++__hx;
+      }
+    else			// x < 0
+      {
+	if (__hy >= 0 || __hx > __hy)	// x < y, x -= ulp
+	  --__hx;
+	else			// x > y, x += ulp
+	  ++__hx;
+      }
+    __hy = __hx & 0x7f80;
+    if (__hy >= 0x7f80)
+      __builtin_nextafterf(__FLT_MAX__, __builtin_inff());	// overflow
+    else if (__hy < 0x0080)
+      __builtin_nextafterf(__FLT_MIN__, 0.0f);	// underflow
+    __builtin_memcpy(&__x, &__hx, sizeof(__x));
+    return __x;
+  }
 
   constexpr __gnu_cxx::__bfloat16_t
   remainder(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
--- libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc.jj	2022-10-18 11:35:55.000000000 +0200
+++ libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc	2022-10-18 18:12:08.311247121 +0200
@@ -63,7 +63,7 @@ test_functions (T *p, int *q, long int *
   p[36] = std::fmod (p[36], p[103]);
   p[37] = std::remainder (p[37], p[104]);
   p[38] = std::copysign (p[38], p[105]);
-//  p[39] = std::nextafter (p[39], p[106]);
+  p[39] = std::nextafter (p[39], p[106]);
   p[40] = std::fdim (p[40], p[107]);
   p[41] = std::fmax (p[41], p[108]);
   p[42] = std::fmin (p[42], p[109]);
@@ -102,13 +102,13 @@ test_functions (T *p, int *q, long int *
   p[75] = std::riemann_zeta (p[75]);
   p[76] = std::sph_bessel (q[12], p[76]);
   p[77] = std::sph_legendre (q[13], q[14], p[77]);
-  p[78] = std::sph_neumann (q[15], q[16], p[78]);
+  p[78] = std::sph_neumann (q[15], p[78]);
 }
 
 int
 main ()
 {
-  int q[17] = {};
+  int q[16] = {};
   long int r[16] = {};
   long long int s[16] = {};
 #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
--- libstdc++-v3/testsuite/26_numerics/headers/cmath/nextafter_c++23.cc.jj	2022-10-18 17:18:32.237061706 +0200
+++ libstdc++-v3/testsuite/26_numerics/headers/cmath/nextafter_c++23.cc	2022-10-18 18:51:21.465258133 +0200
@@ -0,0 +1,124 @@
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++23 } }
+
+#include <stdfloat>
+#include <cmath>
+#include <limits>
+#include <testsuite_hooks.h>
+
+template <typename T>
+void
+test ()
+{
+  using lim = std::numeric_limits<T>;
+  T t0 = std::nextafter(T(-0.0), T(2.0));
+  VERIFY(t0 == lim::denorm_min());
+  T t1 = std::nextafter(T(), T(1.0));
+  VERIFY(t1 == lim::denorm_min());
+  T t2 = std::nextafter(T(), T());
+  VERIFY(t2 == T() && !std::signbit(t2));
+  T t3 = std::nextafter(lim::denorm_min(), T(-2.0));
+  VERIFY(t3 == T() && !std::signbit(t3));
+  T t4 = std::nextafter(lim::min(), T(-0.0));
+  VERIFY(std::fpclassify(t4) == FP_SUBNORMAL && t4 > T());
+  T t5 = std::nextafter(t4, T(1.0));
+  VERIFY(t5 == lim::min());
+  T t6 = std::nextafter(lim::min(), lim::infinity());
+  VERIFY(std::fpclassify(t6) == FP_NORMAL && t6 > lim::min());
+  T t7 = std::nextafter(t6, -lim::infinity());
+  VERIFY(t7 == lim::min());
+  T t8 = std::nextafter(T(16.0), T(16.5));
+  VERIFY(t8 > t7);
+  T t9 = std::nextafter(t8, T(15.5));
+  VERIFY(t9 == T(16.0));
+  T t10 = std::nextafter(lim::max(), T(-0.5));
+  VERIFY(std::fpclassify(t10) == FP_NORMAL && t10 < lim::max());
+  T t11 = std::nextafter(t10, lim::infinity());
+  VERIFY(t11 == lim::max());
+  T t12 = std::nextafter(t11, lim::infinity());
+  VERIFY(std::fpclassify(t12) == FP_INFINITE && !std::signbit(t12));
+  T t13 = std::nextafter(lim::infinity(), t12);
+  VERIFY(t13 == t12);
+  T t14 = std::nextafter(t13, T(1.0));
+  VERIFY(t14 == lim::max());
+  T t15 = std::nextafter(lim::quiet_NaN(), T());
+  VERIFY(std::fpclassify(t15) == FP_NAN);
+  T t16 = std::nextafter(T(17.0), lim::quiet_NaN());
+  VERIFY(std::fpclassify(t16) == FP_NAN);
+  T t17 = std::nextafter(T(), T(-0.0));
+  VERIFY(t17 == T() && std::signbit(t17));
+  T t20 = std::nextafter(T(-0.0), T(-2.0));
+  VERIFY(t20 == -lim::denorm_min());
+  T t21 = std::nextafter(T(), T(-1.0));
+  VERIFY(t21 == -lim::denorm_min());
+  T t22 = std::nextafter(T(-0.0), T(-0.0));
+  VERIFY(t22 == T() && std::signbit(t22));
+  T t23 = std::nextafter(-lim::denorm_min(), T(2.0));
+  VERIFY(t23 == T() && std::signbit(t23));
+  T t24 = std::nextafter(-lim::min(), T());
+  VERIFY(std::fpclassify(t24) == FP_SUBNORMAL && t24 < T());
+  T t25 = std::nextafter(t24, T(-1.0));
+  VERIFY(t25 == -lim::min());
+  T t26 = std::nextafter(-lim::min(), -lim::infinity());
+  VERIFY(std::fpclassify(t26) == FP_NORMAL && t26 < -lim::min());
+  T t27 = std::nextafter(t26, lim::infinity());
+  VERIFY(t27 == -lim::min());
+  T t28 = std::nextafter(T(-16.0), T(-16.5));
+  VERIFY(t28 < t27);
+  T t29 = std::nextafter(t28, T(-15.5));
+  VERIFY(t29 == T(-16.0));
+  T t30 = std::nextafter(-lim::max(), T(0.5));
+  VERIFY(std::fpclassify(t30) == FP_NORMAL && t30 > -lim::max());
+  T t31 = std::nextafter(t30, -lim::infinity());
+  VERIFY(t31 == -lim::max());
+  T t32 = std::nextafter(t31, -lim::infinity());
+  VERIFY(std::fpclassify(t32) == FP_INFINITE && std::signbit(t32));
+  T t33 = std::nextafter(-lim::infinity(), t32);
+  VERIFY(t33 == t32);
+  T t34 = std::nextafter(t33, T(-1.0));
+  VERIFY(t34 == -lim::max());
+  T t35 = std::nextafter(-lim::quiet_NaN(), T());
+  VERIFY(std::fpclassify(t35) == FP_NAN);
+  T t36 = std::nextafter(T(-17.0), lim::quiet_NaN());
+  VERIFY(std::fpclassify(t36) == FP_NAN);
+  T t37 = std::nextafter(T(-0.0), T());
+  VERIFY(t37 == T() && !std::signbit(t37));
+}
+
+int
+main ()
+{
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  test <std::float16_t> ();
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  test <std::float32_t> ();
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  test <std::float64_t> ();
+#endif
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  test <std::float128_t> ();
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  test <std::bfloat16_t> ();
+#endif
+}
