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 //===----------------------------------------------------------------------===//
40 //     Features from C++23
41 //===----------------------------------------------------------------------===//
42 
43 // TODO: Remove this in favor of std::optional<T>::transform once we switch to
44 // C++23.
45 template <typename T, typename Function>
46 auto transformOptional(const std::optional<T> &O, const Function &F)
47     -> std::optional<decltype(F(*O))> {
48   if (O)
49     return F(*O);
50   return std::nullopt;
51 }
52 
53 // TODO: Remove this in favor of std::optional<T>::transform once we switch to
54 // C++23.
55 template <typename T, typename Function>
56 auto transformOptional(std::optional<T> &&O, const Function &F)
57     -> std::optional<decltype(F(*std::move(O)))> {
58   if (O)
59     return F(*std::move(O));
60   return std::nullopt;
61 }
62 
63 /// Returns underlying integer value of an enum. Backport of C++23
64 /// std::to_underlying.
65 template <typename Enum>
to_underlying(Enum E)66 [[nodiscard]] constexpr std::underlying_type_t<Enum> to_underlying(Enum E) {
67   return static_cast<std::underlying_type_t<Enum>>(E);
68 }
69 
70 } // namespace llvm
71 
72 #endif // LLVM_ADT_STLFORWARDCOMPAT_H
73