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
23namespace llvm {
24
25//===----------------------------------------------------------------------===//
26// Features from C++20
27//===----------------------------------------------------------------------===//
28
29template <typename T>
30struct remove_cvref // NOLINT(readability-identifier-naming)
31{
32 using type = std::remove_cv_t<std::remove_reference_t<T>>;
33};
34
35template <typename T>
36using 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.
45template <typename T, typename Function>
46auto 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.
55template <typename T, typename Function>
56auto 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.
65template <typename Enum>
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