LLVM 22.0.0git
STLForwardCompat.h
Go to the documentation of this file.
1//===- STLForwardCompat.h - Library features from future STLs ------C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file contains library features backported from future STL versions.
11///
12/// These should be replaced with their STL counterparts as the C++ version LLVM
13/// is compiled with is updated.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_ADT_STLFORWARDCOMPAT_H
18#define LLVM_ADT_STLFORWARDCOMPAT_H
19
20#include <optional>
21#include <type_traits>
22#include <utility>
23
24namespace llvm {
25
26//===----------------------------------------------------------------------===//
27// Features from C++20
28//===----------------------------------------------------------------------===//
29
30namespace numbers {
31// clang-format off
32template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
33inline constexpr T e_v = T(0x1.5bf0a8b145769P+1); // (2.7182818284590452354) https://oeis.org/A001113
34template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
35inline constexpr T egamma_v = T(0x1.2788cfc6fb619P-1); // (.57721566490153286061) https://oeis.org/A001620
36template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
37inline constexpr T ln2_v = T(0x1.62e42fefa39efP-1); // (.69314718055994530942) https://oeis.org/A002162
38template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
39inline constexpr T ln10_v = T(0x1.26bb1bbb55516P+1); // (2.3025850929940456840) https://oeis.org/A002392
40template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
41inline constexpr T log2e_v = T(0x1.71547652b82feP+0); // (1.4426950408889634074)
42template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
43inline constexpr T log10e_v = T(0x1.bcb7b1526e50eP-2); // (.43429448190325182765)
44template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
45inline constexpr T pi_v = T(0x1.921fb54442d18P+1); // (3.1415926535897932385) https://oeis.org/A000796
46template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
47inline constexpr T inv_pi_v = T(0x1.45f306dc9c883P-2); // (.31830988618379067154) https://oeis.org/A049541
48template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
49inline constexpr T inv_sqrtpi_v = T(0x1.20dd750429b6dP-1); // (.56418958354775628695) https://oeis.org/A087197
50template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
51inline constexpr T sqrt2_v = T(0x1.6a09e667f3bcdP+0); // (1.4142135623730950488) https://oeis.org/A00219
52template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
53inline constexpr T inv_sqrt2_v = T(0x1.6a09e667f3bcdP-1); // (.70710678118654752440)
54template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
55inline constexpr T sqrt3_v = T(0x1.bb67ae8584caaP+0); // (1.7320508075688772935) https://oeis.org/A002194
56template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
57inline constexpr T inv_sqrt3_v = T(0x1.279a74590331cP-1); // (.57735026918962576451)
58template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
59inline constexpr T phi_v = T(0x1.9e3779b97f4a8P+0); // (1.6180339887498948482) https://oeis.org/A001622
60
61inline constexpr double e = e_v<double>;
62inline constexpr double egamma = egamma_v<double>;
63inline constexpr double ln2 = ln2_v<double>;
64inline constexpr double ln10 = ln10_v<double>;
65inline constexpr double log2e = log2e_v<double>;
66inline constexpr double log10e = log10e_v<double>;
67inline constexpr double pi = pi_v<double>;
68inline constexpr double inv_pi = inv_pi_v<double>;
69inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
70inline constexpr double sqrt2 = sqrt2_v<double>;
71inline constexpr double inv_sqrt2 = inv_sqrt2_v<double>;
72inline constexpr double sqrt3 = sqrt3_v<double>;
73inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
74inline constexpr double phi = phi_v<double>;
75// clang-format on
76} // namespace numbers
77
78template <typename T>
79struct remove_cvref // NOLINT(readability-identifier-naming)
80{
81 using type = std::remove_cv_t<std::remove_reference_t<T>>;
82};
83
84template <typename T>
85using remove_cvref_t // NOLINT(readability-identifier-naming)
87
88// TODO: Remove this in favor of std::type_identity<T> once we switch to C++20.
89template <typename T>
90struct type_identity // NOLINT(readability-identifier-naming)
91{
92 using type = T;
93};
94
95// TODO: Remove this in favor of std::type_identity_t<T> once we switch to
96// C++20.
97template <typename T>
98using type_identity_t // NOLINT(readability-identifier-naming)
100
101namespace detail {
102template <class, template <class...> class Op, class... Args> struct detector {
103 using value_t = std::false_type;
104};
105template <template <class...> class Op, class... Args>
106struct detector<std::void_t<Op<Args...>>, Op, Args...> {
107 using value_t = std::true_type;
108};
109} // end namespace detail
110
111/// Detects if a given trait holds for some set of arguments 'Args'.
112/// For example, the given trait could be used to detect if a given type
113/// has a copy assignment operator:
114/// template<class T>
115/// using has_copy_assign_t = decltype(std::declval<T&>()
116/// = std::declval<const T&>());
117/// bool fooHasCopyAssign = is_detected<has_copy_assign_t, FooClass>::value;
118template <template <class...> class Op, class... Args>
119using is_detected = typename detail::detector<void, Op, Args...>::value_t;
120
121struct identity_cxx20 // NOLINT(readability-identifier-naming)
122{
123 using is_transparent = void;
124
125 template <typename T> constexpr T &&operator()(T &&self) const noexcept {
126 return std::forward<T>(self);
127 }
128};
129
130//===----------------------------------------------------------------------===//
131// Features from C++23
132//===----------------------------------------------------------------------===//
133
134// TODO: Remove this in favor of std::optional<T>::transform once we switch to
135// C++23.
136template <typename Optional, typename Function,
137 typename Value = typename llvm::remove_cvref_t<Optional>::value_type>
138std::optional<std::invoke_result_t<Function, Value>>
139transformOptional(Optional &&O, Function &&F) {
140 if (O) {
141 return F(*std::forward<Optional>(O));
142 }
143 return std::nullopt;
144}
145
146/// Returns underlying integer value of an enum. Backport of C++23
147/// std::to_underlying.
148template <typename Enum>
149[[nodiscard]] constexpr std::underlying_type_t<Enum> to_underlying(Enum E) {
150 return static_cast<std::underlying_type_t<Enum>>(E);
151}
152
153// A tag for constructors accepting ranges.
155 explicit from_range_t() = default;
156};
157inline constexpr from_range_t from_range{};
158} // namespace llvm
159
160#endif // LLVM_ADT_STLFORWARDCOMPAT_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define F(x, y, z)
Definition MD5.cpp:55
#define T
Mathematical constants.
constexpr T log10e_v
constexpr double sqrt2
constexpr double inv_sqrt2
constexpr T e_v
constexpr double inv_pi
constexpr T log2e_v
constexpr T egamma_v
constexpr T sqrt3_v
constexpr double ln2
constexpr double inv_sqrt3
constexpr double egamma
constexpr T sqrt2_v
constexpr T inv_sqrt3_v
constexpr T inv_sqrtpi_v
constexpr double ln10
constexpr double inv_sqrtpi
constexpr T ln10_v
constexpr double e
constexpr double phi
constexpr T pi_v
constexpr double sqrt3
constexpr T phi_v
constexpr double log10e
constexpr double log2e
constexpr T ln2_v
constexpr T inv_pi_v
constexpr T inv_sqrt2_v
constexpr double pi
This is an optimization pass for GlobalISel generic memory operations.
constexpr from_range_t from_range
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
DWARFExpression::Operation Op
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.
Definition BitVector.h:867
from_range_t()=default
constexpr T && operator()(T &&self) const noexcept
std::remove_cv_t< std::remove_reference_t< T > > type