File indexing completed on 2026-05-10 08:36:48
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
0010 #define CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
0011
0012 #include "llvm/ADT/Hashing.h"
0013 #include "llvm/Support/Compiler.h"
0014 #include "llvm/Support/type_traits.h"
0015 #include <cassert>
0016 #include <new>
0017 #include <optional>
0018 #include <utility>
0019
0020 namespace clang {
0021
0022 namespace optional_detail {
0023 template <typename> class OptionalStorage;
0024 }
0025
0026
0027
0028 template <typename T> class CustomizableOptional {
0029 optional_detail::OptionalStorage<T> Storage;
0030
0031 public:
0032 using value_type = T;
0033
0034 constexpr CustomizableOptional() = default;
0035 constexpr CustomizableOptional(std::nullopt_t) {}
0036
0037 constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {}
0038 constexpr CustomizableOptional(const CustomizableOptional &O) = default;
0039
0040 constexpr CustomizableOptional(T &&y)
0041 : Storage(std::in_place, std::move(y)) {}
0042 constexpr CustomizableOptional(CustomizableOptional &&O) = default;
0043
0044 template <typename... ArgTypes>
0045 constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args)
0046 : Storage(std::in_place, std::forward<ArgTypes>(Args)...) {}
0047
0048
0049 constexpr CustomizableOptional(const std::optional<T> &y)
0050 : CustomizableOptional(y ? *y : CustomizableOptional()) {}
0051 constexpr CustomizableOptional(std::optional<T> &&y)
0052 : CustomizableOptional(y ? std::move(*y) : CustomizableOptional()) {}
0053
0054 CustomizableOptional &operator=(T &&y) {
0055 Storage = std::move(y);
0056 return *this;
0057 }
0058 CustomizableOptional &operator=(CustomizableOptional &&O) = default;
0059
0060
0061 template <typename... ArgTypes> void emplace(ArgTypes &&...Args) {
0062 Storage.emplace(std::forward<ArgTypes>(Args)...);
0063 }
0064
0065 CustomizableOptional &operator=(const T &y) {
0066 Storage = y;
0067 return *this;
0068 }
0069 CustomizableOptional &operator=(const CustomizableOptional &O) = default;
0070
0071 void reset() { Storage.reset(); }
0072
0073 LLVM_DEPRECATED("Use &*X instead.", "&*X")
0074 constexpr const T *getPointer() const { return &Storage.value(); }
0075 LLVM_DEPRECATED("Use &*X instead.", "&*X")
0076 T *getPointer() { return &Storage.value(); }
0077 LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
0078 constexpr const T &value() const & { return Storage.value(); }
0079 LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
0080 T &value() & { return Storage.value(); }
0081
0082 constexpr explicit operator bool() const { return has_value(); }
0083 constexpr bool has_value() const { return Storage.has_value(); }
0084 constexpr const T *operator->() const { return &Storage.value(); }
0085 T *operator->() { return &Storage.value(); }
0086 constexpr const T &operator*() const & { return Storage.value(); }
0087 T &operator*() & { return Storage.value(); }
0088
0089 template <typename U> constexpr T value_or(U &&alt) const & {
0090 return has_value() ? operator*() : std::forward<U>(alt);
0091 }
0092
0093 LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
0094 T &&value() && { return std::move(Storage.value()); }
0095 T &&operator*() && { return std::move(Storage.value()); }
0096
0097 template <typename U> T value_or(U &&alt) && {
0098 return has_value() ? std::move(operator*()) : std::forward<U>(alt);
0099 }
0100 };
0101
0102 template <typename T>
0103 CustomizableOptional(const T &) -> CustomizableOptional<T>;
0104
0105 template <class T>
0106 llvm::hash_code hash_value(const CustomizableOptional<T> &O) {
0107 return O ? llvm::hash_combine(true, *O) : llvm::hash_value(false);
0108 }
0109
0110 template <typename T, typename U>
0111 constexpr bool operator==(const CustomizableOptional<T> &X,
0112 const CustomizableOptional<U> &Y) {
0113 if (X && Y)
0114 return *X == *Y;
0115 return X.has_value() == Y.has_value();
0116 }
0117
0118 template <typename T, typename U>
0119 constexpr bool operator!=(const CustomizableOptional<T> &X,
0120 const CustomizableOptional<U> &Y) {
0121 return !(X == Y);
0122 }
0123
0124 template <typename T, typename U>
0125 constexpr bool operator<(const CustomizableOptional<T> &X,
0126 const CustomizableOptional<U> &Y) {
0127 if (X && Y)
0128 return *X < *Y;
0129 return X.has_value() < Y.has_value();
0130 }
0131
0132 template <typename T, typename U>
0133 constexpr bool operator<=(const CustomizableOptional<T> &X,
0134 const CustomizableOptional<U> &Y) {
0135 return !(Y < X);
0136 }
0137
0138 template <typename T, typename U>
0139 constexpr bool operator>(const CustomizableOptional<T> &X,
0140 const CustomizableOptional<U> &Y) {
0141 return Y < X;
0142 }
0143
0144 template <typename T, typename U>
0145 constexpr bool operator>=(const CustomizableOptional<T> &X,
0146 const CustomizableOptional<U> &Y) {
0147 return !(X < Y);
0148 }
0149
0150 template <typename T>
0151 constexpr bool operator==(const CustomizableOptional<T> &X, std::nullopt_t) {
0152 return !X;
0153 }
0154
0155 template <typename T>
0156 constexpr bool operator==(std::nullopt_t, const CustomizableOptional<T> &X) {
0157 return X == std::nullopt;
0158 }
0159
0160 template <typename T>
0161 constexpr bool operator!=(const CustomizableOptional<T> &X, std::nullopt_t) {
0162 return !(X == std::nullopt);
0163 }
0164
0165 template <typename T>
0166 constexpr bool operator!=(std::nullopt_t, const CustomizableOptional<T> &X) {
0167 return X != std::nullopt;
0168 }
0169
0170 template <typename T>
0171 constexpr bool operator<(const CustomizableOptional<T> &, std::nullopt_t) {
0172 return false;
0173 }
0174
0175 template <typename T>
0176 constexpr bool operator<(std::nullopt_t, const CustomizableOptional<T> &X) {
0177 return X.has_value();
0178 }
0179
0180 template <typename T>
0181 constexpr bool operator<=(const CustomizableOptional<T> &X, std::nullopt_t) {
0182 return !(std::nullopt < X);
0183 }
0184
0185 template <typename T>
0186 constexpr bool operator<=(std::nullopt_t, const CustomizableOptional<T> &X) {
0187 return !(X < std::nullopt);
0188 }
0189
0190 template <typename T>
0191 constexpr bool operator>(const CustomizableOptional<T> &X, std::nullopt_t) {
0192 return std::nullopt < X;
0193 }
0194
0195 template <typename T>
0196 constexpr bool operator>(std::nullopt_t, const CustomizableOptional<T> &X) {
0197 return X < std::nullopt;
0198 }
0199
0200 template <typename T>
0201 constexpr bool operator>=(const CustomizableOptional<T> &X, std::nullopt_t) {
0202 return std::nullopt <= X;
0203 }
0204
0205 template <typename T>
0206 constexpr bool operator>=(std::nullopt_t, const CustomizableOptional<T> &X) {
0207 return X <= std::nullopt;
0208 }
0209
0210 template <typename T>
0211 constexpr bool operator==(const CustomizableOptional<T> &X, const T &Y) {
0212 return X && *X == Y;
0213 }
0214
0215 template <typename T>
0216 constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) {
0217 return Y && X == *Y;
0218 }
0219
0220 template <typename T>
0221 constexpr bool operator!=(const CustomizableOptional<T> &X, const T &Y) {
0222 return !(X == Y);
0223 }
0224
0225 template <typename T>
0226 constexpr bool operator!=(const T &X, const CustomizableOptional<T> &Y) {
0227 return !(X == Y);
0228 }
0229
0230 template <typename T>
0231 constexpr bool operator<(const CustomizableOptional<T> &X, const T &Y) {
0232 return !X || *X < Y;
0233 }
0234
0235 template <typename T>
0236 constexpr bool operator<(const T &X, const CustomizableOptional<T> &Y) {
0237 return Y && X < *Y;
0238 }
0239
0240 template <typename T>
0241 constexpr bool operator<=(const CustomizableOptional<T> &X, const T &Y) {
0242 return !(Y < X);
0243 }
0244
0245 template <typename T>
0246 constexpr bool operator<=(const T &X, const CustomizableOptional<T> &Y) {
0247 return !(Y < X);
0248 }
0249
0250 template <typename T>
0251 constexpr bool operator>(const CustomizableOptional<T> &X, const T &Y) {
0252 return Y < X;
0253 }
0254
0255 template <typename T>
0256 constexpr bool operator>(const T &X, const CustomizableOptional<T> &Y) {
0257 return Y < X;
0258 }
0259
0260 template <typename T>
0261 constexpr bool operator>=(const CustomizableOptional<T> &X, const T &Y) {
0262 return !(X < Y);
0263 }
0264
0265 template <typename T>
0266 constexpr bool operator>=(const T &X, const CustomizableOptional<T> &Y) {
0267 return !(X < Y);
0268 }
0269
0270 }
0271
0272 #endif