[{"id":3674696,"web_url":"http://patchwork.ozlabs.org/comment/3674696/","msgid":"<CAH6eHdSx5kSs6JuBBv6MZaXk6o1kMk-uwN=kTxWTOODKcjvKww@mail.gmail.com>","list_archive_url":null,"date":"2026-04-08T10:04:32","subject":"Re: [PATCH] libstdc++: Remove non_type and replace it with\n constant_wrapper in function_ref","submitter":{"id":4329,"url":"http://patchwork.ozlabs.org/api/people/4329/","name":"Jonathan Wakely","email":"jwakely.gcc@gmail.com"},"content":"On Wed, 8 Apr 2026, 10:46 Tomasz Kamiński, <tkaminsk@redhat.com> wrote:\n\n> From: Matthias Kretz <m.kretz@gsi.de>\n>\n> This implements P3948R1: constant_wrapper is the only tool needed\n> for passing constant expressions via function arguments.\n>\n> This changes function_ref from nontype_t to constant_wrapper and\n> implements the ambiguity check (static_asert in function_ref\n> from constant_wrapper constructor).\n>\n> In addition to P3948R1 this also includes the (forgotten) deduction\n> guide changes suggested in the draft PR [1].\n>\n> [1] https://github.com/cplusplus/draft/pull/8878\n>\n> libstdc++-v3/ChangeLog:\n>\n>         * include/bits/funcref_impl.h (function_ref::function_ref):\n>         Change nontype_t parameter to constant_wrapper, and adjust\n>         accordingly. Add static_assert detecting ambigous semantics.\n>         (function_refoperator=): Detect constant_wrapper rather than\n>         nontype_t.\n>\n\nMissing :: here\n\n        * include/bits/funcwrap.h (function_ref): Change\n>         * include/bits/utility.h (std::nontype_t, std::nontype)\n>         (std::__is_nontype_v): Remove.\n>         (_is_constant_wrapper_v): Define.\n>\n\nAnd _ here\n\nThe patch itself is fine, so OK with those two tweaks to the changelog.\n\n\n        * src/c++23/std.cc.in (std::nontype_t, std::nontype):\n>         Remove exports.\n>         * testsuite/20_util/function_ref/cw_cons_neg.cc: New tests\n>         for ambiguity check.\n>         * testsuite/20_util/function_ref/assign.cc: Replace nontype_t\n>         with constant_wrapper and nontype with std::cw.\n>         * testsuite/20_util/function_ref/call.cc: Likewise.\n>         * testsuite/20_util/function_ref/cons.cc: Likewise.\n>         * testsuite/20_util/function_ref/cons_neg.cc: Likewise.\n>         * testsuite/20_util/function_ref/deduction.cc: Likewise.\n>         * testsuite/20_util/function_ref/mutation.cc: Likewise.\n>\n> Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>\n> Signed-off-by: Matthias Kretz <m.kretz@gsi.de>\n> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>\n> ---\n> This is based on Matthias patch from formge:\n>\n> https://forge.sourceware.org/gcc/gcc-TEST/pulls/147/commits/cac7355bcbd7ea8b5e26f064922e8f4412a4da97\n>\n> I have applied small adjustment to names and parameter specification,\n> to be more consistient with the standard. Outside of that I have reworked\n> static_assert to reflect more closely what is in the standard, and added\n> negative test (cw_const_neg.cc).\n>\n> Testing on x86_64-linux. All *function_ref* test already passed in\n> all standard modes and with modules. OK for trunk when all test passes?\n>\n>\n>  libstdc++-v3/include/bits/funcref_impl.h      | 36 ++++----\n>  libstdc++-v3/include/bits/funcwrap.h          | 13 +--\n>  libstdc++-v3/include/bits/utility.h           | 23 ++---\n>  libstdc++-v3/src/c++23/std.cc.in              |  4 -\n>  .../testsuite/20_util/function_ref/assign.cc  | 27 +++---\n>  .../testsuite/20_util/function_ref/call.cc    | 51 ++++++------\n>  .../testsuite/20_util/function_ref/cons.cc    | 83 +++++++++----------\n>  .../20_util/function_ref/cons_neg.cc          | 17 ++--\n>  .../20_util/function_ref/cw_cons_neg.cc       | 35 ++++++++\n>  .../20_util/function_ref/dangling.cc          |  2 +-\n>  .../20_util/function_ref/deduction.cc         | 48 +++++------\n>  .../20_util/function_ref/mutation.cc          |  9 +-\n>  12 files changed, 185 insertions(+), 163 deletions(-)\n>  create mode 100644\n> libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>\n> diff --git a/libstdc++-v3/include/bits/funcref_impl.h\n> b/libstdc++-v3/include/bits/funcref_impl.h\n> index 3d55c8406b0..9fcab570803 100644\n> --- a/libstdc++-v3/include/bits/funcref_impl.h\n> +++ b/libstdc++-v3/include/bits/funcref_impl.h\n> @@ -129,12 +129,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>        // _GLIBCXX_RESOLVE_LIB_DEFECTS\n>        // 4256. Incorrect constrains for function_ref constructors from\n> nontype\n>        /// Target object is __fn. There is no bound object.\n> -      template<auto __fn>\n> -       requires __is_invocable_using<const decltype(__fn)&>\n> +      template<auto __cwfn, typename _Fn>\n> +       requires __is_invocable_using<const _Fn&>\n>         constexpr\n> -       function_ref(nontype_t<__fn>) noexcept\n> +       function_ref(constant_wrapper<__cwfn, _Fn>) noexcept\n>         {\n> -         using _Fn = remove_cv_t<decltype(__fn)>;\n> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn, _Fn>::value;\n> +         if constexpr (sizeof...(_ArgTypes) > 0)\n> +           if constexpr ((... &&\n> _ConstExprParam<remove_cvref_t<_ArgTypes>>))\n> +             static_assert(!requires {\n> +               typename constant_wrapper<\n> +                 std::__invoke(__fn,\n> remove_cvref_t<_ArgTypes>::value...)>;\n> +             }, \"cw<fn>(args...) should be equivalent to fn(args...)\");\n> +\n>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>             static_assert(__fn != nullptr);\n>\n> @@ -144,13 +151,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>\n>        /// Target object is equivalent to\n> std::bind_front<_fn>(std::ref(__ref)).\n>        /// Bound object is object referenced by second parameter.\n> -      template<auto __fn, typename _Up, typename _Td =\n> remove_reference_t<_Up>>\n> +      template<auto __cwfn, typename _Fn, typename _Up,\n> +              typename _Td = remove_reference_t<_Up>>\n>         requires (!is_rvalue_reference_v<_Up&&>)\n> -         && __is_invocable_using<const decltype(__fn)&, _Td\n> _GLIBCXX_MOF_CV&>\n> +                && __is_invocable_using<const _Fn&, _Td _GLIBCXX_MOF_CV&>\n>         constexpr\n> -       function_ref(nontype_t<__fn>, _Up&& __ref) noexcept\n> +       function_ref(constant_wrapper<__cwfn, _Fn>, _Up&& __ref) noexcept\n>         {\n> -         using _Fn = remove_cv_t<decltype(__fn)>;\n> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn, _Fn>::value;\n>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>             static_assert(__fn != nullptr);\n>\n> @@ -166,12 +174,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>\n>        /// Target object is equivalent to std::bind_front<_fn>(__ptr).\n>        /// Bound object is object pointed by second parameter (if any).\n> -      template<auto __fn, typename _Td>\n> -       requires __is_invocable_using<const decltype(__fn)&, _Td\n> _GLIBCXX_MOF_CV*>\n> +      template< auto __cwfn, typename _Fn, typename _Td>\n> +       requires __is_invocable_using<const _Fn&, _Td _GLIBCXX_MOF_CV*>\n>         constexpr\n> -       function_ref(nontype_t<__fn>, _Td _GLIBCXX_MOF_CV* __ptr) noexcept\n> +       function_ref(constant_wrapper<__cwfn, _Fn>, _Td _GLIBCXX_MOF_CV*\n> __ptr) noexcept\n>         {\n> -         using _Fn = remove_cv_t<decltype(__fn)>;\n> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn, _Fn>::value;\n>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>             static_assert(__fn != nullptr);\n>           if constexpr (is_member_pointer_v<_Fn>)\n> @@ -182,8 +190,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>         }\n>\n>        template<typename _Tp>\n> -       requires (!is_same_v<_Tp, function_ref>)\n> -              && (!is_pointer_v<_Tp>) && (!__is_nontype_v<_Tp>)\n> +       requires (!is_same_v<_Tp, function_ref>) && (!is_pointer_v<_Tp>)\n> +                && (!__is_constant_wrapper_v<_Tp>)\n>         function_ref&\n>         operator=(_Tp) = delete;\n>\n> diff --git a/libstdc++-v3/include/bits/funcwrap.h\n> b/libstdc++-v3/include/bits/funcwrap.h\n> index 6441893d213..b835e075295 100644\n> --- a/libstdc++-v3/include/bits/funcwrap.h\n> +++ b/libstdc++-v3/include/bits/funcwrap.h\n> @@ -573,15 +573,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>      requires is_function_v<_Fn>\n>      function_ref(_Fn*) -> function_ref<_Fn>;\n>\n> -  template<auto __f, class _Fn = remove_pointer_t<decltype(__f)>>\n> -    requires is_function_v<_Fn>\n> -    function_ref(nontype_t<__f>) -> function_ref<_Fn>;\n> +  template<auto __cwfn, typename _Fn>\n> +    requires is_function_v<remove_pointer_t<_Fn>>\n> +    function_ref(constant_wrapper<__cwfn, _Fn>)\n> +      -> function_ref<remove_pointer_t<_Fn>>;\n>\n> -  template<auto __f, typename _Tp,\n> +  template<auto __cwfn, typename _Fn, typename _Tp,\n>            typename _SignaturePtr =\n> -            decltype(__polyfunc::__deduce_funcref<decltype(__f), _Tp&>())>\n> +            decltype(__polyfunc::__deduce_funcref<_Fn, _Tp&>())>\n>      requires (!is_void_v<_SignaturePtr>)\n> -    function_ref(nontype_t<__f>, _Tp&&)\n> +    function_ref(constant_wrapper<__cwfn, _Fn>, _Tp&&)\n>        -> function_ref<remove_pointer_t<_SignaturePtr>>;\n>\n>  #endif // __glibcxx_function_ref\n> diff --git a/libstdc++-v3/include/bits/utility.h\n> b/libstdc++-v3/include/bits/utility.h\n> index 970e63e8170..93e9e9f9dba 100644\n> --- a/libstdc++-v3/include/bits/utility.h\n> +++ b/libstdc++-v3/include/bits/utility.h\n> @@ -458,6 +458,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>      { return value; }\n>    };\n>\n> +  template<typename>\n> +    constexpr bool __is_constant_wrapper_v = false;\n> +\n> +  template<auto __cw, typename _Fn>\n> +    constexpr bool __is_constant_wrapper_v<constant_wrapper<__cw, _Fn>> =\n> true;\n> +\n>    template<_CwFixedValue _Tp>\n>      constexpr auto cw = constant_wrapper<_Tp>{};\n>  #endif\n> @@ -637,23 +643,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>    inline constexpr sorted_equivalent_t sorted_equivalent{};\n>  #endif\n>\n> -#if __glibcxx_function_ref // >= C++26\n> -  template<auto>\n> -    struct nontype_t\n> -    {\n> -      explicit nontype_t() = default;\n> -    };\n> -\n> -  template<auto __val>\n> -    constexpr nontype_t<__val> nontype{};\n> -\n> -  template<typename>\n> -    inline constexpr bool __is_nontype_v = false;\n> -\n> -  template<auto __val>\n> -    inline constexpr bool __is_nontype_v<nontype_t<__val>> = true;\n> -#endif\n> -\n>  _GLIBCXX_END_NAMESPACE_VERSION\n>  } // namespace\n>\n> diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/\n> std.cc.in\n> index db66677d55b..3ac19871692 100644\n> --- a/libstdc++-v3/src/c++23/std.cc.in\n> +++ b/libstdc++-v3/src/c++23/std.cc.in\n> @@ -3651,10 +3651,6 @@ export namespace std\n>    using std::make_integer_sequence;\n>    using std::move;\n>    using std::move_if_noexcept;\n> -#if __cpp_lib_function_ref\n> -  using std::nontype_t;\n> -  using std::nontype;\n> -#endif\n>    using std::pair;\n>    using std::swap;\n>    using std::operator==;\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n> index 9b02dc49c2a..521a35fc11e 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n> @@ -8,8 +8,7 @@\n>  # error \"Feature-test macro for function_ref has wrong value in\n> <functional>\"\n>  #endif\n>\n> -using std::nontype;\n> -using std::nontype_t;\n> +using std::constant_wrapper;\n>  using std::function_ref;\n>\n>  using std::is_nothrow_move_assignable_v;\n> @@ -55,13 +54,13 @@ static_assert( ! is_assignable_v<function_ref<int(S)>,\n> decltype(&S::x)> );\n>  static_assert( ! is_assignable_v<function_ref<int(S)>, decltype(&S::f)> );\n>\n>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n> -                                      nontype_t<funS>> );\n> +                                      constant_wrapper<funS>> );\n>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n> -                                      nontype_t<&funS>> );\n> +                                      constant_wrapper<&funS>> );\n>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n> -                                      nontype_t<&S::x>> );\n> +                                      constant_wrapper<&S::x>> );\n>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n> -                                      nontype_t<&S::f>> );\n> +                                      constant_wrapper<&S::f>> );\n>  struct Q\n>  {\n>    void operator()() const;\n> @@ -75,22 +74,22 @@ static_assert( ! is_assignable_v<function_ref<void()\n> const>, Q&> );\n>  static_assert( ! is_assignable_v<function_ref<void() const>, const Q&> );\n>\n>  static_assert( is_nothrow_assignable_v<function_ref<void()>,\n> -                                      nontype_t<Q{}>> );\n> +                                      constant_wrapper<Q{}>> );\n>  static_assert( is_nothrow_assignable_v<function_ref<void() const>,\n> -                                      nontype_t<Q{}>> );\n> +                                      constant_wrapper<Q{}>> );\n>\n>  constexpr bool\n>  test_constexpr()\n>  {\n> -  function_ref<void(S)> fp(nontype<funS>);\n> -  fp = nontype<funS>;\n> -  fp = nontype<&funS>;\n> -  fp = nontype<&S::x>;\n> -  fp = nontype<&S::f>;\n> +  function_ref<void(S)> fp(std::cw<funS>);\n> +  fp = std::cw<funS>;\n> +  fp = std::cw<&funS>;\n> +  fp = std::cw<&S::x>;\n> +  fp = std::cw<&S::f>;\n>\n>    constexpr Q cq;\n>    function_ref<void() const> fq(cq);\n> -  fq = nontype<cq>;\n> +  fq = std::cw<cq>;\n>    return true;\n>  }\n>  static_assert( test_constexpr() );\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n> index 49c6030b221..386c8de790a 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n> @@ -4,7 +4,6 @@\n>  #include <utility>\n>  #include <testsuite_hooks.h>\n>\n> -using std::nontype;\n>  using std::function_ref;\n>\n>  using std::is_same_v;\n> @@ -43,7 +42,7 @@ test01()\n>    VERIFY( f0() == 0 );\n>    VERIFY( std::move(f0)() == 0 );\n>\n> -  function_ref<int()> f1{nontype<F{}>};\n> +  function_ref<int()> f1{std::cw<F{}>};\n>    VERIFY( f1() == 1 );\n>    VERIFY( std::move(f1)() == 1 );\n>\n> @@ -53,7 +52,7 @@ test01()\n>    VERIFY( std::move(f2)() == 1 );\n>    VERIFY( std::move(std::as_const(f2))() == 1 );\n>\n> -  function_ref<int() const> f3{nontype<F{}>};\n> +  function_ref<int() const> f3{std::cw<F{}>};\n>    VERIFY( f3() == 1 );\n>    VERIFY( std::as_const(f3)() == 1 );\n>    VERIFY( std::move(f3)() == 1 );\n> @@ -71,11 +70,11 @@ test02()\n>    };\n>    F::Arg arg;\n>\n> -  function_ref<int()> f0{std::nontype<F{}>, arg};\n> +  function_ref<int()> f0{std::cw<F{}>, arg};\n>    VERIFY( f0() == 0 );\n>    VERIFY( std::move(f0)() == 0 );\n>\n> -  function_ref<int() const> f1{std::nontype<F{}>, arg};\n> +  function_ref<int() const> f1{std::cw<F{}>, arg};\n>    VERIFY( f1() == 1 );\n>    VERIFY( std::as_const(f1)() == 1 );\n>  }\n> @@ -91,11 +90,11 @@ test03()\n>    };\n>    F::Arg arg;\n>\n> -  function_ref<int()> f0{std::nontype<F{}>, &arg};\n> +  function_ref<int()> f0{std::cw<F{}>, &arg};\n>    VERIFY( f0() == 0 );\n>    VERIFY( std::move(f0)() == 0 );\n>\n> -  function_ref<int() const> f1{std::nontype<F{}>, &arg};\n> +  function_ref<int() const> f1{std::cw<F{}>, &arg};\n>    VERIFY( f1() == 1 );\n>    VERIFY( std::as_const(f1)() == 1 );\n>  }\n> @@ -108,7 +107,7 @@ test04()\n>    VERIFY( f0() == 0 );\n>    VERIFY( std::move(f0)() == 0 );\n>\n> -  function_ref<int()> f1{nontype<fp>};\n> +  function_ref<int()> f1{std::cw<fp>};\n>    VERIFY( f1() == 0 );\n>    VERIFY( std::move(f1)() == 0 );\n>\n> @@ -116,7 +115,7 @@ test04()\n>    VERIFY( f2() == 0 );\n>    VERIFY( std::move(f2)() == 0 );\n>\n> -  const function_ref<int() const> f3{nontype<fp>};\n> +  const function_ref<int() const> f3{std::cw<fp>};\n>    VERIFY( f2() == 0 );\n>    VERIFY( std::move(f2)() == 0 );\n>  }\n> @@ -130,14 +129,14 @@ int callback_ref(ftype& f, int x) { return f(x); }\n>  void\n>  test05()\n>  {\n> -  function_ref<int(int)> r1(nontype<&callback_ptr>, &twice);\n> +  function_ref<int(int)> r1(std::cw<&callback_ptr>, &twice);\n>    VERIFY( r1(2) == 4 );\n> -  function_ref<int(int)> r2(nontype<&callback_ptr>, cube);\n> +  function_ref<int(int)> r2(std::cw<&callback_ptr>, cube);\n>    VERIFY( r2(2) == 8 );\n>\n> -  function_ref<int(int)> r3(nontype<&callback_ref>, twice);\n> +  function_ref<int(int)> r3(std::cw<&callback_ref>, twice);\n>    VERIFY( r3(3) == 6 );\n> -  function_ref<int(int)> r4(nontype<&callback_ref>, cube);\n> +  function_ref<int(int)> r4(std::cw<&callback_ref>, cube);\n>    VERIFY( r4(3) == 27 );\n>  }\n>\n> @@ -174,37 +173,37 @@ test06()\n>    std::function_ref<const int&(int, int) const> e8(std::as_const(csr));\n>    VERIFY( &e8(0, 0) == &s.v );\n>\n> -  std::function_ref<int&()> f1(std::nontype<&S::v>, sr);\n> +  std::function_ref<int&()> f1(std::cw<&S::v>, sr);\n>    VERIFY( &f1() == &s.v );\n> -  std::function_ref<const int&()> f2(std::nontype<&S::v>, sr);\n> +  std::function_ref<const int&()> f2(std::cw<&S::v>, sr);\n>    VERIFY( &f2() == &s.v );\n> -  std::function_ref<int&()> f3(std::nontype<&S::m>, sr);\n> +  std::function_ref<int&()> f3(std::cw<&S::m>, sr);\n>    VERIFY( &f3() == &s.v );\n> -  std::function_ref<const int&()> f4(std::nontype<&S::c>, sr);\n> +  std::function_ref<const int&()> f4(std::cw<&S::c>, sr);\n>    VERIFY( &f4() == &s.v );\n>\n> -  std::function_ref<const int&()> f5(std::nontype<&S::v>, csr);\n> +  std::function_ref<const int&()> f5(std::cw<&S::v>, csr);\n>    VERIFY( &f5() == &s.v );\n> -  std::function_ref<const int&()> f6(std::nontype<&S::c>, sr);\n> +  std::function_ref<const int&()> f6(std::cw<&S::c>, sr);\n>    VERIFY( &f6() == &s.v );\n>    static_assert( !std::is_constructible_v<\n>      std::function_ref<int&()>,\n> -    std::nontype_t<&S::c>, std::reference_wrapper<S>&>\n> +    std::constant_wrapper<&S::c>, std::reference_wrapper<S>&>\n>     );\n>\n> -  std::function_ref<int&()> f7(std::nontype<&S::v>, std::as_const(sr));\n> +  std::function_ref<int&()> f7(std::cw<&S::v>, std::as_const(sr));\n>    VERIFY( &f7() == &s.v );\n> -  std::function_ref<const int&()> f8(std::nontype<&S::m>,\n> std::as_const(sr));\n> +  std::function_ref<const int&()> f8(std::cw<&S::m>, std::as_const(sr));\n>    VERIFY( &f8() == &s.v );\n>\n>    // No rvalue reference_wrapper support\n>    static_assert( !std::is_constructible_v<\n>      std::function_ref<int&()>,\n> -    std::nontype_t<&S::v>, std::reference_wrapper<S>>\n> +    std::constant_wrapper<&S::v>, std::reference_wrapper<S>>\n>    );\n>    static_assert( !std::is_constructible_v<\n>      std::function_ref<int&()>,\n> -    std::nontype_t<&S::v>, std::reference_wrapper<const S>>\n> +    std::constant_wrapper<&S::v>, std::reference_wrapper<const S>>\n>    );\n>\n>    // reference to reference_wrapper are bound, so mutation are visible\n> @@ -232,9 +231,9 @@ test06()\n>    { return &x; };\n>\n>    // identity of reference_wrapper is preserved\n> -  std::function_ref<const std::reference_wrapper<S>*()>\n> g1(std::nontype<id>, sr);\n> +  std::function_ref<const std::reference_wrapper<S>*()> g1(std::cw<id>,\n> sr);\n>    VERIFY( g1() == &sr );\n> -  std::function_ref<const std::reference_wrapper<const S>*()>\n> g2(std::nontype<id>, csr);\n> +  std::function_ref<const std::reference_wrapper<const S>*()>\n> g2(std::cw<id>, csr);\n>    VERIFY( g2() == &csr );\n>  }\n>\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n> index a91f5ba3dab..78aebd38a07 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n> @@ -9,8 +9,7 @@\n>  # error \"Feature-test macro for function_ref has wrong value in\n> <functional>\"\n>  #endif\n>\n> -using std::nontype;\n> -using std::nontype_t;\n> +using std::constant_wrapper;\n>  using std::function_ref;\n>\n>  using std::is_default_constructible_v;\n> @@ -60,31 +59,31 @@ static_assert( !\n> is_constructible_v<function_ref<int(S)>,\n>                                     decltype(&S::f)> );\n>\n>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n> -                                         nontype_t<funS>> );\n> +                                         constant_wrapper<funS>> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n> -                                         nontype_t<&funS>> );\n> +                                         constant_wrapper<&funS>> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n> -                                         nontype_t<&S::x>> );\n> +                                         constant_wrapper<&S::x>> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n> -                                         nontype_t<&S::f>> );\n> +                                         constant_wrapper<&S::f>> );\n>\n>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n> -                                         nontype_t<funS>, S&> );\n> +                                         constant_wrapper<funS>, S&> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n> -                                         nontype_t<&funS>, S&> );\n> +                                         constant_wrapper<&funS>, S&> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n> -                                         nontype_t<&S::x>, S&> );\n> +                                         constant_wrapper<&S::x>, S&> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n> -                                         nontype_t<&S::f>, S&> );\n> +                                         constant_wrapper<&S::f>, S&> );\n>\n>  static_assert( ! is_constructible_v<function_ref<int()>,\n> -                                   nontype_t<funS>, S*> );\n> +                                   constant_wrapper<funS>, S*> );\n>  static_assert( ! is_constructible_v<function_ref<int()>,\n> -                                   nontype_t<&funS>, S*> );\n> +                                   constant_wrapper<&funS>, S*> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n> -                                         nontype_t<&S::x>, S*> );\n> +                                         constant_wrapper<&S::x>, S*> );\n>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n> -                                         nontype_t<&S::f>, S*> );\n> +                                         constant_wrapper<&S::f>, S*> );\n>\n>  struct M\n>  {\n> @@ -98,9 +97,9 @@ static_assert( !\n> is_constructible_v<function_ref<void()>, const M&> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>, M> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>, const M&>\n> );\n>  static_assert( ! is_constructible_v<function_ref<void()>,\n> -                                   nontype_t<M{}>> );\n> +                                   constant_wrapper<M{}>> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>,\n> -                                   nontype_t<M{}>> );\n> +                                   constant_wrapper<M{}>> );\n>  struct Q\n>  {\n>    void operator()(int) const;\n> @@ -115,22 +114,22 @@ static_assert(\n> is_nothrow_constructible_v<function_ref<void(int) const>, Q&> );\n>  static_assert( is_nothrow_constructible_v<function_ref<void(int) const>,\n> const Q&> );\n>\n>  static_assert( is_nothrow_constructible_v<function_ref<void(int)>,\n> -                                         nontype_t<Q{}>> );\n> +                                         constant_wrapper<Q{}>> );\n>  static_assert( is_nothrow_constructible_v<function_ref<void(int) const>,\n> -                                         nontype_t<Q{}>> );\n> +                                         constant_wrapper<Q{}>> );\n>  static_assert( is_nothrow_constructible_v<function_ref<void()>,\n> -                                         nontype_t<Q{}>, int&> );\n> +                                         constant_wrapper<Q{}>, int&> );\n>  static_assert( is_nothrow_constructible_v<function_ref<void() const>,\n> -                                         nontype_t<Q{}>, int&> );\n> +                                         constant_wrapper<Q{}>, int&> );\n>  static_assert( ! is_constructible_v<function_ref<void()>,\n> -                                   nontype_t<Q{}>, int> );\n> +                                   constant_wrapper<Q{}>, int> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>,\n> -                                   nontype_t<Q{}>, int> );\n> +                                   constant_wrapper<Q{}>, int> );\n>\n>  static_assert( is_nothrow_constructible_v<function_ref<void()>,\n> -                                         nontype_t<Q{}>, int*> );\n> +                                         constant_wrapper<Q{}>, int*> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>,\n> -                                   nontype_t<Q{}>, int*> );\n> +                                   constant_wrapper<Q{}>, int*> );\n>\n>  struct L\n>  {\n> @@ -143,9 +142,9 @@ static_assert( !\n> is_constructible_v<function_ref<void()>, const L&> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>, L> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>, const L&>\n> );\n>  static_assert( ! is_constructible_v<function_ref<void()>,\n> -                                   nontype_t<L{}>> );\n> +                                   constant_wrapper<L{}>> );\n>  static_assert( ! is_constructible_v<function_ref<void() const>,\n> -                                   nontype_t<L{}>> );\n> +                                   constant_wrapper<L{}>> );\n>\n>  struct R\n>  {\n> @@ -159,24 +158,24 @@ static_assert( !\n> is_constructible_v<function_ref<void(float) const>, R&> );\n>  static_assert( ! is_constructible_v<function_ref<void(float) const>,\n> const R&> );\n>\n>  static_assert( ! is_constructible_v<function_ref<void(float)>,\n> -                                                nontype_t<R{}>> );\n> +                                   constant_wrapper<R{}>> );\n>  static_assert( ! is_constructible_v<function_ref<void(float) const>,\n> -                                                nontype_t<R{}>> );\n> +                                   constant_wrapper<R{}>> );\n>\n>  constexpr bool\n>  test_constexpr()\n>  {\n> -  function_ref<void(S)> fp1(nontype<funS>);\n> -  function_ref<void(S)> fp3(nontype<&funS>);\n> -  function_ref<void(S)> fp4(nontype<&S::x>);\n> -  function_ref<void(S)> fp5(nontype<&S::f>);\n> +  function_ref<void(S)> fp1(std::cw<funS>);\n> +  function_ref<void(S)> fp3(std::cw<&funS>);\n> +  function_ref<void(S)> fp4(std::cw<&S::x>);\n> +  function_ref<void(S)> fp5(std::cw<&S::f>);\n>\n>    S s;\n> -  function_ref<void()> fp6(nontype<&funS>, s);\n> -  function_ref<void()> fp7(nontype<&S::x>, s);\n> -  function_ref<void()> fp8(nontype<&S::x>, &s);\n> -  function_ref<void()> fp9(nontype<&S::f>, s);\n> -  function_ref<void()> fp10(nontype<&S::f>, &s);\n> +  function_ref<void()> fp6(std::cw<&funS>, s);\n> +  function_ref<void()> fp7(std::cw<&S::x>, s);\n> +  function_ref<void()> fp8(std::cw<&S::x>, &s);\n> +  function_ref<void()> fp9(std::cw<&S::f>, s);\n> +  function_ref<void()> fp10(std::cw<&S::f>, &s);\n>\n>    M m;\n>    function_ref<void()> fm1(m);\n> @@ -190,13 +189,13 @@ test_constexpr()\n>\n>    function_ref<void(int)> fcq1(cq);\n>    function_ref<void(int) const> f(cq);\n> -  function_ref<void(int)> fcq3(nontype<cq>);\n> -  function_ref<void(int) const> fcq4(nontype<cq>);\n> +  function_ref<void(int)> fcq3(std::cw<cq>);\n> +  function_ref<void(int) const> fcq4(std::cw<cq>);\n>\n>    int i = 0;\n> -  function_ref<void()> fcq5(nontype<cq>, i);\n> -  function_ref<void() const> fcq6(nontype<cq>, i);\n> -  function_ref<void()> fcq7(nontype<cq>, &i);\n> +  function_ref<void()> fcq5(std::cw<cq>, i);\n> +  function_ref<void() const> fcq6(std::cw<cq>, i);\n> +  function_ref<void()> fcq7(std::cw<cq>, &i);\n>\n>    L l;\n>    function_ref<void()> fl1(l);\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n> index 050090df370..a426ac64cd5 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n> @@ -2,7 +2,6 @@\n>\n>  #include <functional>\n>\n> -using std::nontype;\n>  using std::function_ref;\n>\n>  struct S\n> @@ -16,15 +15,15 @@ constexpr int(*fp)(S) = nullptr;\n>  constexpr int S::*mdp = nullptr;\n>  constexpr int (S::*mfp)() = nullptr;\n>\n> -function_ref<int(S)> fd1(nontype<fp>);  // { dg-error \"from here\" }\n> -function_ref<int(S)> fd2(nontype<mdp>); // { dg-error \"from here\" }\n> -function_ref<int(S)> fd3(nontype<mfp>); // { dg-error \"from here\" }\n> +function_ref<int(S)> fd1(std::cw<fp>);  // { dg-error \"from here\" }\n> +function_ref<int(S)> fd2(std::cw<mdp>); // { dg-error \"from here\" }\n> +function_ref<int(S)> fd3(std::cw<mfp>); // { dg-error \"from here\" }\n>\n> -function_ref<int()> br4(nontype<fp>, s);  // { dg-error \"from here\" }\n> -function_ref<int()> br5(nontype<mdp>, s); // { dg-error \"from here\" }\n> -function_ref<int()> br6(nontype<mfp>, s); // { dg-error \"from here\" }\n> +function_ref<int()> br4(std::cw<fp>, s);  // { dg-error \"from here\" }\n> +function_ref<int()> br5(std::cw<mdp>, s); // { dg-error \"from here\" }\n> +function_ref<int()> br6(std::cw<mfp>, s); // { dg-error \"from here\" }\n>\n> -function_ref<int()> bp7(nontype<mdp>, &s); // { dg-error \"from here\" }\n> -function_ref<int()> bp8(nontype<mfp>, &s); // { dg-error \"from here\" }\n> +function_ref<int()> bp7(std::cw<mdp>, &s); // { dg-error \"from here\" }\n> +function_ref<int()> bp8(std::cw<mfp>, &s); // { dg-error \"from here\" }\n>\n>  // { dg-prune-output \"static assertion failed\" }\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n> new file mode 100644\n> index 00000000000..a295bc2ce31\n> --- /dev/null\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n> @@ -0,0 +1,35 @@\n> +// { dg-do compile { target c++26 } }\n> +\n> +#include <functional>\n> +\n> +using std::function_ref;\n> +using std::constant_wrapper;\n> +\n> +struct S\n> +{\n> +  int operator()() const { return 1; }\n> +\n> +  // Non-constant, so cw<S{}>(cw<1>) call never unwrapps\n> +  int operator()(int) const { return 1; }\n> +  template<auto __cw>\n> +    int operator()(constant_wrapper<__cw, int>) const { return 1; }\n> +\n> +  // Constant, cw<S{}>(cw<1>, cw<2>) calls int overload\n> +  // while S{}(cw<1>, cw<1>) calls constant_wrapper overload\n> +  constexpr int operator()(int, int) const { return 1; }\n> +  template<auto __cw1, auto __cw2>\n> +    constexpr int operator()(constant_wrapper<__cw1, int>,\n> +                            constant_wrapper<__cw2, int>)\n> +    { return 1; }\n> +};\n> +\n> +function_ref<int()> f0a(S{});\n> +\n> +function_ref<int(int)> f1a(S{});\n> +function_ref<int(constant_wrapper<2>)> f1b(std::cw<S{}>);\n> +\n> +function_ref<int(int, int)> f2a(std::cw<S{}>); // OK, runtime\n> +function_ref<int(constant_wrapper<1>, int)> f2b(std::cw<S{}>); // OK,\n> still runtime\n> +function_ref<int(constant_wrapper<2>, constant_wrapper<3>)>\n> f2c(std::cw<S{}>); // { dg-error \"from here\" }\n> +\n> +// { dg-prune-output \"static assertion failed\" }\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n> index 3cc782524f6..4ef5d067555 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n> @@ -46,7 +46,7 @@ struct NonStatic {\n>    { return x + y + v; }\n>  };\n>\n> -constexpr auto vNonType = create(std::nontype<NonStatic{3}>);\n> +constexpr auto vNonType = create(std::cw<NonStatic{3}>);\n>\n>  struct StaticWins {\n>    static int\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n> index b034c7af072..63c3f6ea7e3 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n> @@ -4,15 +4,13 @@\n>  #include <type_traits>\n>\n>  using std::is_same_v;\n> -using std::nontype;\n> -using std::nontype_t;\n>  using std::function_ref;\n>\n>  int i = 0;\n>\n>  template<auto f, class... Args>\n>    concept deductible = requires (Args&... args)\n> -  { std::function_ref(std::nontype<f>, args...); };\n> +  { std::function_ref(std::cw<f>, args...); };\n>\n>  static_assert( !deductible<1> );\n>  static_assert( !deductible<1, int> );\n> @@ -24,9 +22,9 @@ static_assert( is_same_v<decltype(function_ref(f0)),\n>                          function_ref<void()>> );\n>  static_assert( is_same_v<decltype(function_ref(f0n)),\n>                          function_ref<void() noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f0>)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f0>)),\n>                          function_ref<void()>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f0n>)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f0n>)),\n>                          function_ref<void() noexcept>> );\n>  static_assert( !deductible<f0, char*> );\n>  static_assert( !deductible<f0n, char*> );\n> @@ -38,13 +36,13 @@ static_assert( is_same_v<decltype(function_ref(f1)),\n>                          function_ref<void(int)>> );\n>  static_assert( is_same_v<decltype(function_ref(f1n)),\n>                          function_ref<void(int) noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f1>)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f1>)),\n>                          function_ref<void(int)>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f1n>)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f1n>)),\n>                          function_ref<void(int) noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f1>, i)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f1>, i)),\n>                          function_ref<void()>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f1n>, i)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f1n>, i)),\n>                          function_ref<void() noexcept>> );\n>  static_assert( !deductible<f1, char*> );\n>  static_assert( !deductible<f1n, char*> );\n> @@ -56,13 +54,13 @@ static_assert( is_same_v<decltype(function_ref(f2)),\n>                          function_ref<void(int*, int)>> );\n>  static_assert( is_same_v<decltype(function_ref(f2n)),\n>                          function_ref<void(int*, int) noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f2>)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f2>)),\n>                          function_ref<void(int*, int)>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f2n>)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f2n>)),\n>                          function_ref<void(int*, int) noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f2>, &i)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f2>, &i)),\n>                          function_ref<void(int)>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<f2n>, &i)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<f2n>, &i)),\n>                          function_ref<void(int) noexcept>> );\n>  static_assert( !deductible<f2, char*> );\n>  static_assert( !deductible<f2n, char*> );\n> @@ -88,40 +86,40 @@ struct S\n>  S s{};\n>  const S cs{};\n>\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, s)),\n>                          function_ref<int&() noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, cs)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, cs)),\n>                          function_ref<const int&() noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, &s)),\n>                          function_ref<int&() noexcept>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &cs)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, &cs)),\n>                          function_ref<const int&() noexcept>> );\n>  static_assert( !deductible<&S::mem, int> );\n>\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::f>, s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::f>, s)),\n>                          function_ref<int()>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fn>, &s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fn>, &s)),\n>                          function_ref<int() noexcept>> );\n>  static_assert( !deductible<&S::f, char*> );\n>  static_assert( !deductible<&S::fn, char*> );\n>  static_assert( !deductible<&S::f, const S> );\n>  static_assert( !deductible<&S::fn, const S> );\n>\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fc>, &s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fc>, &s)),\n>                          function_ref<int(int)>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcn>, s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcn>, s)),\n>                          function_ref<int(int) noexcept>> );\n>  static_assert( !deductible<&S::fc, char*> );\n>  static_assert( !deductible<&S::fcn, char*> );\n>\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fl>, &s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fl>, &s)),\n>                          function_ref<int(int)>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fln>, s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fln>, s)),\n>                          function_ref<int(int) noexcept>> );\n>\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcl>, s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcl>, s)),\n>                          function_ref<int(float)>> );\n> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcln>, &s)),\n> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcln>, &s)),\n>                          function_ref<int(float) noexcept>> );\n>\n>  static_assert( !deductible<&S::fr, char*> );\n> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n> b/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n> index 32c6931e9a8..d55f4facbda 100644\n> --- a/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n> +++ b/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n> @@ -3,7 +3,6 @@\n>  #include <functional>\n>  #include <testsuite_hooks.h>\n>\n> -using std::nontype;\n>  using std::function_ref;\n>\n>  void\n> @@ -55,8 +54,8 @@ test02()\n>    };\n>    S s{10};\n>\n> -  function_ref<int()> r1(nontype<&S::x>, s);\n> -  function_ref<long()> r2(nontype<&S::x>, &s);\n> +  function_ref<int()> r1(std::cw<&S::x>, s);\n> +  function_ref<long()> r2(std::cw<&S::x>, &s);\n>\n>    VERIFY( r1() == 10 );\n>    VERIFY( r2() == 10 );\n> @@ -66,8 +65,8 @@ test02()\n>    VERIFY( r1() == 20 );\n>    VERIFY( r2() == 20 );\n>\n> -  r1 = function_ref<int()>(nontype<&S::f>, &s);\n> -  r2 = function_ref<long()>(nontype<&S::f>, s);\n> +  r1 = function_ref<int()>(std::cw<&S::f>, &s);\n> +  r2 = function_ref<long()>(std::cw<&S::f>, s);\n>\n>    VERIFY( r1() == 20 );\n>    VERIFY( r2() == 20 );\n> --\n> 2.53.0\n>\n>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=HDezlnhj;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=HDezlnhj","sourceware.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com","sourceware.org; spf=pass smtp.mailfrom=gmail.com","server2.sourceware.org;\n arc=pass smtp.remote-ip=209.85.167.46"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frJbY0YtXz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 20:05:27 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id A20AE4BA2E0D\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  8 Apr 2026 10:05:25 +0000 (GMT)","from mail-lf1-f46.google.com (mail-lf1-f46.google.com\n [209.85.167.46])\n by sourceware.org (Postfix) with ESMTPS id 4FB684BA2E14\n for <gcc-patches@gcc.gnu.org>; Wed,  8 Apr 2026 10:04:45 +0000 (GMT)","by mail-lf1-f46.google.com with SMTP id\n 2adb3069b0e04-5a3d2824e4bso5207678e87.3\n for <gcc-patches@gcc.gnu.org>; Wed, 08 Apr 2026 03:04:45 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org A20AE4BA2E0D","OpenDKIM Filter v2.11.0 sourceware.org 4FB684BA2E14"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 4FB684BA2E14","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 4FB684BA2E14","ARC-Seal":["i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1775642685; cv=pass;\n b=D0YnoPjNS/QzVij78BWO1rnJMqy+QpFYOXZ3BodUMFZMQiSsVrnAG22pcg/cQ8r/dKeSR2p5FuLdc65mpRHr0CnatFmzVc01BxTyALUjUnsKGMNs4W9QuPiipTrdwDq+mqIePsdpo6MAjHMlsonzg9GCJD9em6AtFXqnNWwlVJU=","i=1; a=rsa-sha256; t=1775642684; cv=none;\n d=google.com; s=arc-20240605;\n b=Z/e5uFauv+F1OgdwyK2uwvfyL7LenanfW+NAP0poejMJ+x/Dvu9x6SEts5GnsU6bNK\n YjzpP8xt2TbtdpVcp8wZIWPR4gVZb2IYshvWfOcjxXckxRToyluo3rB6m97UV7kQm09k\n F6gtYDXNFjXHrMdp4JR8QaMzZeDD7Se+JJPuF8Si9olHpx0oT3X0BpMokWnf2BIaiBfM\n eBsWuH2I2TWvQr7Jxfu7wkqF3dOSJjhazd6AmHhg9xpGfPajbiXubczxZglT4K1PzLDn\n JiZdGhD5wDxhX3FhkYzQqK7osVgqQmza3jh8mQ0T9v2HtTo9wM2Ln4bG9hUpnys3tWm9\n O/iQ=="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775642685; c=relaxed/simple;\n bh=IhOwYQr19BhiRWFA5PX7MawPO++n7ne33Y9EFJAMCPs=;\n h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;\n b=U3tUuqxP+zbVLXKHoJaIBLMTBP1o+lfE/95OFIdRE219gKEZxc7G/cQVX9zWTgPBFnlazYhNBl/zfxV5Y6JSojzgr9yVJ4E9s8q17E58tNJjbk820uEbyW39smsu0H9uPUO52RerLFyXUUGPr3IGRwUACYqJmfj5qjQjzqaKGd4=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:dkim-signature;\n bh=R7xbEC7Oirbl5qXULVAprwfau6o1q0/o5ZMOpBrdPlI=;\n fh=gN2FLhrfpRlZ8jg64Gdr2C7lXcme2x+GsYU4+YgYNUY=;\n b=D67vViIwLaIaaLCxWZ/waOQS9is9mtsS2dyslN9M2K9k7/o6YtKj19FFRKdIEFkto3\n 7TXba30//Wg9ARIVMfYFFR6sSTYf1Div55YPC0s5R8bAR8D0rfXbUst7j51Fd/G//QpC\n xW8ZnzSSenJeJQzY+5wFfkkdJj7sg5OfR26faqQImEFuUOJr06FdJzCwss6ENoAvtOM8\n bo2/FqFiWIUApjtjJ25gaYW00TzC/Hso0TN8GDuzDjZeLHyNFNQc0ieROws2GQabQ+0G\n nAR3kCOHmscoy7nljTMg7e0fcw2eUDut/LNKNW0vr/wxhDKx2ziBUUmVmNAbjsuyLAA0\n czyg==; darn=gcc.gnu.org"],"ARC-Authentication-Results":["i=2; server2.sourceware.org","i=1; mx.google.com; arc=none"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1775642684; x=1776247484; darn=gcc.gnu.org;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:from:to:cc:subject:date:message-id:reply-to;\n bh=R7xbEC7Oirbl5qXULVAprwfau6o1q0/o5ZMOpBrdPlI=;\n b=HDezlnhji7PMfpLCdcKSvBdzIeiGfW3rztezhAgv1RPv8nBQEd9dJBG0TOXo9DisOI\n y0/xSJB9LK+iuO+D8mOUTZnDqJbnUs7Rk2XQuO76zzQEwkPmn9zQ5RN0lPAgavfeqKN3\n J8pgbvTm/YxIAuVwkssdoEuyt1avV6k01w3VBMV11pAVlpZ1FBYByPalFCTvsCpWCIos\n XSmB49id2uXLzttVXjEJCGvEb6U13lTErzvnF2yxLu72GicO9tOMhjUHekHJPIuPQid+\n ekCsE7DDIAdVXFVnSZTYNlvVmPAr7esUNvAk/I8iWBuy6nGkD4m005r0NVrjzbtiTnO/\n HZZg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775642684; x=1776247484;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=R7xbEC7Oirbl5qXULVAprwfau6o1q0/o5ZMOpBrdPlI=;\n b=PObiQ6o/Pq3Kfa5NPpp5sHAoLpX21DdEf4+gdLDv9rafVbRUU0xskEc1aYkF5oApVk\n Xqp6rpmwE+0RnLzR63MjunOoGm0+hnPBO35MymdVqcGeJnUbyqlKHyhWblrf91CBbYE4\n fnwx8xj0Z6UxLEq8e0mQ648JBtGi1bX16e7hH552eAFAkUr2S8wGu/RzN8hFoCwfz7V1\n GKg2/jXPfNHdODUOYfDpkY0HV3idtonywbdFJqUCkM/3KXJb5YHDoEslOhyy8LoskhRJ\n q+pjgtHww9tESiXmq4cGVUY3oJTUEe+o8Tblw8Zpy9QUZFcaU4vgzKmuM1VJABLtG7hS\n RoZw==","X-Forwarded-Encrypted":"i=1;\n AJvYcCXS4aBJHw6ttpVbDl+ngEng9OR1d2pV7VIEPVGF82lp79QjQIYDdYMEXuoi5cxHmb5kiK4BJFlydX7Qng==@gcc.gnu.org","X-Gm-Message-State":"AOJu0Ywmk8mzc8gpCsPYOHsEi+LZig0cH2CQVBnHX9SeOBtrowtj9Z2b\n i3ZbIqK/yBhFZ6To9zwIbUW0He9hOB6H1EmciaiTTfmEKHV4wfQnptPE0Sfv2vT3xfOw+IMCdcM\n +0BP266v4cnmhVgoA6pv8K3kKxqGfi9Y=","X-Gm-Gg":"AeBDievY0Ib8pZAeer2itFfzQCJW2MhwGCi7rBSTwggrSfJxtWNu9nsskvgkHkyl6wF\n 4aoHc6he1QVqB6J0iSgoibXcspqqN1hmFRvXssTScFpRQTcY81eDJLNbbaPBhfMPwdwsEghykpr\n p+2Ial569HL3TYUXzRocIvgDQcd0FLWrdc1v2LkkGHqnoGloh5kp2cUkTCNp0etvfv/oKjtZd8T\n XMWi0ciHADeED5ZqlPhbjABQQPF4+7471cuw4kv/krG1XboB7aFfUS7n0kPiXB6jtK23yIXxByz\n XgcUJT7MwASYAeq8eYNx1MNFEOHcjKwXAwTb3VCmsdtNA4gOxtCaMz6ljAcHYleZuSGGqeYOoAw\n u0IhGvtdpCpe5np4wIynvpAC+Nqk=","X-Received":"by 2002:ac2:558b:0:b0:5a3:d100:3c82 with SMTP id\n 2adb3069b0e04-5a3d1003da8mr3952227e87.23.1775642683230; Wed, 08 Apr 2026\n 03:04:43 -0700 (PDT)","MIME-Version":"1.0","References":"<20260408094553.155396-1-tkaminsk@redhat.com>","In-Reply-To":"<20260408094553.155396-1-tkaminsk@redhat.com>","From":"Jonathan Wakely <jwakely.gcc@gmail.com>","Date":"Wed, 8 Apr 2026 11:04:32 +0100","X-Gm-Features":"AQROBzANV-FuXxPejb74k1Q_uFZuRRUFL-XeiFYwbQ5KPFMEs2ZnVB5QCLnDNRc","Message-ID":"\n <CAH6eHdSx5kSs6JuBBv6MZaXk6o1kMk-uwN=kTxWTOODKcjvKww@mail.gmail.com>","Subject":"Re: [PATCH] libstdc++: Remove non_type and replace it with\n constant_wrapper in function_ref","To":"=?utf-8?q?Tomasz_Kami=C5=84ski?= <tkaminsk@redhat.com>","Cc":"\"libstdc++\" <libstdc++@gcc.gnu.org>,\n gcc-patches <gcc-patches@gcc.gnu.org>,\n Matthias Kretz <m.kretz@gsi.de>","Content-Type":"multipart/alternative; boundary=\"00000000000061d12b064ef0072e\"","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}},{"id":3674756,"web_url":"http://patchwork.ozlabs.org/comment/3674756/","msgid":"<CAKvuMXC9h_u8EaKGL7Pc_3g0hfuGaPjp6j4-iXJ5RQ1GahMOTg@mail.gmail.com>","list_archive_url":null,"date":"2026-04-08T12:56:09","subject":"Re: [PATCH] libstdc++: Remove non_type and replace it with\n constant_wrapper in function_ref","submitter":{"id":90409,"url":"http://patchwork.ozlabs.org/api/people/90409/","name":"Tomasz Kamiński","email":"tkaminsk@redhat.com"},"content":"I have forgotten to bump function_ref FTM, but that turned out to be good\nthing, because we have another paper\nbumping it at the same time:\nhttps://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3961r0.html\nShould we use 202304L for the second paper? They seem separable, but we\nwill inflict some order.\n\n\nOn Wed, Apr 8, 2026 at 12:04 PM Jonathan Wakely <jwakely.gcc@gmail.com>\nwrote:\n\n>\n>\n> On Wed, 8 Apr 2026, 10:46 Tomasz Kamiński, <tkaminsk@redhat.com> wrote:\n>\n>> From: Matthias Kretz <m.kretz@gsi.de>\n>>\n>> This implements P3948R1: constant_wrapper is the only tool needed\n>> for passing constant expressions via function arguments.\n>>\n>> This changes function_ref from nontype_t to constant_wrapper and\n>> implements the ambiguity check (static_asert in function_ref\n>> from constant_wrapper constructor).\n>>\n>> In addition to P3948R1 this also includes the (forgotten) deduction\n>> guide changes suggested in the draft PR [1].\n>>\n>> [1] https://github.com/cplusplus/draft/pull/8878\n>>\n>> libstdc++-v3/ChangeLog:\n>>\n>>         * include/bits/funcref_impl.h (function_ref::function_ref):\n>>         Change nontype_t parameter to constant_wrapper, and adjust\n>>         accordingly. Add static_assert detecting ambigous semantics.\n>>         (function_refoperator=): Detect constant_wrapper rather than\n>>         nontype_t.\n>>\n>\n> Missing :: here\n>\n>         * include/bits/funcwrap.h (function_ref): Change\n>>         * include/bits/utility.h (std::nontype_t, std::nontype)\n>>         (std::__is_nontype_v): Remove.\n>>         (_is_constant_wrapper_v): Define.\n>>\n>\n> And _ here\n>\n> The patch itself is fine, so OK with those two tweaks to the changelog.\n>\n>\n>         * src/c++23/std.cc.in (std::nontype_t, std::nontype):\n>>         Remove exports.\n>>         * testsuite/20_util/function_ref/cw_cons_neg.cc: New tests\n>>         for ambiguity check.\n>>         * testsuite/20_util/function_ref/assign.cc: Replace nontype_t\n>>         with constant_wrapper and nontype with std::cw.\n>>         * testsuite/20_util/function_ref/call.cc: Likewise.\n>>         * testsuite/20_util/function_ref/cons.cc: Likewise.\n>>         * testsuite/20_util/function_ref/cons_neg.cc: Likewise.\n>>         * testsuite/20_util/function_ref/deduction.cc: Likewise.\n>>         * testsuite/20_util/function_ref/mutation.cc: Likewise.\n>>\n>> Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>\n>> Signed-off-by: Matthias Kretz <m.kretz@gsi.de>\n>> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>\n>> ---\n>> This is based on Matthias patch from formge:\n>>\n>> https://forge.sourceware.org/gcc/gcc-TEST/pulls/147/commits/cac7355bcbd7ea8b5e26f064922e8f4412a4da97\n>>\n>> I have applied small adjustment to names and parameter specification,\n>> to be more consistient with the standard. Outside of that I have reworked\n>> static_assert to reflect more closely what is in the standard, and added\n>> negative test (cw_const_neg.cc).\n>>\n>> Testing on x86_64-linux. All *function_ref* test already passed in\n>> all standard modes and with modules. OK for trunk when all test passes?\n>>\n>>\n>>  libstdc++-v3/include/bits/funcref_impl.h      | 36 ++++----\n>>  libstdc++-v3/include/bits/funcwrap.h          | 13 +--\n>>  libstdc++-v3/include/bits/utility.h           | 23 ++---\n>>  libstdc++-v3/src/c++23/std.cc.in              |  4 -\n>>  .../testsuite/20_util/function_ref/assign.cc  | 27 +++---\n>>  .../testsuite/20_util/function_ref/call.cc    | 51 ++++++------\n>>  .../testsuite/20_util/function_ref/cons.cc    | 83 +++++++++----------\n>>  .../20_util/function_ref/cons_neg.cc          | 17 ++--\n>>  .../20_util/function_ref/cw_cons_neg.cc       | 35 ++++++++\n>>  .../20_util/function_ref/dangling.cc          |  2 +-\n>>  .../20_util/function_ref/deduction.cc         | 48 +++++------\n>>  .../20_util/function_ref/mutation.cc          |  9 +-\n>>  12 files changed, 185 insertions(+), 163 deletions(-)\n>>  create mode 100644\n>> libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>>\n>> diff --git a/libstdc++-v3/include/bits/funcref_impl.h\n>> b/libstdc++-v3/include/bits/funcref_impl.h\n>> index 3d55c8406b0..9fcab570803 100644\n>> --- a/libstdc++-v3/include/bits/funcref_impl.h\n>> +++ b/libstdc++-v3/include/bits/funcref_impl.h\n>> @@ -129,12 +129,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>        // _GLIBCXX_RESOLVE_LIB_DEFECTS\n>>        // 4256. Incorrect constrains for function_ref constructors from\n>> nontype\n>>        /// Target object is __fn. There is no bound object.\n>> -      template<auto __fn>\n>> -       requires __is_invocable_using<const decltype(__fn)&>\n>> +      template<auto __cwfn, typename _Fn>\n>> +       requires __is_invocable_using<const _Fn&>\n>>         constexpr\n>> -       function_ref(nontype_t<__fn>) noexcept\n>> +       function_ref(constant_wrapper<__cwfn, _Fn>) noexcept\n>>         {\n>> -         using _Fn = remove_cv_t<decltype(__fn)>;\n>> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn,\n>> _Fn>::value;\n>> +         if constexpr (sizeof...(_ArgTypes) > 0)\n>> +           if constexpr ((... &&\n>> _ConstExprParam<remove_cvref_t<_ArgTypes>>))\n>> +             static_assert(!requires {\n>> +               typename constant_wrapper<\n>> +                 std::__invoke(__fn,\n>> remove_cvref_t<_ArgTypes>::value...)>;\n>> +             }, \"cw<fn>(args...) should be equivalent to fn(args...)\");\n>> +\n>>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>>             static_assert(__fn != nullptr);\n>>\n>> @@ -144,13 +151,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>\n>>        /// Target object is equivalent to\n>> std::bind_front<_fn>(std::ref(__ref)).\n>>        /// Bound object is object referenced by second parameter.\n>> -      template<auto __fn, typename _Up, typename _Td =\n>> remove_reference_t<_Up>>\n>> +      template<auto __cwfn, typename _Fn, typename _Up,\n>> +              typename _Td = remove_reference_t<_Up>>\n>>         requires (!is_rvalue_reference_v<_Up&&>)\n>> -         && __is_invocable_using<const decltype(__fn)&, _Td\n>> _GLIBCXX_MOF_CV&>\n>> +                && __is_invocable_using<const _Fn&, _Td _GLIBCXX_MOF_CV&>\n>>         constexpr\n>> -       function_ref(nontype_t<__fn>, _Up&& __ref) noexcept\n>> +       function_ref(constant_wrapper<__cwfn, _Fn>, _Up&& __ref) noexcept\n>>         {\n>> -         using _Fn = remove_cv_t<decltype(__fn)>;\n>> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn,\n>> _Fn>::value;\n>>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>>             static_assert(__fn != nullptr);\n>>\n>> @@ -166,12 +174,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>\n>>        /// Target object is equivalent to std::bind_front<_fn>(__ptr).\n>>        /// Bound object is object pointed by second parameter (if any).\n>> -      template<auto __fn, typename _Td>\n>> -       requires __is_invocable_using<const decltype(__fn)&, _Td\n>> _GLIBCXX_MOF_CV*>\n>> +      template< auto __cwfn, typename _Fn, typename _Td>\n>> +       requires __is_invocable_using<const _Fn&, _Td _GLIBCXX_MOF_CV*>\n>>         constexpr\n>> -       function_ref(nontype_t<__fn>, _Td _GLIBCXX_MOF_CV* __ptr) noexcept\n>> +       function_ref(constant_wrapper<__cwfn, _Fn>, _Td _GLIBCXX_MOF_CV*\n>> __ptr) noexcept\n>>         {\n>> -         using _Fn = remove_cv_t<decltype(__fn)>;\n>> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn,\n>> _Fn>::value;\n>>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>>             static_assert(__fn != nullptr);\n>>           if constexpr (is_member_pointer_v<_Fn>)\n>> @@ -182,8 +190,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>         }\n>>\n>>        template<typename _Tp>\n>> -       requires (!is_same_v<_Tp, function_ref>)\n>> -              && (!is_pointer_v<_Tp>) && (!__is_nontype_v<_Tp>)\n>> +       requires (!is_same_v<_Tp, function_ref>) && (!is_pointer_v<_Tp>)\n>> +                && (!__is_constant_wrapper_v<_Tp>)\n>>         function_ref&\n>>         operator=(_Tp) = delete;\n>>\n>> diff --git a/libstdc++-v3/include/bits/funcwrap.h\n>> b/libstdc++-v3/include/bits/funcwrap.h\n>> index 6441893d213..b835e075295 100644\n>> --- a/libstdc++-v3/include/bits/funcwrap.h\n>> +++ b/libstdc++-v3/include/bits/funcwrap.h\n>> @@ -573,15 +573,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>      requires is_function_v<_Fn>\n>>      function_ref(_Fn*) -> function_ref<_Fn>;\n>>\n>> -  template<auto __f, class _Fn = remove_pointer_t<decltype(__f)>>\n>> -    requires is_function_v<_Fn>\n>> -    function_ref(nontype_t<__f>) -> function_ref<_Fn>;\n>> +  template<auto __cwfn, typename _Fn>\n>> +    requires is_function_v<remove_pointer_t<_Fn>>\n>> +    function_ref(constant_wrapper<__cwfn, _Fn>)\n>> +      -> function_ref<remove_pointer_t<_Fn>>;\n>>\n>> -  template<auto __f, typename _Tp,\n>> +  template<auto __cwfn, typename _Fn, typename _Tp,\n>>            typename _SignaturePtr =\n>> -            decltype(__polyfunc::__deduce_funcref<decltype(__f),\n>> _Tp&>())>\n>> +            decltype(__polyfunc::__deduce_funcref<_Fn, _Tp&>())>\n>>      requires (!is_void_v<_SignaturePtr>)\n>> -    function_ref(nontype_t<__f>, _Tp&&)\n>> +    function_ref(constant_wrapper<__cwfn, _Fn>, _Tp&&)\n>>        -> function_ref<remove_pointer_t<_SignaturePtr>>;\n>>\n>>  #endif // __glibcxx_function_ref\n>> diff --git a/libstdc++-v3/include/bits/utility.h\n>> b/libstdc++-v3/include/bits/utility.h\n>> index 970e63e8170..93e9e9f9dba 100644\n>> --- a/libstdc++-v3/include/bits/utility.h\n>> +++ b/libstdc++-v3/include/bits/utility.h\n>> @@ -458,6 +458,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>      { return value; }\n>>    };\n>>\n>> +  template<typename>\n>> +    constexpr bool __is_constant_wrapper_v = false;\n>> +\n>> +  template<auto __cw, typename _Fn>\n>> +    constexpr bool __is_constant_wrapper_v<constant_wrapper<__cw, _Fn>>\n>> = true;\n>> +\n>>    template<_CwFixedValue _Tp>\n>>      constexpr auto cw = constant_wrapper<_Tp>{};\n>>  #endif\n>> @@ -637,23 +643,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>    inline constexpr sorted_equivalent_t sorted_equivalent{};\n>>  #endif\n>>\n>> -#if __glibcxx_function_ref // >= C++26\n>> -  template<auto>\n>> -    struct nontype_t\n>> -    {\n>> -      explicit nontype_t() = default;\n>> -    };\n>> -\n>> -  template<auto __val>\n>> -    constexpr nontype_t<__val> nontype{};\n>> -\n>> -  template<typename>\n>> -    inline constexpr bool __is_nontype_v = false;\n>> -\n>> -  template<auto __val>\n>> -    inline constexpr bool __is_nontype_v<nontype_t<__val>> = true;\n>> -#endif\n>> -\n>>  _GLIBCXX_END_NAMESPACE_VERSION\n>>  } // namespace\n>>\n>> diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/\n>> std.cc.in\n>> index db66677d55b..3ac19871692 100644\n>> --- a/libstdc++-v3/src/c++23/std.cc.in\n>> +++ b/libstdc++-v3/src/c++23/std.cc.in\n>> @@ -3651,10 +3651,6 @@ export namespace std\n>>    using std::make_integer_sequence;\n>>    using std::move;\n>>    using std::move_if_noexcept;\n>> -#if __cpp_lib_function_ref\n>> -  using std::nontype_t;\n>> -  using std::nontype;\n>> -#endif\n>>    using std::pair;\n>>    using std::swap;\n>>    using std::operator==;\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>> index 9b02dc49c2a..521a35fc11e 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>> @@ -8,8 +8,7 @@\n>>  # error \"Feature-test macro for function_ref has wrong value in\n>> <functional>\"\n>>  #endif\n>>\n>> -using std::nontype;\n>> -using std::nontype_t;\n>> +using std::constant_wrapper;\n>>  using std::function_ref;\n>>\n>>  using std::is_nothrow_move_assignable_v;\n>> @@ -55,13 +54,13 @@ static_assert( !\n>> is_assignable_v<function_ref<int(S)>, decltype(&S::x)> );\n>>  static_assert( ! is_assignable_v<function_ref<int(S)>, decltype(&S::f)>\n>> );\n>>\n>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>> -                                      nontype_t<funS>> );\n>> +                                      constant_wrapper<funS>> );\n>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>> -                                      nontype_t<&funS>> );\n>> +                                      constant_wrapper<&funS>> );\n>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>> -                                      nontype_t<&S::x>> );\n>> +                                      constant_wrapper<&S::x>> );\n>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>> -                                      nontype_t<&S::f>> );\n>> +                                      constant_wrapper<&S::f>> );\n>>  struct Q\n>>  {\n>>    void operator()() const;\n>> @@ -75,22 +74,22 @@ static_assert( ! is_assignable_v<function_ref<void()\n>> const>, Q&> );\n>>  static_assert( ! is_assignable_v<function_ref<void() const>, const Q&> );\n>>\n>>  static_assert( is_nothrow_assignable_v<function_ref<void()>,\n>> -                                      nontype_t<Q{}>> );\n>> +                                      constant_wrapper<Q{}>> );\n>>  static_assert( is_nothrow_assignable_v<function_ref<void() const>,\n>> -                                      nontype_t<Q{}>> );\n>> +                                      constant_wrapper<Q{}>> );\n>>\n>>  constexpr bool\n>>  test_constexpr()\n>>  {\n>> -  function_ref<void(S)> fp(nontype<funS>);\n>> -  fp = nontype<funS>;\n>> -  fp = nontype<&funS>;\n>> -  fp = nontype<&S::x>;\n>> -  fp = nontype<&S::f>;\n>> +  function_ref<void(S)> fp(std::cw<funS>);\n>> +  fp = std::cw<funS>;\n>> +  fp = std::cw<&funS>;\n>> +  fp = std::cw<&S::x>;\n>> +  fp = std::cw<&S::f>;\n>>\n>>    constexpr Q cq;\n>>    function_ref<void() const> fq(cq);\n>> -  fq = nontype<cq>;\n>> +  fq = std::cw<cq>;\n>>    return true;\n>>  }\n>>  static_assert( test_constexpr() );\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>> index 49c6030b221..386c8de790a 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>> @@ -4,7 +4,6 @@\n>>  #include <utility>\n>>  #include <testsuite_hooks.h>\n>>\n>> -using std::nontype;\n>>  using std::function_ref;\n>>\n>>  using std::is_same_v;\n>> @@ -43,7 +42,7 @@ test01()\n>>    VERIFY( f0() == 0 );\n>>    VERIFY( std::move(f0)() == 0 );\n>>\n>> -  function_ref<int()> f1{nontype<F{}>};\n>> +  function_ref<int()> f1{std::cw<F{}>};\n>>    VERIFY( f1() == 1 );\n>>    VERIFY( std::move(f1)() == 1 );\n>>\n>> @@ -53,7 +52,7 @@ test01()\n>>    VERIFY( std::move(f2)() == 1 );\n>>    VERIFY( std::move(std::as_const(f2))() == 1 );\n>>\n>> -  function_ref<int() const> f3{nontype<F{}>};\n>> +  function_ref<int() const> f3{std::cw<F{}>};\n>>    VERIFY( f3() == 1 );\n>>    VERIFY( std::as_const(f3)() == 1 );\n>>    VERIFY( std::move(f3)() == 1 );\n>> @@ -71,11 +70,11 @@ test02()\n>>    };\n>>    F::Arg arg;\n>>\n>> -  function_ref<int()> f0{std::nontype<F{}>, arg};\n>> +  function_ref<int()> f0{std::cw<F{}>, arg};\n>>    VERIFY( f0() == 0 );\n>>    VERIFY( std::move(f0)() == 0 );\n>>\n>> -  function_ref<int() const> f1{std::nontype<F{}>, arg};\n>> +  function_ref<int() const> f1{std::cw<F{}>, arg};\n>>    VERIFY( f1() == 1 );\n>>    VERIFY( std::as_const(f1)() == 1 );\n>>  }\n>> @@ -91,11 +90,11 @@ test03()\n>>    };\n>>    F::Arg arg;\n>>\n>> -  function_ref<int()> f0{std::nontype<F{}>, &arg};\n>> +  function_ref<int()> f0{std::cw<F{}>, &arg};\n>>    VERIFY( f0() == 0 );\n>>    VERIFY( std::move(f0)() == 0 );\n>>\n>> -  function_ref<int() const> f1{std::nontype<F{}>, &arg};\n>> +  function_ref<int() const> f1{std::cw<F{}>, &arg};\n>>    VERIFY( f1() == 1 );\n>>    VERIFY( std::as_const(f1)() == 1 );\n>>  }\n>> @@ -108,7 +107,7 @@ test04()\n>>    VERIFY( f0() == 0 );\n>>    VERIFY( std::move(f0)() == 0 );\n>>\n>> -  function_ref<int()> f1{nontype<fp>};\n>> +  function_ref<int()> f1{std::cw<fp>};\n>>    VERIFY( f1() == 0 );\n>>    VERIFY( std::move(f1)() == 0 );\n>>\n>> @@ -116,7 +115,7 @@ test04()\n>>    VERIFY( f2() == 0 );\n>>    VERIFY( std::move(f2)() == 0 );\n>>\n>> -  const function_ref<int() const> f3{nontype<fp>};\n>> +  const function_ref<int() const> f3{std::cw<fp>};\n>>    VERIFY( f2() == 0 );\n>>    VERIFY( std::move(f2)() == 0 );\n>>  }\n>> @@ -130,14 +129,14 @@ int callback_ref(ftype& f, int x) { return f(x); }\n>>  void\n>>  test05()\n>>  {\n>> -  function_ref<int(int)> r1(nontype<&callback_ptr>, &twice);\n>> +  function_ref<int(int)> r1(std::cw<&callback_ptr>, &twice);\n>>    VERIFY( r1(2) == 4 );\n>> -  function_ref<int(int)> r2(nontype<&callback_ptr>, cube);\n>> +  function_ref<int(int)> r2(std::cw<&callback_ptr>, cube);\n>>    VERIFY( r2(2) == 8 );\n>>\n>> -  function_ref<int(int)> r3(nontype<&callback_ref>, twice);\n>> +  function_ref<int(int)> r3(std::cw<&callback_ref>, twice);\n>>    VERIFY( r3(3) == 6 );\n>> -  function_ref<int(int)> r4(nontype<&callback_ref>, cube);\n>> +  function_ref<int(int)> r4(std::cw<&callback_ref>, cube);\n>>    VERIFY( r4(3) == 27 );\n>>  }\n>>\n>> @@ -174,37 +173,37 @@ test06()\n>>    std::function_ref<const int&(int, int) const> e8(std::as_const(csr));\n>>    VERIFY( &e8(0, 0) == &s.v );\n>>\n>> -  std::function_ref<int&()> f1(std::nontype<&S::v>, sr);\n>> +  std::function_ref<int&()> f1(std::cw<&S::v>, sr);\n>>    VERIFY( &f1() == &s.v );\n>> -  std::function_ref<const int&()> f2(std::nontype<&S::v>, sr);\n>> +  std::function_ref<const int&()> f2(std::cw<&S::v>, sr);\n>>    VERIFY( &f2() == &s.v );\n>> -  std::function_ref<int&()> f3(std::nontype<&S::m>, sr);\n>> +  std::function_ref<int&()> f3(std::cw<&S::m>, sr);\n>>    VERIFY( &f3() == &s.v );\n>> -  std::function_ref<const int&()> f4(std::nontype<&S::c>, sr);\n>> +  std::function_ref<const int&()> f4(std::cw<&S::c>, sr);\n>>    VERIFY( &f4() == &s.v );\n>>\n>> -  std::function_ref<const int&()> f5(std::nontype<&S::v>, csr);\n>> +  std::function_ref<const int&()> f5(std::cw<&S::v>, csr);\n>>    VERIFY( &f5() == &s.v );\n>> -  std::function_ref<const int&()> f6(std::nontype<&S::c>, sr);\n>> +  std::function_ref<const int&()> f6(std::cw<&S::c>, sr);\n>>    VERIFY( &f6() == &s.v );\n>>    static_assert( !std::is_constructible_v<\n>>      std::function_ref<int&()>,\n>> -    std::nontype_t<&S::c>, std::reference_wrapper<S>&>\n>> +    std::constant_wrapper<&S::c>, std::reference_wrapper<S>&>\n>>     );\n>>\n>> -  std::function_ref<int&()> f7(std::nontype<&S::v>, std::as_const(sr));\n>> +  std::function_ref<int&()> f7(std::cw<&S::v>, std::as_const(sr));\n>>    VERIFY( &f7() == &s.v );\n>> -  std::function_ref<const int&()> f8(std::nontype<&S::m>,\n>> std::as_const(sr));\n>> +  std::function_ref<const int&()> f8(std::cw<&S::m>, std::as_const(sr));\n>>    VERIFY( &f8() == &s.v );\n>>\n>>    // No rvalue reference_wrapper support\n>>    static_assert( !std::is_constructible_v<\n>>      std::function_ref<int&()>,\n>> -    std::nontype_t<&S::v>, std::reference_wrapper<S>>\n>> +    std::constant_wrapper<&S::v>, std::reference_wrapper<S>>\n>>    );\n>>    static_assert( !std::is_constructible_v<\n>>      std::function_ref<int&()>,\n>> -    std::nontype_t<&S::v>, std::reference_wrapper<const S>>\n>> +    std::constant_wrapper<&S::v>, std::reference_wrapper<const S>>\n>>    );\n>>\n>>    // reference to reference_wrapper are bound, so mutation are visible\n>> @@ -232,9 +231,9 @@ test06()\n>>    { return &x; };\n>>\n>>    // identity of reference_wrapper is preserved\n>> -  std::function_ref<const std::reference_wrapper<S>*()>\n>> g1(std::nontype<id>, sr);\n>> +  std::function_ref<const std::reference_wrapper<S>*()> g1(std::cw<id>,\n>> sr);\n>>    VERIFY( g1() == &sr );\n>> -  std::function_ref<const std::reference_wrapper<const S>*()>\n>> g2(std::nontype<id>, csr);\n>> +  std::function_ref<const std::reference_wrapper<const S>*()>\n>> g2(std::cw<id>, csr);\n>>    VERIFY( g2() == &csr );\n>>  }\n>>\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>> index a91f5ba3dab..78aebd38a07 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>> @@ -9,8 +9,7 @@\n>>  # error \"Feature-test macro for function_ref has wrong value in\n>> <functional>\"\n>>  #endif\n>>\n>> -using std::nontype;\n>> -using std::nontype_t;\n>> +using std::constant_wrapper;\n>>  using std::function_ref;\n>>\n>>  using std::is_default_constructible_v;\n>> @@ -60,31 +59,31 @@ static_assert( !\n>> is_constructible_v<function_ref<int(S)>,\n>>                                     decltype(&S::f)> );\n>>\n>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>> -                                         nontype_t<funS>> );\n>> +                                         constant_wrapper<funS>> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>> -                                         nontype_t<&funS>> );\n>> +                                         constant_wrapper<&funS>> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>> -                                         nontype_t<&S::x>> );\n>> +                                         constant_wrapper<&S::x>> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>> -                                         nontype_t<&S::f>> );\n>> +                                         constant_wrapper<&S::f>> );\n>>\n>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>> -                                         nontype_t<funS>, S&> );\n>> +                                         constant_wrapper<funS>, S&> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>> -                                         nontype_t<&funS>, S&> );\n>> +                                         constant_wrapper<&funS>, S&> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>> -                                         nontype_t<&S::x>, S&> );\n>> +                                         constant_wrapper<&S::x>, S&> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>> -                                         nontype_t<&S::f>, S&> );\n>> +                                         constant_wrapper<&S::f>, S&> );\n>>\n>>  static_assert( ! is_constructible_v<function_ref<int()>,\n>> -                                   nontype_t<funS>, S*> );\n>> +                                   constant_wrapper<funS>, S*> );\n>>  static_assert( ! is_constructible_v<function_ref<int()>,\n>> -                                   nontype_t<&funS>, S*> );\n>> +                                   constant_wrapper<&funS>, S*> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>> -                                         nontype_t<&S::x>, S*> );\n>> +                                         constant_wrapper<&S::x>, S*> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>> -                                         nontype_t<&S::f>, S*> );\n>> +                                         constant_wrapper<&S::f>, S*> );\n>>\n>>  struct M\n>>  {\n>> @@ -98,9 +97,9 @@ static_assert( !\n>> is_constructible_v<function_ref<void()>, const M&> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>, M> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>, const\n>> M&> );\n>>  static_assert( ! is_constructible_v<function_ref<void()>,\n>> -                                   nontype_t<M{}>> );\n>> +                                   constant_wrapper<M{}>> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>> -                                   nontype_t<M{}>> );\n>> +                                   constant_wrapper<M{}>> );\n>>  struct Q\n>>  {\n>>    void operator()(int) const;\n>> @@ -115,22 +114,22 @@ static_assert(\n>> is_nothrow_constructible_v<function_ref<void(int) const>, Q&> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<void(int) const>,\n>> const Q&> );\n>>\n>>  static_assert( is_nothrow_constructible_v<function_ref<void(int)>,\n>> -                                         nontype_t<Q{}>> );\n>> +                                         constant_wrapper<Q{}>> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<void(int) const>,\n>> -                                         nontype_t<Q{}>> );\n>> +                                         constant_wrapper<Q{}>> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<void()>,\n>> -                                         nontype_t<Q{}>, int&> );\n>> +                                         constant_wrapper<Q{}>, int&> );\n>>  static_assert( is_nothrow_constructible_v<function_ref<void() const>,\n>> -                                         nontype_t<Q{}>, int&> );\n>> +                                         constant_wrapper<Q{}>, int&> );\n>>  static_assert( ! is_constructible_v<function_ref<void()>,\n>> -                                   nontype_t<Q{}>, int> );\n>> +                                   constant_wrapper<Q{}>, int> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>> -                                   nontype_t<Q{}>, int> );\n>> +                                   constant_wrapper<Q{}>, int> );\n>>\n>>  static_assert( is_nothrow_constructible_v<function_ref<void()>,\n>> -                                         nontype_t<Q{}>, int*> );\n>> +                                         constant_wrapper<Q{}>, int*> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>> -                                   nontype_t<Q{}>, int*> );\n>> +                                   constant_wrapper<Q{}>, int*> );\n>>\n>>  struct L\n>>  {\n>> @@ -143,9 +142,9 @@ static_assert( !\n>> is_constructible_v<function_ref<void()>, const L&> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>, L> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>, const\n>> L&> );\n>>  static_assert( ! is_constructible_v<function_ref<void()>,\n>> -                                   nontype_t<L{}>> );\n>> +                                   constant_wrapper<L{}>> );\n>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>> -                                   nontype_t<L{}>> );\n>> +                                   constant_wrapper<L{}>> );\n>>\n>>  struct R\n>>  {\n>> @@ -159,24 +158,24 @@ static_assert( !\n>> is_constructible_v<function_ref<void(float) const>, R&> );\n>>  static_assert( ! is_constructible_v<function_ref<void(float) const>,\n>> const R&> );\n>>\n>>  static_assert( ! is_constructible_v<function_ref<void(float)>,\n>> -                                                nontype_t<R{}>> );\n>> +                                   constant_wrapper<R{}>> );\n>>  static_assert( ! is_constructible_v<function_ref<void(float) const>,\n>> -                                                nontype_t<R{}>> );\n>> +                                   constant_wrapper<R{}>> );\n>>\n>>  constexpr bool\n>>  test_constexpr()\n>>  {\n>> -  function_ref<void(S)> fp1(nontype<funS>);\n>> -  function_ref<void(S)> fp3(nontype<&funS>);\n>> -  function_ref<void(S)> fp4(nontype<&S::x>);\n>> -  function_ref<void(S)> fp5(nontype<&S::f>);\n>> +  function_ref<void(S)> fp1(std::cw<funS>);\n>> +  function_ref<void(S)> fp3(std::cw<&funS>);\n>> +  function_ref<void(S)> fp4(std::cw<&S::x>);\n>> +  function_ref<void(S)> fp5(std::cw<&S::f>);\n>>\n>>    S s;\n>> -  function_ref<void()> fp6(nontype<&funS>, s);\n>> -  function_ref<void()> fp7(nontype<&S::x>, s);\n>> -  function_ref<void()> fp8(nontype<&S::x>, &s);\n>> -  function_ref<void()> fp9(nontype<&S::f>, s);\n>> -  function_ref<void()> fp10(nontype<&S::f>, &s);\n>> +  function_ref<void()> fp6(std::cw<&funS>, s);\n>> +  function_ref<void()> fp7(std::cw<&S::x>, s);\n>> +  function_ref<void()> fp8(std::cw<&S::x>, &s);\n>> +  function_ref<void()> fp9(std::cw<&S::f>, s);\n>> +  function_ref<void()> fp10(std::cw<&S::f>, &s);\n>>\n>>    M m;\n>>    function_ref<void()> fm1(m);\n>> @@ -190,13 +189,13 @@ test_constexpr()\n>>\n>>    function_ref<void(int)> fcq1(cq);\n>>    function_ref<void(int) const> f(cq);\n>> -  function_ref<void(int)> fcq3(nontype<cq>);\n>> -  function_ref<void(int) const> fcq4(nontype<cq>);\n>> +  function_ref<void(int)> fcq3(std::cw<cq>);\n>> +  function_ref<void(int) const> fcq4(std::cw<cq>);\n>>\n>>    int i = 0;\n>> -  function_ref<void()> fcq5(nontype<cq>, i);\n>> -  function_ref<void() const> fcq6(nontype<cq>, i);\n>> -  function_ref<void()> fcq7(nontype<cq>, &i);\n>> +  function_ref<void()> fcq5(std::cw<cq>, i);\n>> +  function_ref<void() const> fcq6(std::cw<cq>, i);\n>> +  function_ref<void()> fcq7(std::cw<cq>, &i);\n>>\n>>    L l;\n>>    function_ref<void()> fl1(l);\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>> index 050090df370..a426ac64cd5 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>> @@ -2,7 +2,6 @@\n>>\n>>  #include <functional>\n>>\n>> -using std::nontype;\n>>  using std::function_ref;\n>>\n>>  struct S\n>> @@ -16,15 +15,15 @@ constexpr int(*fp)(S) = nullptr;\n>>  constexpr int S::*mdp = nullptr;\n>>  constexpr int (S::*mfp)() = nullptr;\n>>\n>> -function_ref<int(S)> fd1(nontype<fp>);  // { dg-error \"from here\" }\n>> -function_ref<int(S)> fd2(nontype<mdp>); // { dg-error \"from here\" }\n>> -function_ref<int(S)> fd3(nontype<mfp>); // { dg-error \"from here\" }\n>> +function_ref<int(S)> fd1(std::cw<fp>);  // { dg-error \"from here\" }\n>> +function_ref<int(S)> fd2(std::cw<mdp>); // { dg-error \"from here\" }\n>> +function_ref<int(S)> fd3(std::cw<mfp>); // { dg-error \"from here\" }\n>>\n>> -function_ref<int()> br4(nontype<fp>, s);  // { dg-error \"from here\" }\n>> -function_ref<int()> br5(nontype<mdp>, s); // { dg-error \"from here\" }\n>> -function_ref<int()> br6(nontype<mfp>, s); // { dg-error \"from here\" }\n>> +function_ref<int()> br4(std::cw<fp>, s);  // { dg-error \"from here\" }\n>> +function_ref<int()> br5(std::cw<mdp>, s); // { dg-error \"from here\" }\n>> +function_ref<int()> br6(std::cw<mfp>, s); // { dg-error \"from here\" }\n>>\n>> -function_ref<int()> bp7(nontype<mdp>, &s); // { dg-error \"from here\" }\n>> -function_ref<int()> bp8(nontype<mfp>, &s); // { dg-error \"from here\" }\n>> +function_ref<int()> bp7(std::cw<mdp>, &s); // { dg-error \"from here\" }\n>> +function_ref<int()> bp8(std::cw<mfp>, &s); // { dg-error \"from here\" }\n>>\n>>  // { dg-prune-output \"static assertion failed\" }\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>> new file mode 100644\n>> index 00000000000..a295bc2ce31\n>> --- /dev/null\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>> @@ -0,0 +1,35 @@\n>> +// { dg-do compile { target c++26 } }\n>> +\n>> +#include <functional>\n>> +\n>> +using std::function_ref;\n>> +using std::constant_wrapper;\n>> +\n>> +struct S\n>> +{\n>> +  int operator()() const { return 1; }\n>> +\n>> +  // Non-constant, so cw<S{}>(cw<1>) call never unwrapps\n>> +  int operator()(int) const { return 1; }\n>> +  template<auto __cw>\n>> +    int operator()(constant_wrapper<__cw, int>) const { return 1; }\n>> +\n>> +  // Constant, cw<S{}>(cw<1>, cw<2>) calls int overload\n>> +  // while S{}(cw<1>, cw<1>) calls constant_wrapper overload\n>> +  constexpr int operator()(int, int) const { return 1; }\n>> +  template<auto __cw1, auto __cw2>\n>> +    constexpr int operator()(constant_wrapper<__cw1, int>,\n>> +                            constant_wrapper<__cw2, int>)\n>> +    { return 1; }\n>> +};\n>> +\n>> +function_ref<int()> f0a(S{});\n>> +\n>> +function_ref<int(int)> f1a(S{});\n>> +function_ref<int(constant_wrapper<2>)> f1b(std::cw<S{}>);\n>> +\n>> +function_ref<int(int, int)> f2a(std::cw<S{}>); // OK, runtime\n>> +function_ref<int(constant_wrapper<1>, int)> f2b(std::cw<S{}>); // OK,\n>> still runtime\n>> +function_ref<int(constant_wrapper<2>, constant_wrapper<3>)>\n>> f2c(std::cw<S{}>); // { dg-error \"from here\" }\n>> +\n>> +// { dg-prune-output \"static assertion failed\" }\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>> index 3cc782524f6..4ef5d067555 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>> @@ -46,7 +46,7 @@ struct NonStatic {\n>>    { return x + y + v; }\n>>  };\n>>\n>> -constexpr auto vNonType = create(std::nontype<NonStatic{3}>);\n>> +constexpr auto vNonType = create(std::cw<NonStatic{3}>);\n>>\n>>  struct StaticWins {\n>>    static int\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>> index b034c7af072..63c3f6ea7e3 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>> @@ -4,15 +4,13 @@\n>>  #include <type_traits>\n>>\n>>  using std::is_same_v;\n>> -using std::nontype;\n>> -using std::nontype_t;\n>>  using std::function_ref;\n>>\n>>  int i = 0;\n>>\n>>  template<auto f, class... Args>\n>>    concept deductible = requires (Args&... args)\n>> -  { std::function_ref(std::nontype<f>, args...); };\n>> +  { std::function_ref(std::cw<f>, args...); };\n>>\n>>  static_assert( !deductible<1> );\n>>  static_assert( !deductible<1, int> );\n>> @@ -24,9 +22,9 @@ static_assert( is_same_v<decltype(function_ref(f0)),\n>>                          function_ref<void()>> );\n>>  static_assert( is_same_v<decltype(function_ref(f0n)),\n>>                          function_ref<void() noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f0>)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f0>)),\n>>                          function_ref<void()>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f0n>)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f0n>)),\n>>                          function_ref<void() noexcept>> );\n>>  static_assert( !deductible<f0, char*> );\n>>  static_assert( !deductible<f0n, char*> );\n>> @@ -38,13 +36,13 @@ static_assert( is_same_v<decltype(function_ref(f1)),\n>>                          function_ref<void(int)>> );\n>>  static_assert( is_same_v<decltype(function_ref(f1n)),\n>>                          function_ref<void(int) noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f1>)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1>)),\n>>                          function_ref<void(int)>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f1n>)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1n>)),\n>>                          function_ref<void(int) noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f1>, i)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1>, i)),\n>>                          function_ref<void()>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f1n>, i)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1n>, i)),\n>>                          function_ref<void() noexcept>> );\n>>  static_assert( !deductible<f1, char*> );\n>>  static_assert( !deductible<f1n, char*> );\n>> @@ -56,13 +54,13 @@ static_assert( is_same_v<decltype(function_ref(f2)),\n>>                          function_ref<void(int*, int)>> );\n>>  static_assert( is_same_v<decltype(function_ref(f2n)),\n>>                          function_ref<void(int*, int) noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f2>)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2>)),\n>>                          function_ref<void(int*, int)>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f2n>)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2n>)),\n>>                          function_ref<void(int*, int) noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f2>, &i)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2>, &i)),\n>>                          function_ref<void(int)>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<f2n>, &i)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2n>, &i)),\n>>                          function_ref<void(int) noexcept>> );\n>>  static_assert( !deductible<f2, char*> );\n>>  static_assert( !deductible<f2n, char*> );\n>> @@ -88,40 +86,40 @@ struct S\n>>  S s{};\n>>  const S cs{};\n>>\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, s)),\n>>                          function_ref<int&() noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, cs)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, cs)),\n>>                          function_ref<const int&() noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, &s)),\n>>                          function_ref<int&() noexcept>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &cs)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, &cs)),\n>>                          function_ref<const int&() noexcept>> );\n>>  static_assert( !deductible<&S::mem, int> );\n>>\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::f>, s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::f>, s)),\n>>                          function_ref<int()>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fn>, &s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fn>, &s)),\n>>                          function_ref<int() noexcept>> );\n>>  static_assert( !deductible<&S::f, char*> );\n>>  static_assert( !deductible<&S::fn, char*> );\n>>  static_assert( !deductible<&S::f, const S> );\n>>  static_assert( !deductible<&S::fn, const S> );\n>>\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fc>, &s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fc>, &s)),\n>>                          function_ref<int(int)>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcn>, s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcn>, s)),\n>>                          function_ref<int(int) noexcept>> );\n>>  static_assert( !deductible<&S::fc, char*> );\n>>  static_assert( !deductible<&S::fcn, char*> );\n>>\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fl>, &s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fl>, &s)),\n>>                          function_ref<int(int)>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fln>, s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fln>, s)),\n>>                          function_ref<int(int) noexcept>> );\n>>\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcl>, s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcl>, s)),\n>>                          function_ref<int(float)>> );\n>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcln>, &s)),\n>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcln>, &s)),\n>>                          function_ref<int(float) noexcept>> );\n>>\n>>  static_assert( !deductible<&S::fr, char*> );\n>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>> b/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>> index 32c6931e9a8..d55f4facbda 100644\n>> --- a/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>> @@ -3,7 +3,6 @@\n>>  #include <functional>\n>>  #include <testsuite_hooks.h>\n>>\n>> -using std::nontype;\n>>  using std::function_ref;\n>>\n>>  void\n>> @@ -55,8 +54,8 @@ test02()\n>>    };\n>>    S s{10};\n>>\n>> -  function_ref<int()> r1(nontype<&S::x>, s);\n>> -  function_ref<long()> r2(nontype<&S::x>, &s);\n>> +  function_ref<int()> r1(std::cw<&S::x>, s);\n>> +  function_ref<long()> r2(std::cw<&S::x>, &s);\n>>\n>>    VERIFY( r1() == 10 );\n>>    VERIFY( r2() == 10 );\n>> @@ -66,8 +65,8 @@ test02()\n>>    VERIFY( r1() == 20 );\n>>    VERIFY( r2() == 20 );\n>>\n>> -  r1 = function_ref<int()>(nontype<&S::f>, &s);\n>> -  r2 = function_ref<long()>(nontype<&S::f>, s);\n>> +  r1 = function_ref<int()>(std::cw<&S::f>, &s);\n>> +  r2 = function_ref<long()>(std::cw<&S::f>, s);\n>>\n>>    VERIFY( r1() == 20 );\n>>    VERIFY( r2() == 20 );\n>> --\n>> 2.53.0\n>>\n>>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=egxZogg2;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=egxZogg2","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frNQ94Rn4z1yD3\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 22:57:36 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 37EE14BA2E36\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  8 Apr 2026 12:57:34 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id 2CC154BA2E17\n for <gcc-patches@gcc.gnu.org>; Wed,  8 Apr 2026 12:56:27 +0000 (GMT)","from mail-yw1-f197.google.com (mail-yw1-f197.google.com\n [209.85.128.197]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-160-Lz2QvRUkOruOOB9rEwdjcw-1; Wed, 08 Apr 2026 08:56:22 -0400","by mail-yw1-f197.google.com with SMTP id\n 00721157ae682-790afc07667so108729997b3.0\n for <gcc-patches@gcc.gnu.org>; Wed, 08 Apr 2026 05:56:22 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 37EE14BA2E36","OpenDKIM Filter v2.11.0 sourceware.org 2CC154BA2E17"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 2CC154BA2E17","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 2CC154BA2E17","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775652987; cv=none;\n b=oa58YO/47Wk7nTyJxDluExfLcO1/V/QSMWXFliuYRGmk/K5OwBvou+77ATJEzq1wQTN2f5Fo1UsdlIDhpexLxCRgVj62mDsMN/204d6kI1EyF6c91Qq86+Dx+Epl+SYIL7todcJG3Pcu5pY4g67DGcI41k3z6O9dHNKOAJiWj3w=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775652987; c=relaxed/simple;\n bh=L9aKiy3K0MWoWy7oi8exZeFkNobaiGme1cPv1loqnrY=;\n h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;\n b=gOtRWwijCWeFSzNdpygr+yssZxOwMLdgI3WkMPB3+oftVgECJTqbhZa2E3rcUGVzB4OzzRayimcTcMj/EUbHpoPfRYycA7aRdjD2X4hVL4ipRm1O23PkYJZ4csElMqEMFMlAikh/Dpt4QjkmO85lo1Q+Ofk0mehI+/9elZydbQk=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775652986;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=CfYeBrUArgGanrY8OEYvjqk0OvbOCuxbPxxaeo/e+jM=;\n b=egxZogg2Ehod7/GpzeTQ/4YaXhutqWUnvH6zn0aKCys33al30sf85NJqPrOYqGeW4Is99O\n DEha/T7VXTyTxmB/wpl7UvMtl3raL2P8BufqV4AFG9HkxmoUV5W5T9z95QJNHbopeydNAl\n N2o4v6ewbwWDu/4ARowZhVC1tRAvgiw=","X-MC-Unique":"Lz2QvRUkOruOOB9rEwdjcw-1","X-Mimecast-MFC-AGG-ID":"Lz2QvRUkOruOOB9rEwdjcw_1775652982","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775652982; x=1776257782;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=CfYeBrUArgGanrY8OEYvjqk0OvbOCuxbPxxaeo/e+jM=;\n b=G+STr9eofBhdc0wyXXJEB8QzjnEzu4/CFh2HQT+DRndJRDYKvdgUtmd5EjEEkF6JHA\n zRdbzfkJspl7kh/r1Ga9GLXbcFl/lKnKMKGYOuvMRbQMgGceqSyWhbWf9Cmh53wwYDVa\n fvzeYbpFwyCnaMWAPCMjrRdQarMYaqM+5BOm2HBUy2fZOCBIykW69kcjukpQKFAQTszq\n QIzMcbvC6MCaiGusL61BKc2asxJx1J8HkBakIlSDo1JBcJvyQiE4cEAvBp90G9o/tipM\n uayDqXdU6d/0+6+QHqmRCFBU8jY4ih4uWVShVwxI2nHJ1NrAf2vnCgvDEIxJtm9EkXlv\n k79A==","X-Forwarded-Encrypted":"i=1;\n AJvYcCUKWU7Tw32++MpIgzDRIuKbb5ThSlYfw89yK/d1yTXNZytvkm7ZU02u4EtWdBEaiPr7UzAFLV3xK/3zvQ==@gcc.gnu.org","X-Gm-Message-State":"AOJu0YxMXzEqkeM88iyL2XFPMQY8GzfOIDQ6mWXUXuHFnQ+bkm7ouh2n\n vXuTBdBePaJvWyDwdgZV8I1br3JyH33k1chqZx0/GUodoSN/X9kSiCIkAgFZj6CBetJFapvUgRJ\n C84vbLkQ3hkwjwVYN5QfZEIE+Ua2G0uN+khfa9J7U86cuwXLVUlxM5jbdwSpztL+m27z69OqosT\n p+ihkJ6X7xFbwJR10uML1fmxEkVVNThyRHFw==","X-Gm-Gg":"AeBDietpCVIE1C4rtRTvAA1GLUJ6yd0TOLmAgm0Z1HIymy1hRA3I8dFX/itlrvzp/j2\n fHHRBWYKcqguACpGRjYwuyWXALkS51pXdvH1A8kPmVY4yX9SCcj/cydVvC9aUag0hEsBNm2p3Fz\n FS+OI4Gs31EWsjwzod9KY+NVekAnInuxb7Pdi5HQkUk0yfkOLTlda61AvpmmYuIZ5vDCxn88VTj\n DP2mtFFNp82+9ZwKlJbXcKvqjBC5t/UWmlxko4i1FQNOr5KsG7OAFPi+6j/VuG1V86p","X-Received":["by 2002:a05:690c:c50f:b0:79e:fcc9:aea6 with SMTP id\n 00721157ae682-7a4d90a1959mr191040737b3.44.1775652981836;\n Wed, 08 Apr 2026 05:56:21 -0700 (PDT)","by 2002:a05:690c:c50f:b0:79e:fcc9:aea6 with SMTP id\n 00721157ae682-7a4d90a1959mr191040407b3.44.1775652981167; Wed, 08 Apr 2026\n 05:56:21 -0700 (PDT)"],"MIME-Version":"1.0","References":"<20260408094553.155396-1-tkaminsk@redhat.com>\n <CAH6eHdSx5kSs6JuBBv6MZaXk6o1kMk-uwN=kTxWTOODKcjvKww@mail.gmail.com>","In-Reply-To":"\n <CAH6eHdSx5kSs6JuBBv6MZaXk6o1kMk-uwN=kTxWTOODKcjvKww@mail.gmail.com>","From":"Tomasz Kaminski <tkaminsk@redhat.com>","Date":"Wed, 8 Apr 2026 14:56:09 +0200","X-Gm-Features":"AQROBzCF9ncrT_TZKcRQTPYeZWxBMgxopkjfdnGMZ_bSWbmtx7jHbByTk4LFdbo","Message-ID":"\n <CAKvuMXC9h_u8EaKGL7Pc_3g0hfuGaPjp6j4-iXJ5RQ1GahMOTg@mail.gmail.com>","Subject":"Re: [PATCH] libstdc++: Remove non_type and replace it with\n constant_wrapper in function_ref","To":"Jonathan Wakely <jwakely.gcc@gmail.com>","Cc":"\"libstdc++\" <libstdc++@gcc.gnu.org>,\n gcc-patches <gcc-patches@gcc.gnu.org>,\n Matthias Kretz <m.kretz@gsi.de>","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"GD_bHOcQyOJkLwDbIXvIWp2nlAA5_OKAudEefOOXPzA_1775652982","X-Mimecast-Originator":"redhat.com","Content-Type":"multipart/alternative; boundary=\"0000000000003071e5064ef26d26\"","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}},{"id":3674831,"web_url":"http://patchwork.ozlabs.org/comment/3674831/","msgid":"<CAH6eHdTuGF+PpFkJ5dZNnSc5Qh92sP-d9WQndPDQ-MwjqjSz2Q@mail.gmail.com>","list_archive_url":null,"date":"2026-04-08T15:24:06","subject":"Re: [PATCH] libstdc++: Remove non_type and replace it with\n constant_wrapper in function_ref","submitter":{"id":4329,"url":"http://patchwork.ozlabs.org/api/people/4329/","name":"Jonathan Wakely","email":"jwakely.gcc@gmail.com"},"content":"On Wed, 8 Apr 2026, 13:56 Tomasz Kaminski, <tkaminsk@redhat.com> wrote:\n\n> I have forgotten to bump function_ref FTM, but that turned out to be good\n> thing, because we have another paper\n> bumping it at the same time:\n> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3961r0.html\n> Should we use 202304L for the second paper?\n>\n\nYes that makes sense. Barry and I agree on behalf of sg10.\n\n\nThey seem separable, but we will inflict some order.\n>\n>\n> On Wed, Apr 8, 2026 at 12:04 PM Jonathan Wakely <jwakely.gcc@gmail.com>\n> wrote:\n>\n>>\n>>\n>> On Wed, 8 Apr 2026, 10:46 Tomasz Kamiński, <tkaminsk@redhat.com> wrote:\n>>\n>>> From: Matthias Kretz <m.kretz@gsi.de>\n>>>\n>>> This implements P3948R1: constant_wrapper is the only tool needed\n>>> for passing constant expressions via function arguments.\n>>>\n>>> This changes function_ref from nontype_t to constant_wrapper and\n>>> implements the ambiguity check (static_asert in function_ref\n>>> from constant_wrapper constructor).\n>>>\n>>> In addition to P3948R1 this also includes the (forgotten) deduction\n>>> guide changes suggested in the draft PR [1].\n>>>\n>>> [1] https://github.com/cplusplus/draft/pull/8878\n>>>\n>>> libstdc++-v3/ChangeLog:\n>>>\n>>>         * include/bits/funcref_impl.h (function_ref::function_ref):\n>>>         Change nontype_t parameter to constant_wrapper, and adjust\n>>>         accordingly. Add static_assert detecting ambigous semantics.\n>>>         (function_refoperator=): Detect constant_wrapper rather than\n>>>         nontype_t.\n>>>\n>>\n>> Missing :: here\n>>\n>>         * include/bits/funcwrap.h (function_ref): Change\n>>>         * include/bits/utility.h (std::nontype_t, std::nontype)\n>>>         (std::__is_nontype_v): Remove.\n>>>         (_is_constant_wrapper_v): Define.\n>>>\n>>\n>> And _ here\n>>\n>> The patch itself is fine, so OK with those two tweaks to the changelog.\n>>\n>>\n>>         * src/c++23/std.cc.in (std::nontype_t, std::nontype):\n>>>         Remove exports.\n>>>         * testsuite/20_util/function_ref/cw_cons_neg.cc: New tests\n>>>         for ambiguity check.\n>>>         * testsuite/20_util/function_ref/assign.cc: Replace nontype_t\n>>>         with constant_wrapper and nontype with std::cw.\n>>>         * testsuite/20_util/function_ref/call.cc: Likewise.\n>>>         * testsuite/20_util/function_ref/cons.cc: Likewise.\n>>>         * testsuite/20_util/function_ref/cons_neg.cc: Likewise.\n>>>         * testsuite/20_util/function_ref/deduction.cc: Likewise.\n>>>         * testsuite/20_util/function_ref/mutation.cc: Likewise.\n>>>\n>>> Co-authored-by: Tomasz Kamiński <tkaminsk@redhat.com>\n>>> Signed-off-by: Matthias Kretz <m.kretz@gsi.de>\n>>> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>\n>>> ---\n>>> This is based on Matthias patch from formge:\n>>>\n>>> https://forge.sourceware.org/gcc/gcc-TEST/pulls/147/commits/cac7355bcbd7ea8b5e26f064922e8f4412a4da97\n>>>\n>>> I have applied small adjustment to names and parameter specification,\n>>> to be more consistient with the standard. Outside of that I have reworked\n>>> static_assert to reflect more closely what is in the standard, and added\n>>> negative test (cw_const_neg.cc).\n>>>\n>>> Testing on x86_64-linux. All *function_ref* test already passed in\n>>> all standard modes and with modules. OK for trunk when all test passes?\n>>>\n>>>\n>>>  libstdc++-v3/include/bits/funcref_impl.h      | 36 ++++----\n>>>  libstdc++-v3/include/bits/funcwrap.h          | 13 +--\n>>>  libstdc++-v3/include/bits/utility.h           | 23 ++---\n>>>  libstdc++-v3/src/c++23/std.cc.in              |  4 -\n>>>  .../testsuite/20_util/function_ref/assign.cc  | 27 +++---\n>>>  .../testsuite/20_util/function_ref/call.cc    | 51 ++++++------\n>>>  .../testsuite/20_util/function_ref/cons.cc    | 83 +++++++++----------\n>>>  .../20_util/function_ref/cons_neg.cc          | 17 ++--\n>>>  .../20_util/function_ref/cw_cons_neg.cc       | 35 ++++++++\n>>>  .../20_util/function_ref/dangling.cc          |  2 +-\n>>>  .../20_util/function_ref/deduction.cc         | 48 +++++------\n>>>  .../20_util/function_ref/mutation.cc          |  9 +-\n>>>  12 files changed, 185 insertions(+), 163 deletions(-)\n>>>  create mode 100644\n>>> libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>>>\n>>> diff --git a/libstdc++-v3/include/bits/funcref_impl.h\n>>> b/libstdc++-v3/include/bits/funcref_impl.h\n>>> index 3d55c8406b0..9fcab570803 100644\n>>> --- a/libstdc++-v3/include/bits/funcref_impl.h\n>>> +++ b/libstdc++-v3/include/bits/funcref_impl.h\n>>> @@ -129,12 +129,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>        // _GLIBCXX_RESOLVE_LIB_DEFECTS\n>>>        // 4256. Incorrect constrains for function_ref constructors from\n>>> nontype\n>>>        /// Target object is __fn. There is no bound object.\n>>> -      template<auto __fn>\n>>> -       requires __is_invocable_using<const decltype(__fn)&>\n>>> +      template<auto __cwfn, typename _Fn>\n>>> +       requires __is_invocable_using<const _Fn&>\n>>>         constexpr\n>>> -       function_ref(nontype_t<__fn>) noexcept\n>>> +       function_ref(constant_wrapper<__cwfn, _Fn>) noexcept\n>>>         {\n>>> -         using _Fn = remove_cv_t<decltype(__fn)>;\n>>> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn,\n>>> _Fn>::value;\n>>> +         if constexpr (sizeof...(_ArgTypes) > 0)\n>>> +           if constexpr ((... &&\n>>> _ConstExprParam<remove_cvref_t<_ArgTypes>>))\n>>> +             static_assert(!requires {\n>>> +               typename constant_wrapper<\n>>> +                 std::__invoke(__fn,\n>>> remove_cvref_t<_ArgTypes>::value...)>;\n>>> +             }, \"cw<fn>(args...) should be equivalent to fn(args...)\");\n>>> +\n>>>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>>>             static_assert(__fn != nullptr);\n>>>\n>>> @@ -144,13 +151,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>\n>>>        /// Target object is equivalent to\n>>> std::bind_front<_fn>(std::ref(__ref)).\n>>>        /// Bound object is object referenced by second parameter.\n>>> -      template<auto __fn, typename _Up, typename _Td =\n>>> remove_reference_t<_Up>>\n>>> +      template<auto __cwfn, typename _Fn, typename _Up,\n>>> +              typename _Td = remove_reference_t<_Up>>\n>>>         requires (!is_rvalue_reference_v<_Up&&>)\n>>> -         && __is_invocable_using<const decltype(__fn)&, _Td\n>>> _GLIBCXX_MOF_CV&>\n>>> +                && __is_invocable_using<const _Fn&, _Td\n>>> _GLIBCXX_MOF_CV&>\n>>>         constexpr\n>>> -       function_ref(nontype_t<__fn>, _Up&& __ref) noexcept\n>>> +       function_ref(constant_wrapper<__cwfn, _Fn>, _Up&& __ref) noexcept\n>>>         {\n>>> -         using _Fn = remove_cv_t<decltype(__fn)>;\n>>> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn,\n>>> _Fn>::value;\n>>>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>>>             static_assert(__fn != nullptr);\n>>>\n>>> @@ -166,12 +174,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>\n>>>        /// Target object is equivalent to std::bind_front<_fn>(__ptr).\n>>>        /// Bound object is object pointed by second parameter (if any).\n>>> -      template<auto __fn, typename _Td>\n>>> -       requires __is_invocable_using<const decltype(__fn)&, _Td\n>>> _GLIBCXX_MOF_CV*>\n>>> +      template< auto __cwfn, typename _Fn, typename _Td>\n>>> +       requires __is_invocable_using<const _Fn&, _Td _GLIBCXX_MOF_CV*>\n>>>         constexpr\n>>> -       function_ref(nontype_t<__fn>, _Td _GLIBCXX_MOF_CV* __ptr)\n>>> noexcept\n>>> +       function_ref(constant_wrapper<__cwfn, _Fn>, _Td _GLIBCXX_MOF_CV*\n>>> __ptr) noexcept\n>>>         {\n>>> -         using _Fn = remove_cv_t<decltype(__fn)>;\n>>> +         constexpr const _Fn& __fn = constant_wrapper<__cwfn,\n>>> _Fn>::value;\n>>>           if constexpr (is_pointer_v<_Fn> || is_member_pointer_v<_Fn>)\n>>>             static_assert(__fn != nullptr);\n>>>           if constexpr (is_member_pointer_v<_Fn>)\n>>> @@ -182,8 +190,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>         }\n>>>\n>>>        template<typename _Tp>\n>>> -       requires (!is_same_v<_Tp, function_ref>)\n>>> -              && (!is_pointer_v<_Tp>) && (!__is_nontype_v<_Tp>)\n>>> +       requires (!is_same_v<_Tp, function_ref>) && (!is_pointer_v<_Tp>)\n>>> +                && (!__is_constant_wrapper_v<_Tp>)\n>>>         function_ref&\n>>>         operator=(_Tp) = delete;\n>>>\n>>> diff --git a/libstdc++-v3/include/bits/funcwrap.h\n>>> b/libstdc++-v3/include/bits/funcwrap.h\n>>> index 6441893d213..b835e075295 100644\n>>> --- a/libstdc++-v3/include/bits/funcwrap.h\n>>> +++ b/libstdc++-v3/include/bits/funcwrap.h\n>>> @@ -573,15 +573,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>      requires is_function_v<_Fn>\n>>>      function_ref(_Fn*) -> function_ref<_Fn>;\n>>>\n>>> -  template<auto __f, class _Fn = remove_pointer_t<decltype(__f)>>\n>>> -    requires is_function_v<_Fn>\n>>> -    function_ref(nontype_t<__f>) -> function_ref<_Fn>;\n>>> +  template<auto __cwfn, typename _Fn>\n>>> +    requires is_function_v<remove_pointer_t<_Fn>>\n>>> +    function_ref(constant_wrapper<__cwfn, _Fn>)\n>>> +      -> function_ref<remove_pointer_t<_Fn>>;\n>>>\n>>> -  template<auto __f, typename _Tp,\n>>> +  template<auto __cwfn, typename _Fn, typename _Tp,\n>>>            typename _SignaturePtr =\n>>> -            decltype(__polyfunc::__deduce_funcref<decltype(__f),\n>>> _Tp&>())>\n>>> +            decltype(__polyfunc::__deduce_funcref<_Fn, _Tp&>())>\n>>>      requires (!is_void_v<_SignaturePtr>)\n>>> -    function_ref(nontype_t<__f>, _Tp&&)\n>>> +    function_ref(constant_wrapper<__cwfn, _Fn>, _Tp&&)\n>>>        -> function_ref<remove_pointer_t<_SignaturePtr>>;\n>>>\n>>>  #endif // __glibcxx_function_ref\n>>> diff --git a/libstdc++-v3/include/bits/utility.h\n>>> b/libstdc++-v3/include/bits/utility.h\n>>> index 970e63e8170..93e9e9f9dba 100644\n>>> --- a/libstdc++-v3/include/bits/utility.h\n>>> +++ b/libstdc++-v3/include/bits/utility.h\n>>> @@ -458,6 +458,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>      { return value; }\n>>>    };\n>>>\n>>> +  template<typename>\n>>> +    constexpr bool __is_constant_wrapper_v = false;\n>>> +\n>>> +  template<auto __cw, typename _Fn>\n>>> +    constexpr bool __is_constant_wrapper_v<constant_wrapper<__cw, _Fn>>\n>>> = true;\n>>> +\n>>>    template<_CwFixedValue _Tp>\n>>>      constexpr auto cw = constant_wrapper<_Tp>{};\n>>>  #endif\n>>> @@ -637,23 +643,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>>>    inline constexpr sorted_equivalent_t sorted_equivalent{};\n>>>  #endif\n>>>\n>>> -#if __glibcxx_function_ref // >= C++26\n>>> -  template<auto>\n>>> -    struct nontype_t\n>>> -    {\n>>> -      explicit nontype_t() = default;\n>>> -    };\n>>> -\n>>> -  template<auto __val>\n>>> -    constexpr nontype_t<__val> nontype{};\n>>> -\n>>> -  template<typename>\n>>> -    inline constexpr bool __is_nontype_v = false;\n>>> -\n>>> -  template<auto __val>\n>>> -    inline constexpr bool __is_nontype_v<nontype_t<__val>> = true;\n>>> -#endif\n>>> -\n>>>  _GLIBCXX_END_NAMESPACE_VERSION\n>>>  } // namespace\n>>>\n>>> diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/\n>>> std.cc.in\n>>> index db66677d55b..3ac19871692 100644\n>>> --- a/libstdc++-v3/src/c++23/std.cc.in\n>>> +++ b/libstdc++-v3/src/c++23/std.cc.in\n>>> @@ -3651,10 +3651,6 @@ export namespace std\n>>>    using std::make_integer_sequence;\n>>>    using std::move;\n>>>    using std::move_if_noexcept;\n>>> -#if __cpp_lib_function_ref\n>>> -  using std::nontype_t;\n>>> -  using std::nontype;\n>>> -#endif\n>>>    using std::pair;\n>>>    using std::swap;\n>>>    using std::operator==;\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>>> index 9b02dc49c2a..521a35fc11e 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/assign.cc\n>>> @@ -8,8 +8,7 @@\n>>>  # error \"Feature-test macro for function_ref has wrong value in\n>>> <functional>\"\n>>>  #endif\n>>>\n>>> -using std::nontype;\n>>> -using std::nontype_t;\n>>> +using std::constant_wrapper;\n>>>  using std::function_ref;\n>>>\n>>>  using std::is_nothrow_move_assignable_v;\n>>> @@ -55,13 +54,13 @@ static_assert( !\n>>> is_assignable_v<function_ref<int(S)>, decltype(&S::x)> );\n>>>  static_assert( ! is_assignable_v<function_ref<int(S)>, decltype(&S::f)>\n>>> );\n>>>\n>>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>>> -                                      nontype_t<funS>> );\n>>> +                                      constant_wrapper<funS>> );\n>>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>>> -                                      nontype_t<&funS>> );\n>>> +                                      constant_wrapper<&funS>> );\n>>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>>> -                                      nontype_t<&S::x>> );\n>>> +                                      constant_wrapper<&S::x>> );\n>>>  static_assert( is_nothrow_assignable_v<function_ref<int(S)>,\n>>> -                                      nontype_t<&S::f>> );\n>>> +                                      constant_wrapper<&S::f>> );\n>>>  struct Q\n>>>  {\n>>>    void operator()() const;\n>>> @@ -75,22 +74,22 @@ static_assert( ! is_assignable_v<function_ref<void()\n>>> const>, Q&> );\n>>>  static_assert( ! is_assignable_v<function_ref<void() const>, const Q&>\n>>> );\n>>>\n>>>  static_assert( is_nothrow_assignable_v<function_ref<void()>,\n>>> -                                      nontype_t<Q{}>> );\n>>> +                                      constant_wrapper<Q{}>> );\n>>>  static_assert( is_nothrow_assignable_v<function_ref<void() const>,\n>>> -                                      nontype_t<Q{}>> );\n>>> +                                      constant_wrapper<Q{}>> );\n>>>\n>>>  constexpr bool\n>>>  test_constexpr()\n>>>  {\n>>> -  function_ref<void(S)> fp(nontype<funS>);\n>>> -  fp = nontype<funS>;\n>>> -  fp = nontype<&funS>;\n>>> -  fp = nontype<&S::x>;\n>>> -  fp = nontype<&S::f>;\n>>> +  function_ref<void(S)> fp(std::cw<funS>);\n>>> +  fp = std::cw<funS>;\n>>> +  fp = std::cw<&funS>;\n>>> +  fp = std::cw<&S::x>;\n>>> +  fp = std::cw<&S::f>;\n>>>\n>>>    constexpr Q cq;\n>>>    function_ref<void() const> fq(cq);\n>>> -  fq = nontype<cq>;\n>>> +  fq = std::cw<cq>;\n>>>    return true;\n>>>  }\n>>>  static_assert( test_constexpr() );\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>>> index 49c6030b221..386c8de790a 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/call.cc\n>>> @@ -4,7 +4,6 @@\n>>>  #include <utility>\n>>>  #include <testsuite_hooks.h>\n>>>\n>>> -using std::nontype;\n>>>  using std::function_ref;\n>>>\n>>>  using std::is_same_v;\n>>> @@ -43,7 +42,7 @@ test01()\n>>>    VERIFY( f0() == 0 );\n>>>    VERIFY( std::move(f0)() == 0 );\n>>>\n>>> -  function_ref<int()> f1{nontype<F{}>};\n>>> +  function_ref<int()> f1{std::cw<F{}>};\n>>>    VERIFY( f1() == 1 );\n>>>    VERIFY( std::move(f1)() == 1 );\n>>>\n>>> @@ -53,7 +52,7 @@ test01()\n>>>    VERIFY( std::move(f2)() == 1 );\n>>>    VERIFY( std::move(std::as_const(f2))() == 1 );\n>>>\n>>> -  function_ref<int() const> f3{nontype<F{}>};\n>>> +  function_ref<int() const> f3{std::cw<F{}>};\n>>>    VERIFY( f3() == 1 );\n>>>    VERIFY( std::as_const(f3)() == 1 );\n>>>    VERIFY( std::move(f3)() == 1 );\n>>> @@ -71,11 +70,11 @@ test02()\n>>>    };\n>>>    F::Arg arg;\n>>>\n>>> -  function_ref<int()> f0{std::nontype<F{}>, arg};\n>>> +  function_ref<int()> f0{std::cw<F{}>, arg};\n>>>    VERIFY( f0() == 0 );\n>>>    VERIFY( std::move(f0)() == 0 );\n>>>\n>>> -  function_ref<int() const> f1{std::nontype<F{}>, arg};\n>>> +  function_ref<int() const> f1{std::cw<F{}>, arg};\n>>>    VERIFY( f1() == 1 );\n>>>    VERIFY( std::as_const(f1)() == 1 );\n>>>  }\n>>> @@ -91,11 +90,11 @@ test03()\n>>>    };\n>>>    F::Arg arg;\n>>>\n>>> -  function_ref<int()> f0{std::nontype<F{}>, &arg};\n>>> +  function_ref<int()> f0{std::cw<F{}>, &arg};\n>>>    VERIFY( f0() == 0 );\n>>>    VERIFY( std::move(f0)() == 0 );\n>>>\n>>> -  function_ref<int() const> f1{std::nontype<F{}>, &arg};\n>>> +  function_ref<int() const> f1{std::cw<F{}>, &arg};\n>>>    VERIFY( f1() == 1 );\n>>>    VERIFY( std::as_const(f1)() == 1 );\n>>>  }\n>>> @@ -108,7 +107,7 @@ test04()\n>>>    VERIFY( f0() == 0 );\n>>>    VERIFY( std::move(f0)() == 0 );\n>>>\n>>> -  function_ref<int()> f1{nontype<fp>};\n>>> +  function_ref<int()> f1{std::cw<fp>};\n>>>    VERIFY( f1() == 0 );\n>>>    VERIFY( std::move(f1)() == 0 );\n>>>\n>>> @@ -116,7 +115,7 @@ test04()\n>>>    VERIFY( f2() == 0 );\n>>>    VERIFY( std::move(f2)() == 0 );\n>>>\n>>> -  const function_ref<int() const> f3{nontype<fp>};\n>>> +  const function_ref<int() const> f3{std::cw<fp>};\n>>>    VERIFY( f2() == 0 );\n>>>    VERIFY( std::move(f2)() == 0 );\n>>>  }\n>>> @@ -130,14 +129,14 @@ int callback_ref(ftype& f, int x) { return f(x); }\n>>>  void\n>>>  test05()\n>>>  {\n>>> -  function_ref<int(int)> r1(nontype<&callback_ptr>, &twice);\n>>> +  function_ref<int(int)> r1(std::cw<&callback_ptr>, &twice);\n>>>    VERIFY( r1(2) == 4 );\n>>> -  function_ref<int(int)> r2(nontype<&callback_ptr>, cube);\n>>> +  function_ref<int(int)> r2(std::cw<&callback_ptr>, cube);\n>>>    VERIFY( r2(2) == 8 );\n>>>\n>>> -  function_ref<int(int)> r3(nontype<&callback_ref>, twice);\n>>> +  function_ref<int(int)> r3(std::cw<&callback_ref>, twice);\n>>>    VERIFY( r3(3) == 6 );\n>>> -  function_ref<int(int)> r4(nontype<&callback_ref>, cube);\n>>> +  function_ref<int(int)> r4(std::cw<&callback_ref>, cube);\n>>>    VERIFY( r4(3) == 27 );\n>>>  }\n>>>\n>>> @@ -174,37 +173,37 @@ test06()\n>>>    std::function_ref<const int&(int, int) const> e8(std::as_const(csr));\n>>>    VERIFY( &e8(0, 0) == &s.v );\n>>>\n>>> -  std::function_ref<int&()> f1(std::nontype<&S::v>, sr);\n>>> +  std::function_ref<int&()> f1(std::cw<&S::v>, sr);\n>>>    VERIFY( &f1() == &s.v );\n>>> -  std::function_ref<const int&()> f2(std::nontype<&S::v>, sr);\n>>> +  std::function_ref<const int&()> f2(std::cw<&S::v>, sr);\n>>>    VERIFY( &f2() == &s.v );\n>>> -  std::function_ref<int&()> f3(std::nontype<&S::m>, sr);\n>>> +  std::function_ref<int&()> f3(std::cw<&S::m>, sr);\n>>>    VERIFY( &f3() == &s.v );\n>>> -  std::function_ref<const int&()> f4(std::nontype<&S::c>, sr);\n>>> +  std::function_ref<const int&()> f4(std::cw<&S::c>, sr);\n>>>    VERIFY( &f4() == &s.v );\n>>>\n>>> -  std::function_ref<const int&()> f5(std::nontype<&S::v>, csr);\n>>> +  std::function_ref<const int&()> f5(std::cw<&S::v>, csr);\n>>>    VERIFY( &f5() == &s.v );\n>>> -  std::function_ref<const int&()> f6(std::nontype<&S::c>, sr);\n>>> +  std::function_ref<const int&()> f6(std::cw<&S::c>, sr);\n>>>    VERIFY( &f6() == &s.v );\n>>>    static_assert( !std::is_constructible_v<\n>>>      std::function_ref<int&()>,\n>>> -    std::nontype_t<&S::c>, std::reference_wrapper<S>&>\n>>> +    std::constant_wrapper<&S::c>, std::reference_wrapper<S>&>\n>>>     );\n>>>\n>>> -  std::function_ref<int&()> f7(std::nontype<&S::v>, std::as_const(sr));\n>>> +  std::function_ref<int&()> f7(std::cw<&S::v>, std::as_const(sr));\n>>>    VERIFY( &f7() == &s.v );\n>>> -  std::function_ref<const int&()> f8(std::nontype<&S::m>,\n>>> std::as_const(sr));\n>>> +  std::function_ref<const int&()> f8(std::cw<&S::m>, std::as_const(sr));\n>>>    VERIFY( &f8() == &s.v );\n>>>\n>>>    // No rvalue reference_wrapper support\n>>>    static_assert( !std::is_constructible_v<\n>>>      std::function_ref<int&()>,\n>>> -    std::nontype_t<&S::v>, std::reference_wrapper<S>>\n>>> +    std::constant_wrapper<&S::v>, std::reference_wrapper<S>>\n>>>    );\n>>>    static_assert( !std::is_constructible_v<\n>>>      std::function_ref<int&()>,\n>>> -    std::nontype_t<&S::v>, std::reference_wrapper<const S>>\n>>> +    std::constant_wrapper<&S::v>, std::reference_wrapper<const S>>\n>>>    );\n>>>\n>>>    // reference to reference_wrapper are bound, so mutation are visible\n>>> @@ -232,9 +231,9 @@ test06()\n>>>    { return &x; };\n>>>\n>>>    // identity of reference_wrapper is preserved\n>>> -  std::function_ref<const std::reference_wrapper<S>*()>\n>>> g1(std::nontype<id>, sr);\n>>> +  std::function_ref<const std::reference_wrapper<S>*()> g1(std::cw<id>,\n>>> sr);\n>>>    VERIFY( g1() == &sr );\n>>> -  std::function_ref<const std::reference_wrapper<const S>*()>\n>>> g2(std::nontype<id>, csr);\n>>> +  std::function_ref<const std::reference_wrapper<const S>*()>\n>>> g2(std::cw<id>, csr);\n>>>    VERIFY( g2() == &csr );\n>>>  }\n>>>\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>>> index a91f5ba3dab..78aebd38a07 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cons.cc\n>>> @@ -9,8 +9,7 @@\n>>>  # error \"Feature-test macro for function_ref has wrong value in\n>>> <functional>\"\n>>>  #endif\n>>>\n>>> -using std::nontype;\n>>> -using std::nontype_t;\n>>> +using std::constant_wrapper;\n>>>  using std::function_ref;\n>>>\n>>>  using std::is_default_constructible_v;\n>>> @@ -60,31 +59,31 @@ static_assert( !\n>>> is_constructible_v<function_ref<int(S)>,\n>>>                                     decltype(&S::f)> );\n>>>\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>>> -                                         nontype_t<funS>> );\n>>> +                                         constant_wrapper<funS>> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>>> -                                         nontype_t<&funS>> );\n>>> +                                         constant_wrapper<&funS>> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>>> -                                         nontype_t<&S::x>> );\n>>> +                                         constant_wrapper<&S::x>> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int(S)>,\n>>> -                                         nontype_t<&S::f>> );\n>>> +                                         constant_wrapper<&S::f>> );\n>>>\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>>> -                                         nontype_t<funS>, S&> );\n>>> +                                         constant_wrapper<funS>, S&> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>>> -                                         nontype_t<&funS>, S&> );\n>>> +                                         constant_wrapper<&funS>, S&> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>>> -                                         nontype_t<&S::x>, S&> );\n>>> +                                         constant_wrapper<&S::x>, S&> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>>> -                                         nontype_t<&S::f>, S&> );\n>>> +                                         constant_wrapper<&S::f>, S&> );\n>>>\n>>>  static_assert( ! is_constructible_v<function_ref<int()>,\n>>> -                                   nontype_t<funS>, S*> );\n>>> +                                   constant_wrapper<funS>, S*> );\n>>>  static_assert( ! is_constructible_v<function_ref<int()>,\n>>> -                                   nontype_t<&funS>, S*> );\n>>> +                                   constant_wrapper<&funS>, S*> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>>> -                                         nontype_t<&S::x>, S*> );\n>>> +                                         constant_wrapper<&S::x>, S*> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<int()>,\n>>> -                                         nontype_t<&S::f>, S*> );\n>>> +                                         constant_wrapper<&S::f>, S*> );\n>>>\n>>>  struct M\n>>>  {\n>>> @@ -98,9 +97,9 @@ static_assert( !\n>>> is_constructible_v<function_ref<void()>, const M&> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>, M> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>, const\n>>> M&> );\n>>>  static_assert( ! is_constructible_v<function_ref<void()>,\n>>> -                                   nontype_t<M{}>> );\n>>> +                                   constant_wrapper<M{}>> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>>> -                                   nontype_t<M{}>> );\n>>> +                                   constant_wrapper<M{}>> );\n>>>  struct Q\n>>>  {\n>>>    void operator()(int) const;\n>>> @@ -115,22 +114,22 @@ static_assert(\n>>> is_nothrow_constructible_v<function_ref<void(int) const>, Q&> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<void(int)\n>>> const>, const Q&> );\n>>>\n>>>  static_assert( is_nothrow_constructible_v<function_ref<void(int)>,\n>>> -                                         nontype_t<Q{}>> );\n>>> +                                         constant_wrapper<Q{}>> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<void(int) const>,\n>>> -                                         nontype_t<Q{}>> );\n>>> +                                         constant_wrapper<Q{}>> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<void()>,\n>>> -                                         nontype_t<Q{}>, int&> );\n>>> +                                         constant_wrapper<Q{}>, int&> );\n>>>  static_assert( is_nothrow_constructible_v<function_ref<void() const>,\n>>> -                                         nontype_t<Q{}>, int&> );\n>>> +                                         constant_wrapper<Q{}>, int&> );\n>>>  static_assert( ! is_constructible_v<function_ref<void()>,\n>>> -                                   nontype_t<Q{}>, int> );\n>>> +                                   constant_wrapper<Q{}>, int> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>>> -                                   nontype_t<Q{}>, int> );\n>>> +                                   constant_wrapper<Q{}>, int> );\n>>>\n>>>  static_assert( is_nothrow_constructible_v<function_ref<void()>,\n>>> -                                         nontype_t<Q{}>, int*> );\n>>> +                                         constant_wrapper<Q{}>, int*> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>>> -                                   nontype_t<Q{}>, int*> );\n>>> +                                   constant_wrapper<Q{}>, int*> );\n>>>\n>>>  struct L\n>>>  {\n>>> @@ -143,9 +142,9 @@ static_assert( !\n>>> is_constructible_v<function_ref<void()>, const L&> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>, L> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>, const\n>>> L&> );\n>>>  static_assert( ! is_constructible_v<function_ref<void()>,\n>>> -                                   nontype_t<L{}>> );\n>>> +                                   constant_wrapper<L{}>> );\n>>>  static_assert( ! is_constructible_v<function_ref<void() const>,\n>>> -                                   nontype_t<L{}>> );\n>>> +                                   constant_wrapper<L{}>> );\n>>>\n>>>  struct R\n>>>  {\n>>> @@ -159,24 +158,24 @@ static_assert( !\n>>> is_constructible_v<function_ref<void(float) const>, R&> );\n>>>  static_assert( ! is_constructible_v<function_ref<void(float) const>,\n>>> const R&> );\n>>>\n>>>  static_assert( ! is_constructible_v<function_ref<void(float)>,\n>>> -                                                nontype_t<R{}>> );\n>>> +                                   constant_wrapper<R{}>> );\n>>>  static_assert( ! is_constructible_v<function_ref<void(float) const>,\n>>> -                                                nontype_t<R{}>> );\n>>> +                                   constant_wrapper<R{}>> );\n>>>\n>>>  constexpr bool\n>>>  test_constexpr()\n>>>  {\n>>> -  function_ref<void(S)> fp1(nontype<funS>);\n>>> -  function_ref<void(S)> fp3(nontype<&funS>);\n>>> -  function_ref<void(S)> fp4(nontype<&S::x>);\n>>> -  function_ref<void(S)> fp5(nontype<&S::f>);\n>>> +  function_ref<void(S)> fp1(std::cw<funS>);\n>>> +  function_ref<void(S)> fp3(std::cw<&funS>);\n>>> +  function_ref<void(S)> fp4(std::cw<&S::x>);\n>>> +  function_ref<void(S)> fp5(std::cw<&S::f>);\n>>>\n>>>    S s;\n>>> -  function_ref<void()> fp6(nontype<&funS>, s);\n>>> -  function_ref<void()> fp7(nontype<&S::x>, s);\n>>> -  function_ref<void()> fp8(nontype<&S::x>, &s);\n>>> -  function_ref<void()> fp9(nontype<&S::f>, s);\n>>> -  function_ref<void()> fp10(nontype<&S::f>, &s);\n>>> +  function_ref<void()> fp6(std::cw<&funS>, s);\n>>> +  function_ref<void()> fp7(std::cw<&S::x>, s);\n>>> +  function_ref<void()> fp8(std::cw<&S::x>, &s);\n>>> +  function_ref<void()> fp9(std::cw<&S::f>, s);\n>>> +  function_ref<void()> fp10(std::cw<&S::f>, &s);\n>>>\n>>>    M m;\n>>>    function_ref<void()> fm1(m);\n>>> @@ -190,13 +189,13 @@ test_constexpr()\n>>>\n>>>    function_ref<void(int)> fcq1(cq);\n>>>    function_ref<void(int) const> f(cq);\n>>> -  function_ref<void(int)> fcq3(nontype<cq>);\n>>> -  function_ref<void(int) const> fcq4(nontype<cq>);\n>>> +  function_ref<void(int)> fcq3(std::cw<cq>);\n>>> +  function_ref<void(int) const> fcq4(std::cw<cq>);\n>>>\n>>>    int i = 0;\n>>> -  function_ref<void()> fcq5(nontype<cq>, i);\n>>> -  function_ref<void() const> fcq6(nontype<cq>, i);\n>>> -  function_ref<void()> fcq7(nontype<cq>, &i);\n>>> +  function_ref<void()> fcq5(std::cw<cq>, i);\n>>> +  function_ref<void() const> fcq6(std::cw<cq>, i);\n>>> +  function_ref<void()> fcq7(std::cw<cq>, &i);\n>>>\n>>>    L l;\n>>>    function_ref<void()> fl1(l);\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>>> index 050090df370..a426ac64cd5 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cons_neg.cc\n>>> @@ -2,7 +2,6 @@\n>>>\n>>>  #include <functional>\n>>>\n>>> -using std::nontype;\n>>>  using std::function_ref;\n>>>\n>>>  struct S\n>>> @@ -16,15 +15,15 @@ constexpr int(*fp)(S) = nullptr;\n>>>  constexpr int S::*mdp = nullptr;\n>>>  constexpr int (S::*mfp)() = nullptr;\n>>>\n>>> -function_ref<int(S)> fd1(nontype<fp>);  // { dg-error \"from here\" }\n>>> -function_ref<int(S)> fd2(nontype<mdp>); // { dg-error \"from here\" }\n>>> -function_ref<int(S)> fd3(nontype<mfp>); // { dg-error \"from here\" }\n>>> +function_ref<int(S)> fd1(std::cw<fp>);  // { dg-error \"from here\" }\n>>> +function_ref<int(S)> fd2(std::cw<mdp>); // { dg-error \"from here\" }\n>>> +function_ref<int(S)> fd3(std::cw<mfp>); // { dg-error \"from here\" }\n>>>\n>>> -function_ref<int()> br4(nontype<fp>, s);  // { dg-error \"from here\" }\n>>> -function_ref<int()> br5(nontype<mdp>, s); // { dg-error \"from here\" }\n>>> -function_ref<int()> br6(nontype<mfp>, s); // { dg-error \"from here\" }\n>>> +function_ref<int()> br4(std::cw<fp>, s);  // { dg-error \"from here\" }\n>>> +function_ref<int()> br5(std::cw<mdp>, s); // { dg-error \"from here\" }\n>>> +function_ref<int()> br6(std::cw<mfp>, s); // { dg-error \"from here\" }\n>>>\n>>> -function_ref<int()> bp7(nontype<mdp>, &s); // { dg-error \"from here\" }\n>>> -function_ref<int()> bp8(nontype<mfp>, &s); // { dg-error \"from here\" }\n>>> +function_ref<int()> bp7(std::cw<mdp>, &s); // { dg-error \"from here\" }\n>>> +function_ref<int()> bp8(std::cw<mfp>, &s); // { dg-error \"from here\" }\n>>>\n>>>  // { dg-prune-output \"static assertion failed\" }\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>>> new file mode 100644\n>>> index 00000000000..a295bc2ce31\n>>> --- /dev/null\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/cw_cons_neg.cc\n>>> @@ -0,0 +1,35 @@\n>>> +// { dg-do compile { target c++26 } }\n>>> +\n>>> +#include <functional>\n>>> +\n>>> +using std::function_ref;\n>>> +using std::constant_wrapper;\n>>> +\n>>> +struct S\n>>> +{\n>>> +  int operator()() const { return 1; }\n>>> +\n>>> +  // Non-constant, so cw<S{}>(cw<1>) call never unwrapps\n>>> +  int operator()(int) const { return 1; }\n>>> +  template<auto __cw>\n>>> +    int operator()(constant_wrapper<__cw, int>) const { return 1; }\n>>> +\n>>> +  // Constant, cw<S{}>(cw<1>, cw<2>) calls int overload\n>>> +  // while S{}(cw<1>, cw<1>) calls constant_wrapper overload\n>>> +  constexpr int operator()(int, int) const { return 1; }\n>>> +  template<auto __cw1, auto __cw2>\n>>> +    constexpr int operator()(constant_wrapper<__cw1, int>,\n>>> +                            constant_wrapper<__cw2, int>)\n>>> +    { return 1; }\n>>> +};\n>>> +\n>>> +function_ref<int()> f0a(S{});\n>>> +\n>>> +function_ref<int(int)> f1a(S{});\n>>> +function_ref<int(constant_wrapper<2>)> f1b(std::cw<S{}>);\n>>> +\n>>> +function_ref<int(int, int)> f2a(std::cw<S{}>); // OK, runtime\n>>> +function_ref<int(constant_wrapper<1>, int)> f2b(std::cw<S{}>); // OK,\n>>> still runtime\n>>> +function_ref<int(constant_wrapper<2>, constant_wrapper<3>)>\n>>> f2c(std::cw<S{}>); // { dg-error \"from here\" }\n>>> +\n>>> +// { dg-prune-output \"static assertion failed\" }\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>>> index 3cc782524f6..4ef5d067555 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/dangling.cc\n>>> @@ -46,7 +46,7 @@ struct NonStatic {\n>>>    { return x + y + v; }\n>>>  };\n>>>\n>>> -constexpr auto vNonType = create(std::nontype<NonStatic{3}>);\n>>> +constexpr auto vNonType = create(std::cw<NonStatic{3}>);\n>>>\n>>>  struct StaticWins {\n>>>    static int\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>>> index b034c7af072..63c3f6ea7e3 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/deduction.cc\n>>> @@ -4,15 +4,13 @@\n>>>  #include <type_traits>\n>>>\n>>>  using std::is_same_v;\n>>> -using std::nontype;\n>>> -using std::nontype_t;\n>>>  using std::function_ref;\n>>>\n>>>  int i = 0;\n>>>\n>>>  template<auto f, class... Args>\n>>>    concept deductible = requires (Args&... args)\n>>> -  { std::function_ref(std::nontype<f>, args...); };\n>>> +  { std::function_ref(std::cw<f>, args...); };\n>>>\n>>>  static_assert( !deductible<1> );\n>>>  static_assert( !deductible<1, int> );\n>>> @@ -24,9 +22,9 @@ static_assert( is_same_v<decltype(function_ref(f0)),\n>>>                          function_ref<void()>> );\n>>>  static_assert( is_same_v<decltype(function_ref(f0n)),\n>>>                          function_ref<void() noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f0>)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f0>)),\n>>>                          function_ref<void()>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f0n>)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f0n>)),\n>>>                          function_ref<void() noexcept>> );\n>>>  static_assert( !deductible<f0, char*> );\n>>>  static_assert( !deductible<f0n, char*> );\n>>> @@ -38,13 +36,13 @@ static_assert( is_same_v<decltype(function_ref(f1)),\n>>>                          function_ref<void(int)>> );\n>>>  static_assert( is_same_v<decltype(function_ref(f1n)),\n>>>                          function_ref<void(int) noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f1>)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1>)),\n>>>                          function_ref<void(int)>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f1n>)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1n>)),\n>>>                          function_ref<void(int) noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f1>, i)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1>, i)),\n>>>                          function_ref<void()>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f1n>, i)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f1n>, i)),\n>>>                          function_ref<void() noexcept>> );\n>>>  static_assert( !deductible<f1, char*> );\n>>>  static_assert( !deductible<f1n, char*> );\n>>> @@ -56,13 +54,13 @@ static_assert( is_same_v<decltype(function_ref(f2)),\n>>>                          function_ref<void(int*, int)>> );\n>>>  static_assert( is_same_v<decltype(function_ref(f2n)),\n>>>                          function_ref<void(int*, int) noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f2>)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2>)),\n>>>                          function_ref<void(int*, int)>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f2n>)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2n>)),\n>>>                          function_ref<void(int*, int) noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f2>, &i)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2>, &i)),\n>>>                          function_ref<void(int)>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<f2n>, &i)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<f2n>, &i)),\n>>>                          function_ref<void(int) noexcept>> );\n>>>  static_assert( !deductible<f2, char*> );\n>>>  static_assert( !deductible<f2n, char*> );\n>>> @@ -88,40 +86,40 @@ struct S\n>>>  S s{};\n>>>  const S cs{};\n>>>\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, s)),\n>>>                          function_ref<int&() noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, cs)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, cs)),\n>>>                          function_ref<const int&() noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, &s)),\n>>>                          function_ref<int&() noexcept>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::mem>, &cs)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::mem>, &cs)),\n>>>                          function_ref<const int&() noexcept>> );\n>>>  static_assert( !deductible<&S::mem, int> );\n>>>\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::f>, s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::f>, s)),\n>>>                          function_ref<int()>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fn>, &s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fn>, &s)),\n>>>                          function_ref<int() noexcept>> );\n>>>  static_assert( !deductible<&S::f, char*> );\n>>>  static_assert( !deductible<&S::fn, char*> );\n>>>  static_assert( !deductible<&S::f, const S> );\n>>>  static_assert( !deductible<&S::fn, const S> );\n>>>\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fc>, &s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fc>, &s)),\n>>>                          function_ref<int(int)>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcn>, s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcn>, s)),\n>>>                          function_ref<int(int) noexcept>> );\n>>>  static_assert( !deductible<&S::fc, char*> );\n>>>  static_assert( !deductible<&S::fcn, char*> );\n>>>\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fl>, &s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fl>, &s)),\n>>>                          function_ref<int(int)>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fln>, s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fln>, s)),\n>>>                          function_ref<int(int) noexcept>> );\n>>>\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcl>, s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcl>, s)),\n>>>                          function_ref<int(float)>> );\n>>> -static_assert( is_same_v<decltype(function_ref(nontype<&S::fcln>, &s)),\n>>> +static_assert( is_same_v<decltype(function_ref(std::cw<&S::fcln>, &s)),\n>>>                          function_ref<int(float) noexcept>> );\n>>>\n>>>  static_assert( !deductible<&S::fr, char*> );\n>>> diff --git a/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>>> b/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>>> index 32c6931e9a8..d55f4facbda 100644\n>>> --- a/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>>> +++ b/libstdc++-v3/testsuite/20_util/function_ref/mutation.cc\n>>> @@ -3,7 +3,6 @@\n>>>  #include <functional>\n>>>  #include <testsuite_hooks.h>\n>>>\n>>> -using std::nontype;\n>>>  using std::function_ref;\n>>>\n>>>  void\n>>> @@ -55,8 +54,8 @@ test02()\n>>>    };\n>>>    S s{10};\n>>>\n>>> -  function_ref<int()> r1(nontype<&S::x>, s);\n>>> -  function_ref<long()> r2(nontype<&S::x>, &s);\n>>> +  function_ref<int()> r1(std::cw<&S::x>, s);\n>>> +  function_ref<long()> r2(std::cw<&S::x>, &s);\n>>>\n>>>    VERIFY( r1() == 10 );\n>>>    VERIFY( r2() == 10 );\n>>> @@ -66,8 +65,8 @@ test02()\n>>>    VERIFY( r1() == 20 );\n>>>    VERIFY( r2() == 20 );\n>>>\n>>> -  r1 = function_ref<int()>(nontype<&S::f>, &s);\n>>> -  r2 = function_ref<long()>(nontype<&S::f>, s);\n>>> +  r1 = function_ref<int()>(std::cw<&S::f>, &s);\n>>> +  r2 = function_ref<long()>(std::cw<&S::f>, s);\n>>>\n>>>    VERIFY( r1() == 20 );\n>>>    VERIFY( r2() == 20 );\n>>> --\n>>> 2.53.0\n>>>\n>>>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=c/xzTeBV;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=c/xzTeBV","sourceware.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com","sourceware.org; spf=pass smtp.mailfrom=gmail.com","server2.sourceware.org;\n arc=pass smtp.remote-ip=209.85.167.42"],"Received":["from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frRhW49Cmz1xv0\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 09 Apr 2026 01:25:15 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 909084BA5439\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  8 Apr 2026 15:25:13 +0000 (GMT)","from mail-lf1-f42.google.com (mail-lf1-f42.google.com\n [209.85.167.42])\n by sourceware.org (Postfix) with ESMTPS id B128B4BA2E26\n for <gcc-patches@gcc.gnu.org>; Wed,  8 Apr 2026 15:24:21 +0000 (GMT)","by mail-lf1-f42.google.com with SMTP id\n 2adb3069b0e04-59e5aa4ca41so6862321e87.2\n for <gcc-patches@gcc.gnu.org>; Wed, 08 Apr 2026 08:24:21 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 909084BA5439","OpenDKIM Filter v2.11.0 sourceware.org B128B4BA2E26"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org B128B4BA2E26","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org B128B4BA2E26","ARC-Seal":["i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1775661862; cv=pass;\n b=uPD8Fy1NwMmbgTl4NF+OasRWiA0dvBZBYYLaE8xzWO68j8eJlT0rF14NfDh/xfS1pxSlmaOp4hXVDzm7eJKAfFA9xpaWEGAYJpDkpIpGfZxZvgLo14NcUfozW5g9BGakDQxMo0AXzITNs3Nm7b9tIr2utLCBnqEAgqYADButiiI=","i=1; a=rsa-sha256; t=1775661860; cv=none;\n d=google.com; s=arc-20240605;\n b=ClJs7HBwxnqu2w2fOq9jgm1JDEGJoQRYga3Rm2Q3wMryJMfoVzD7AvjE2XbCQBJIu7\n JeGGGS6dAa7gwZznQDVICbvlOOfGAXioIRq3laAxcUP/73YWRMi2P4oRAFDPkaJ3faKK\n Nbzudsy9Y0DPmT8hCA8dUe/SfW/9M+E8z1qPD0DaytNewLHCK0NxX3I4bh5m2BZfJVdE\n tu+451/VLdijkejZHedsPbtevTs46Tnj/0+j4OMat52O9ax1iX5r5ijlWDWMuQLBEuwh\n ViGJdPm2TYWu7hNGFUHtesTsJJbkk+zBKNe4Cb0fhxWwzzq4vqv5ItBn/1MYFkx5z8g9\n lpNQ=="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775661862; c=relaxed/simple;\n bh=HUjZyH1NKqqEuGUr1Udf11/4foFqph2X/BTSvNr0l6M=;\n h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;\n b=awr7nCZ7y+WZc+hri+l+fF9pTZOW2cGNlsn0cO28SSEUv0+Alx7XqqrnlVV5u8u35N3f1Z+sul2HOBRkYV0BvJHUYyKPRMkWlXNTYAtH+3RDEpHjJlLnEnpmgoj8b81MOywjADIVvJ4ot3idTog1PvkTV0/lADKKx/V7aqg7r0Y=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:dkim-signature;\n bh=Tvl0BlBnOtaKw8HYu+OC7mqHbvs2i6OQgu+RFzvZ3FY=;\n fh=lVbzi9LKwipFEikMq8e4M15vTk9Z1zNDgGuNsZYvZPE=;\n b=AeDhNj7OCKKutxTmR4mKectjvV/M+F9KK8ytIpQ0d0IPLR9VFjt3X3kb17bNPH+c9R\n /TeyiV/2Cpy5hYAJjSCTCb+ELkxi2PjuuZu6DrQHPrX6vxN/LxX4/YVsO4zbKx/sGJ+c\n If5jtiwKKulLSgXv/Ez3SKcQ+qfASfDttik4FjT5Lox3J0MGTO/q638t4/pxvpUszpiO\n zqPnHpKsXN90bR3NcomcIwU8aUiXaVSMCTdGg3Tu91G3EYhJPBF8EiGRv1FB1mxFpdza\n 2uDRs8ODhR57zysFY3U6uD7GWIX6T2zp+/JFRzVenUh2lO/B52irx0IQjaFlPqbOen/n\n k9og==; darn=gcc.gnu.org"],"ARC-Authentication-Results":["i=2; server2.sourceware.org","i=1; mx.google.com; arc=none"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1775661860; x=1776266660; darn=gcc.gnu.org;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:from:to:cc:subject:date:message-id:reply-to;\n bh=Tvl0BlBnOtaKw8HYu+OC7mqHbvs2i6OQgu+RFzvZ3FY=;\n b=c/xzTeBVFwU3qRxOVyaxTZarwlpmeodqoGYWaEKscL5uHFfmf/vOX9rF+AMRbiuHvr\n I9D4SzvUoIUYU4cHrB+UfcZXbmICsfzmHuBaxh4MAkbGCVESwqa0DoONS7LwfB9ea0xY\n DXWzhpoeHqAPA64EgeIpIDSoPqypQZhJgUZsws0MgRVBJkeJcVsyxCIlPwcefTIayTHt\n U0i9PIoAJqETrckc7WFYmg3gWJ4Dstl1YHMxO5W9Ufnbo7qBEClCPDdLdOdqWKv8++Yw\n 7wo2ADd3Taj3IcYKz05CpOM1AvkS8bs/hk1pYtbkn1+fEFHgRt626FaajnOK0PphAu3L\n eIGA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775661860; x=1776266660;\n h=cc:to:subject:message-id:date:from:in-reply-to:references\n :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=Tvl0BlBnOtaKw8HYu+OC7mqHbvs2i6OQgu+RFzvZ3FY=;\n b=Hd0G4H1miE+V3TeaPUwmw5bJ3fkn5IfbeyWLAtorvzFT6N/ml3fUtrnKeJOB5Dnipp\n 20agjazO2tVTQ5Y/O+ROnaFdwWWAJf/4/eOpJvnmtPJi7zrSuvo9gpDYOsl8M1fUtHCu\n Rj+v7gBPz/6dxHtGVrWHmPz+bpBDPA/8m8Yy1cFDJqmqZTN5iTXgHlTgKaPxtSXSKNxq\n krkGGsjKldfSuNRKtW0c23JknHCwsqbKtWp12rQR5B6mZo2ykzye/F/mMMJ6fqmsaFu4\n GTBFLZPxKDhOG6V9E/b6wQFKQfAcZC4g249iqn9Fm4fM8N1ZWNpkik1MogcR7jHhDLhF\n P4/w==","X-Forwarded-Encrypted":"i=1;\n AJvYcCUEa1cAnbzJnDf4qx3IIgtQKlB4RPwb0LyUnlglNQ6gKGu9EvQxO/SryBNW9BQajpG3q0+hMgx18MVBEQ==@gcc.gnu.org","X-Gm-Message-State":"AOJu0YyljaZnvB35wwpTLjZluXeWUOK0ASQu6YAd4dx+kdbdV/YA9lzP\n GvsTaTjUr06h1NWJNbdzUq5MKleyQWebIy6z2i3Zd+kUKFrewgdjlBwi4hDLYOZqkqnO0qWaRbH\n oxY7jG/cJJDOKa3L+2xCziNR64E7QYac=","X-Gm-Gg":"AeBDiesZkjhkNPdrzMZpOM2hKkLpuTZab/PKfENALNObOb8lZ9leM8wwGvrzJ9omM48\n OwEKwZ9NigMxlaLGTSUw+PXwu7kVWk7FuQZmKBDWB9o8vM/X4isFBzkdxBB5fcMsQX9RmTYnnwL\n cSCMmN+xGTt3+Djzvm/qFTvl84E5BGLLnenhOGE62dV+jYOR12YbYqiVv3ypRVy9ezrbDZvxwzX\n 8J83spv0DfU15PdygqxOPpFKS5Bix28MuBLekukF3YcsIYWQdMairrep6TiLnRxcoH4C7kSNgsK\n 0UFbyHlNoI87ndxj/kj+IaE2uaXsZCa40aJsH+mqyogL9Dm2drrrhZj7wPQWnzqgiAOKhbZ04uX\n oHnXz0DWdzVJaySLsVXb54PLZdQw=","X-Received":"by 2002:a05:6512:690:b0:5a1:378c:11e8 with SMTP id\n 2adb3069b0e04-5a33755ca72mr6725181e87.14.1775661859629; Wed, 08 Apr 2026\n 08:24:19 -0700 (PDT)","MIME-Version":"1.0","References":"<20260408094553.155396-1-tkaminsk@redhat.com>\n <CAH6eHdSx5kSs6JuBBv6MZaXk6o1kMk-uwN=kTxWTOODKcjvKww@mail.gmail.com>\n <CAKvuMXC9h_u8EaKGL7Pc_3g0hfuGaPjp6j4-iXJ5RQ1GahMOTg@mail.gmail.com>","In-Reply-To":"\n <CAKvuMXC9h_u8EaKGL7Pc_3g0hfuGaPjp6j4-iXJ5RQ1GahMOTg@mail.gmail.com>","From":"Jonathan Wakely <jwakely.gcc@gmail.com>","Date":"Wed, 8 Apr 2026 16:24:06 +0100","X-Gm-Features":"AQROBzAakKs049DwwjVKH1A9BQOBUugbd-cJDba0hiqRNZJIKwI0hBJwblzw2tg","Message-ID":"\n <CAH6eHdTuGF+PpFkJ5dZNnSc5Qh92sP-d9WQndPDQ-MwjqjSz2Q@mail.gmail.com>","Subject":"Re: [PATCH] libstdc++: Remove non_type and replace it with\n constant_wrapper in function_ref","To":"Tomasz Kaminski <tkaminsk@redhat.com>","Cc":"\"libstdc++\" <libstdc++@gcc.gnu.org>,\n gcc-patches <gcc-patches@gcc.gnu.org>,\n Matthias Kretz <m.kretz@gsi.de>","Content-Type":"multipart/alternative; boundary=\"0000000000006270e7064ef47e6c\"","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]