[libcxx-commits] [libcxx] constexpr function ref (PR #186692)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 24 00:33:48 PDT 2026


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff origin/main HEAD --extensions ,h,cpp,inc -- libcxx/include/__functional/function_ref.h libcxx/include/__functional/function_ref_common.h libcxx/include/__functional/function_ref_impl.h libcxx/include/__utility/constant_arg.h libcxx/test/libcxx/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/assert.constant_arg_ptr.pass.cpp libcxx/test/libcxx/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/assert.function_ptr.pass.cpp libcxx/test/libcxx/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/constant_arg.mandates.verify.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/ctad.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/assign.delete.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/constant_arg.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/constant_arg_ptr.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/constant_arg_ref.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/copy.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/copy_assign.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/function_ptr.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/move.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/move_assign.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.ctor/ref.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/func.wrap.ref.inv/invoke.pass.cpp libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.ref/trivially_copyable.compile.pass.cpp libcxx/include/functional libcxx/include/utility libcxx/include/version libcxx/modules/std/functional.inc libcxx/modules/std/utility.inc libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp --diff_from_common_commit
``````````

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/libcxx/include/__functional/function_ref_common.h b/libcxx/include/__functional/function_ref_common.h
index 0b1aa207c..83d0c8b18 100644
--- a/libcxx/include/__functional/function_ref_common.h
+++ b/libcxx/include/__functional/function_ref_common.h
@@ -31,45 +31,45 @@ class function_ref;
 template <class _Fn, bool _NoExcept1, class _Rp, class... _ArgTypes>
 struct __is_convertible_from_specialization : false_type {};
 
-  // use a union instead of a plain `void*` to avoid dropping const qualifiers and casting function pointers to data
-  // pointers
-  // todo: libstdc++ does not support volatile objects. shall we support it? the standard does not say it should not be
-  // supported
-  template <class _Rp, class... _ArgTypes>
-  union __storage_func_ref_t {
-    void* __obj_ptr_;
-    void const* __obj_const_ptr_;
-    _Rp (*__fn_ptr_)(_ArgTypes...);
-    _Rp (*__fn_ptr_noexcept_)(_ArgTypes...) noexcept;
-    void(* __fn_ptr_type_erased_)();
-
-    _LIBCPP_HIDE_FROM_ABI constexpr explicit __storage_func_ref_t() noexcept : __obj_ptr_(nullptr) {}
-
-    template <class _Tp>
-    _LIBCPP_HIDE_FROM_ABI constexpr explicit __storage_func_ref_t(_Tp* __ptr) noexcept {
-      if constexpr (is_object_v<_Tp>) {
-        if constexpr (is_const_v<_Tp>) {
-          __obj_const_ptr_ = __ptr;
+// use a union instead of a plain `void*` to avoid dropping const qualifiers and casting function pointers to data
+// pointers
+// todo: libstdc++ does not support volatile objects. shall we support it? the standard does not say it should not be
+// supported
+template <class _Rp, class... _ArgTypes>
+union __storage_func_ref_t {
+  void* __obj_ptr_;
+  void const* __obj_const_ptr_;
+  _Rp (*__fn_ptr_)(_ArgTypes...);
+  _Rp (*__fn_ptr_noexcept_)(_ArgTypes...) noexcept;
+  void (*__fn_ptr_type_erased_)();
+
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __storage_func_ref_t() noexcept : __obj_ptr_(nullptr) {}
+
+  template <class _Tp>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __storage_func_ref_t(_Tp* __ptr) noexcept {
+    if constexpr (is_object_v<_Tp>) {
+      if constexpr (is_const_v<_Tp>) {
+        __obj_const_ptr_ = __ptr;
+      } else {
+        __obj_ptr_ = __ptr;
+      }
+    } else {
+      static_assert(is_function_v<_Tp>);
+      if constexpr (is_nothrow_invocable_v<_Tp, _ArgTypes...>) {
+        if constexpr (requires { __fn_ptr_noexcept_ = __ptr; }) {
+          __fn_ptr_noexcept_ = __ptr;
         } else {
-          __obj_ptr_ = __ptr;
+          __fn_ptr_type_erased_ = reinterpret_cast<void (*)()>(__ptr);
         }
       } else {
-        static_assert(is_function_v<_Tp>);
-        if constexpr (is_nothrow_invocable_v<_Tp, _ArgTypes...>) {
-          if constexpr (requires { __fn_ptr_noexcept_ = __ptr; }) {
-            __fn_ptr_noexcept_ = __ptr;
-          } else {
-            __fn_ptr_type_erased_ = reinterpret_cast<void(*)()>(__ptr);
-          }
+        if constexpr (requires { __fn_ptr_ = __ptr; }) {
+          __fn_ptr_ = __ptr;
         } else {
-          if constexpr (requires { __fn_ptr_ = __ptr; }) {
-            __fn_ptr_ = __ptr;
-          } else {
-            __fn_ptr_type_erased_ = reinterpret_cast<void(*)()>(__ptr);
-          }
+          __fn_ptr_type_erased_ = reinterpret_cast<void (*)()>(__ptr);
         }
       }
     }
+  }
 
   template <class _Tp>
   _LIBCPP_HIDE_FROM_ABI static constexpr auto __get(__storage_func_ref_t __storage) {
@@ -96,9 +96,7 @@ struct __is_convertible_from_specialization : false_type {};
       }
     }
   }
-  };
-
-
+};
 
 template <class _Fp, class _Tp>
 struct __function_ref_bind {};
diff --git a/libcxx/include/__functional/function_ref_impl.h b/libcxx/include/__functional/function_ref_impl.h
index 78c5b6a35..7fda664c2 100644
--- a/libcxx/include/__functional/function_ref_impl.h
+++ b/libcxx/include/__functional/function_ref_impl.h
@@ -46,9 +46,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class...>
 class function_ref;
 
-template <bool _NoExcept2,  bool _NoExcept1, class _Rp, class... _ArgTypes>
-struct __is_convertible_from_specialization<function_ref<_Rp(_ArgTypes...) _LIBCPP_FUNCTION_REF_CV noexcept(_NoExcept2)>, _NoExcept1, _Rp, _ArgTypes...>
- : is_convertible<_Rp(&)(_ArgTypes...) noexcept(_NoExcept2), _Rp(&)(_ArgTypes...) noexcept(_NoExcept1)> {};
+template <bool _NoExcept2, bool _NoExcept1, class _Rp, class... _ArgTypes>
+struct __is_convertible_from_specialization<
+    function_ref<_Rp(_ArgTypes...) _LIBCPP_FUNCTION_REF_CV noexcept(_NoExcept2)>,
+    _NoExcept1,
+    _Rp,
+    _ArgTypes...>
+    : is_convertible<_Rp (&)(_ArgTypes...) noexcept(_NoExcept2), _Rp (&)(_ArgTypes...) noexcept(_NoExcept1)> {};
 
 template <class _Rp, class... _ArgTypes, bool __is_noexcept>
 class function_ref<_Rp(_ArgTypes...) _LIBCPP_FUNCTION_REF_CV noexcept(__is_noexcept)> {
@@ -59,9 +63,10 @@ private:
           value;
 
   template <class _Fn>
-  static constexpr bool __is_convertible_from_specialization_v = __is_convertible_from_specialization<_Fn, __is_noexcept, _Rp, _ArgTypes...>::value;
+  static constexpr bool __is_convertible_from_specialization_v =
+      __is_convertible_from_specialization<_Fn, __is_noexcept, _Rp, _ArgTypes...>::value;
 
-  template<class... _Tp>
+  template <class... _Tp>
   friend class function_ref;
 
   using __storage_t _LIBCPP_NODEBUG = __storage_func_ref_t<_Rp, _ArgTypes...>;
@@ -96,8 +101,7 @@ public:
     requires(!is_same_v<remove_cvref_t<_Fn>, function_ref> && !is_member_pointer_v<_Tp> &&
              __is_invocable_using<_LIBCPP_FUNCTION_REF_CV _Tp&> && __is_convertible_from_specialization_v<_Tp>)
   _LIBCPP_HIDE_FROM_ABI constexpr function_ref(_Fn&& __obj) noexcept
-      : __storage_(__obj.__storage_),
-        __call_(__obj.__call_) {}
+      : __storage_(__obj.__storage_), __call_(__obj.__call_) {}
 
   template <auto _Fn>
     requires __is_invocable_using<const decltype(_Fn)&>

``````````

</details>


https://github.com/llvm/llvm-project/pull/186692


More information about the libcxx-commits mailing list