17#ifndef LLVM_ADT_STLFORWARDCOMPAT_H
18#define LLVM_ADT_STLFORWARDCOMPAT_H
34template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
35inline constexpr T e_v =
T(0x1.5bf0a8b145769P+1);
36template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
38template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
39inline constexpr T ln2_v =
T(0x1.62e42fefa39efP-1);
40template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
41inline constexpr T ln10_v =
T(0x1.26bb1bbb55516P+1);
42template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
43inline constexpr T log2e_v =
T(0x1.71547652b82feP+0);
44template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
46template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
47inline constexpr T pi_v =
T(0x1.921fb54442d18P+1);
48template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
50template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
52template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
53inline constexpr T sqrt2_v =
T(0x1.6a09e667f3bcdP+0);
54template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
56template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
57inline constexpr T sqrt3_v =
T(0x1.bb67ae8584caaP+0);
58template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
60template <
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>>>
61inline constexpr T phi_v =
T(0x1.9e3779b97f4a8P+0);
83 using type = std::remove_cv_t<std::remove_reference_t<T>>;
104template <
class,
template <
class...>
class Op,
class... Args>
struct detector {
107template <
template <
class...>
class Op,
class... Args>
127template <
template <
class...>
class Op,
class... Args>
134 template <
typename T>
constexpr T &&
operator()(
T &&self)
const noexcept {
135 return std::forward<T>(self);
146template <
class Ptr>
auto to_address(
const Ptr &
P) {
return P.operator->(); }
148 static_assert(!std::is_function_v<T>);
154template <
typename FnT,
typename... ArgsT>
155constexpr std::invoke_result_t<
FnT, ArgsT...>
157 return std::apply(std::forward<FnT>(Fn),
158 std::forward_as_tuple(std::forward<ArgsT>(Args)...));
167template <
typename Optional,
typename Function,
169std::optional<std::invoke_result_t<Function, Value>>
172 return F(*std::forward<Optional>(O));
179template <
typename Enum>
181 return static_cast<std::underlying_type_t<Enum>
>(
E);
204 template <
typename FnArgT>
213 constexpr decltype(
auto)
get()
const {
return ConstFn; }
220template <
bool BindFront,
typename BoundArgsTupleT,
typename FnStorageT,
224template <
bool BindFront,
typename BoundArgsTupleT,
typename FnStorageT,
227 std::index_sequence<Indices...>> {
228 BoundArgsTupleT BoundArgs;
234 template <
typename FnArgT,
typename... BoundArgsArgT>
236 : BoundArgs(
std::forward<BoundArgsArgT>(Args)...),
237 FnStorage(
std::forward<FnArgT>(
F)) {}
240 template <
typename... BoundArgsArgT>
242 : BoundArgs(
std::forward<BoundArgsArgT>(Args)...), FnStorage() {}
244 template <
typename... CallArgsT>
245 constexpr decltype(
auto)
operator()(CallArgsT &&...CallArgs) {
246 if constexpr (BindFront)
247 return llvm::invoke(FnStorage.get(), std::get<Indices>(BoundArgs)...,
248 std::forward<CallArgsT>(CallArgs)...);
250 return llvm::invoke(FnStorage.get(), std::forward<CallArgsT>(CallArgs)...,
251 std::get<Indices>(BoundArgs)...);
254 template <
typename... CallArgsT>
255 constexpr decltype(
auto)
operator()(CallArgsT &&...CallArgs)
const {
256 if constexpr (BindFront)
257 return llvm::invoke(FnStorage.get(), std::get<Indices>(BoundArgs)...,
258 std::forward<CallArgsT>(CallArgs)...);
260 return llvm::invoke(FnStorage.get(), std::forward<CallArgsT>(CallArgs)...,
261 std::get<Indices>(BoundArgs)...);
269template <
typename FnT,
typename... BindArgsT>
271 BindArgsT &&...BindArgs) {
273 std::tuple<std::decay_t<BindArgsT>...>,
275 std::index_sequence_for<BindArgsT...>>(
277 std::forward<BindArgsT>(BindArgs)...);
282template <
auto ConstFn,
typename... BindArgsT>
285 if constexpr (std::is_pointer_v<
decltype(ConstFn)> ||
286 std::is_member_pointer_v<
decltype(ConstFn)>)
287 static_assert(ConstFn !=
nullptr);
290 true, std::tuple<std::decay_t<BindArgsT>...>,
298template <
typename FnT,
typename... BindArgsT>
300 BindArgsT &&...BindArgs) {
302 std::tuple<std::decay_t<BindArgsT>...>,
304 std::index_sequence_for<BindArgsT...>>(
306 std::forward<BindArgsT>(BindArgs)...);
311template <
auto ConstFn,
typename... BindArgsT>
314 if constexpr (std::is_pointer_v<
decltype(ConstFn)> ||
315 std::is_member_pointer_v<
decltype(ConstFn)>)
316 static_assert(ConstFn !=
nullptr);
319 false, std::tuple<std::decay_t<BindArgsT>...>,
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_NO_UNIQUE_ADDRESS
constexpr BindStorage(RuntimeFnTag, FnArgT &&F, BoundArgsArgT &&...Args)
constexpr decltype(auto) operator()(CallArgsT &&...CallArgs)
constexpr BindStorage(ConstantFnTag, BoundArgsArgT &&...Args)
constexpr double inv_sqrt2
constexpr double inv_sqrt3
constexpr double inv_sqrtpi
This is an optimization pass for GlobalISel generic memory operations.
constexpr from_range_t from_range
constexpr std::invoke_result_t< FnT, ArgsT... > invoke(FnT &&Fn, ArgsT &&...Args)
C++20 constexpr invoke.
constexpr auto bind_back(FnT &&Fn, BindArgsT &&...BindArgs)
C++23 bind_back.
constexpr auto bind_front(FnT &&Fn, BindArgsT &&...BindArgs)
C++20 bind_front.
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
DWARFExpression::Operation Op
auto to_address(const Ptr &P)
Returns a raw pointer that represents the same address as the argument.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
std::optional< std::invoke_result_t< Function, Value > > transformOptional(Optional &&O, Function &&F)
Implement std::hash so that hash_code can be used in STL containers.
Holds a compile-time constant callable (empty storage).
constexpr decltype(auto) get() const
Stores a callable as a data member.
constexpr const FnT & get() const
constexpr FnHolder(FnArgT &&F)
constexpr T && operator()(T &&self) const noexcept
std::remove_cv_t< std::remove_reference_t< T > > type