[llvm] [ADT] Consolidate CallbacksHolder (NFC) (PR #160234)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 22 22:43:07 PDT 2025
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/160234
This patch consolidates the two implementations of CallbacksHolder
with "if constexpr". The immediately evaluated lambda expression
works as a type selector as well as initializers. This way, we can
migrate away from the SFINAE trick.
>From 2c47754a4ebfb325f2bf197579cdd9436ac307fb Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Mon, 22 Sep 2025 08:02:12 -0700
Subject: [PATCH] [ADT] Consolidate CallbacksHolder (NFC)
This patch consolidates the two implementations of CallbacksHolder
with "if constexpr". The immediately evaluated lambda expression
works as a type selector as well as initializers. This way, we can
migrate away from the SFINAE trick.
---
llvm/include/llvm/ADT/FunctionExtras.h | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h
index 1311452a17bb3..12a2dc36e1af0 100644
--- a/llvm/include/llvm/ADT/FunctionExtras.h
+++ b/llvm/include/llvm/ADT/FunctionExtras.h
@@ -58,10 +58,6 @@ template <typename FunctionT> class unique_function;
namespace detail {
-template <typename T>
-using EnableIfTrivial =
- std::enable_if_t<std::is_trivially_move_constructible<T>::value &&
- std::is_trivially_destructible<T>::value>;
template <typename CallableT, typename ThisT>
using EnableUnlessSameType =
std::enable_if_t<!std::is_same<remove_cvref_t<CallableT>, ThisT>::value>;
@@ -236,17 +232,17 @@ template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
// type erased behaviors needed. Create a static instance of the struct type
// here and each instance will contain a pointer to it.
// Wrap in a struct to avoid https://gcc.gnu.org/PR71954
- template <typename CallableT, typename CalledAs, typename Enable = void>
- struct CallbacksHolder {
- inline static NonTrivialCallbacks Callbacks = {
- &CallImpl<CalledAs>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
- };
- // See if we can create a trivial callback. We need the callable to be
- // trivially moved and trivially destroyed so that we don't have to store
- // type erased callbacks for those operations.
- template <typename CallableT, typename CalledAs>
- struct CallbacksHolder<CallableT, CalledAs, EnableIfTrivial<CallableT>> {
- inline static TrivialCallback Callbacks = {&CallImpl<CalledAs>};
+ template <typename CallableT, typename CalledAs> struct CallbacksHolder {
+ inline static auto Callbacks = []() constexpr {
+ // For trivial callables, we don't need to store move and destroy
+ // callbacks.
+ if constexpr (std::is_trivially_move_constructible_v<CallableT> &&
+ std::is_trivially_destructible_v<CallableT>)
+ return TrivialCallback{&CallImpl<CalledAs>};
+ else
+ return NonTrivialCallbacks{&CallImpl<CalledAs>, &MoveImpl<CallableT>,
+ &DestroyImpl<CallableT>};
+ }();
};
// A simple tag type so the call-as type to be passed to the constructor.
More information about the llvm-commits
mailing list