xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/STLForwardCompat.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
23 namespace llvm {
24 
25 //===----------------------------------------------------------------------===//
26 //     Features from C++20
27 //===----------------------------------------------------------------------===//
28 
29 template <typename T>
30 struct remove_cvref // NOLINT(readability-identifier-naming)
31 {
32   using type = std::remove_cv_t<std::remove_reference_t<T>>;
33 };
34 
35 template <typename T>
36 using remove_cvref_t // NOLINT(readability-identifier-naming)
37     = typename llvm::remove_cvref<T>::type;
38 
39 // TODO: Remove this in favor of std::type_identity<T> once we switch to C++23.
40 template <typename T>
41 struct type_identity // NOLINT(readability-identifier-naming)
42 {
43   using type = T;
44 };
45 
46 // TODO: Remove this in favor of std::type_identity_t<T> once we switch to
47 // C++23.
48 template <typename T>
49 using type_identity_t // NOLINT(readability-identifier-naming)
50     = typename llvm::type_identity<T>::type;
51 
52 //===----------------------------------------------------------------------===//
53 //     Features from C++23
54 //===----------------------------------------------------------------------===//
55 
56 // TODO: Remove this in favor of std::optional<T>::transform once we switch to
57 // C++23.
58 template <typename T, typename Function>
59 auto transformOptional(const std::optional<T> &O, const Function &F)
60     -> std::optional<decltype(F(*O))> {
61   if (O)
62     return F(*O);
63   return std::nullopt;
64 }
65 
66 // TODO: Remove this in favor of std::optional<T>::transform once we switch to
67 // C++23.
68 template <typename T, typename Function>
69 auto transformOptional(std::optional<T> &&O, const Function &F)
70     -> std::optional<decltype(F(*std::move(O)))> {
71   if (O)
72     return F(*std::move(O));
73   return std::nullopt;
74 }
75 
76 /// Returns underlying integer value of an enum. Backport of C++23
77 /// std::to_underlying.
78 template <typename Enum>
to_underlying(Enum E)79 [[nodiscard]] constexpr std::underlying_type_t<Enum> to_underlying(Enum E) {
80   return static_cast<std::underlying_type_t<Enum>>(E);
81 }
82 
83 // A tag for constructors accepting ranges.
84 struct from_range_t {
85   explicit from_range_t() = default;
86 };
87 inline constexpr from_range_t from_range{};
88 } // namespace llvm
89 
90 #endif // LLVM_ADT_STLFORWARDCOMPAT_H
91