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