clang 22.0.0git
CustomizableOptional.h
Go to the documentation of this file.
1//===- CustomizableOptional.h - Optional with custom storage ----*- 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#ifndef CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
10#define CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
11
12#include "llvm/ADT/Hashing.h"
13#include "llvm/Support/Compiler.h"
14#include "llvm/Support/type_traits.h"
15#include <cassert>
16#include <new>
17#include <optional>
18#include <utility>
19
20namespace clang {
21
22namespace optional_detail {
23template <typename> class OptionalStorage;
24} // namespace optional_detail
25
26// Optional type which internal storage can be specialized by providing
27// OptionalStorage. The interface follows std::optional.
28template <typename T> class CustomizableOptional {
30
31public:
32 using value_type = T;
33
34 constexpr CustomizableOptional() = default;
35 constexpr CustomizableOptional(std::nullopt_t) {}
36
37 constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {}
38 constexpr CustomizableOptional(const CustomizableOptional &O) = default;
39
40 constexpr CustomizableOptional(T &&y)
41 : Storage(std::in_place, std::move(y)) {}
43
44 template <typename... ArgTypes>
45 constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args)
46 : Storage(std::in_place, std::forward<ArgTypes>(Args)...) {}
47
48 // Allow conversion from std::optional<T>.
49 constexpr CustomizableOptional(const std::optional<T> &y)
51 constexpr CustomizableOptional(std::optional<T> &&y)
52 : CustomizableOptional(y ? std::move(*y) : CustomizableOptional()) {}
53
55 Storage = std::move(y);
56 return *this;
57 }
59
60 /// Create a new object by constructing it in place with the given arguments.
61 template <typename... ArgTypes> void emplace(ArgTypes &&...Args) {
62 Storage.emplace(std::forward<ArgTypes>(Args)...);
63 }
64
66 Storage = y;
67 return *this;
68 }
70
71 void reset() { Storage.reset(); }
72
73 constexpr explicit operator bool() const { return has_value(); }
74 constexpr bool has_value() const { return Storage.has_value(); }
75 constexpr const T *operator->() const { return &Storage.value(); }
76 T *operator->() { return &Storage.value(); }
77 constexpr const T &operator*() const & { return Storage.value(); }
78 T &operator*() & { return Storage.value(); }
79
80 template <typename U> constexpr T value_or(U &&alt) const & {
81 return has_value() ? operator*() : std::forward<U>(alt);
82 }
83
84 T &&operator*() && { return std::move(Storage.value()); }
85
86 template <typename U> T value_or(U &&alt) && {
87 return has_value() ? std::move(operator*()) : std::forward<U>(alt);
88 }
89};
90
91template <typename T>
93
94template <class T>
95llvm::hash_code hash_value(const CustomizableOptional<T> &O) {
96 return O ? llvm::hash_combine(true, *O) : llvm::hash_value(false);
97}
98
99template <typename T, typename U>
101 const CustomizableOptional<U> &Y) {
102 if (X && Y)
103 return *X == *Y;
104 return X.has_value() == Y.has_value();
105}
106
107template <typename T, typename U>
109 const CustomizableOptional<U> &Y) {
110 return !(X == Y);
111}
112
113template <typename T, typename U>
114constexpr bool operator<(const CustomizableOptional<T> &X,
115 const CustomizableOptional<U> &Y) {
116 if (X && Y)
117 return *X < *Y;
118 return X.has_value() < Y.has_value();
119}
120
121template <typename T, typename U>
123 const CustomizableOptional<U> &Y) {
124 return !(Y < X);
125}
126
127template <typename T, typename U>
128constexpr bool operator>(const CustomizableOptional<T> &X,
129 const CustomizableOptional<U> &Y) {
130 return Y < X;
131}
132
133template <typename T, typename U>
135 const CustomizableOptional<U> &Y) {
136 return !(X < Y);
137}
138
139template <typename T>
140constexpr bool operator==(const CustomizableOptional<T> &X, std::nullopt_t) {
141 return !X;
142}
143
144template <typename T>
145constexpr bool operator==(std::nullopt_t, const CustomizableOptional<T> &X) {
146 return X == std::nullopt;
147}
148
149template <typename T>
150constexpr bool operator!=(const CustomizableOptional<T> &X, std::nullopt_t) {
151 return !(X == std::nullopt);
152}
153
154template <typename T>
155constexpr bool operator!=(std::nullopt_t, const CustomizableOptional<T> &X) {
156 return X != std::nullopt;
157}
158
159template <typename T>
160constexpr bool operator<(const CustomizableOptional<T> &, std::nullopt_t) {
161 return false;
162}
163
164template <typename T>
165constexpr bool operator<(std::nullopt_t, const CustomizableOptional<T> &X) {
166 return X.has_value();
167}
168
169template <typename T>
170constexpr bool operator<=(const CustomizableOptional<T> &X, std::nullopt_t) {
171 return !(std::nullopt < X);
172}
173
174template <typename T>
175constexpr bool operator<=(std::nullopt_t, const CustomizableOptional<T> &X) {
176 return !(X < std::nullopt);
177}
178
179template <typename T>
180constexpr bool operator>(const CustomizableOptional<T> &X, std::nullopt_t) {
181 return std::nullopt < X;
182}
183
184template <typename T>
185constexpr bool operator>(std::nullopt_t, const CustomizableOptional<T> &X) {
186 return X < std::nullopt;
187}
188
189template <typename T>
190constexpr bool operator>=(const CustomizableOptional<T> &X, std::nullopt_t) {
191 return std::nullopt <= X;
192}
193
194template <typename T>
195constexpr bool operator>=(std::nullopt_t, const CustomizableOptional<T> &X) {
196 return X <= std::nullopt;
197}
198
199template <typename T>
200constexpr bool operator==(const CustomizableOptional<T> &X, const T &Y) {
201 return X && *X == Y;
202}
203
204template <typename T>
205constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) {
206 return Y && X == *Y;
207}
208
209template <typename T>
210constexpr bool operator!=(const CustomizableOptional<T> &X, const T &Y) {
211 return !(X == Y);
212}
213
214template <typename T>
215constexpr bool operator!=(const T &X, const CustomizableOptional<T> &Y) {
216 return !(X == Y);
217}
218
219template <typename T>
220constexpr bool operator<(const CustomizableOptional<T> &X, const T &Y) {
221 return !X || *X < Y;
222}
223
224template <typename T>
225constexpr bool operator<(const T &X, const CustomizableOptional<T> &Y) {
226 return Y && X < *Y;
227}
228
229template <typename T>
230constexpr bool operator<=(const CustomizableOptional<T> &X, const T &Y) {
231 return !(Y < X);
232}
233
234template <typename T>
235constexpr bool operator<=(const T &X, const CustomizableOptional<T> &Y) {
236 return !(Y < X);
237}
238
239template <typename T>
240constexpr bool operator>(const CustomizableOptional<T> &X, const T &Y) {
241 return Y < X;
242}
243
244template <typename T>
245constexpr bool operator>(const T &X, const CustomizableOptional<T> &Y) {
246 return Y < X;
247}
248
249template <typename T>
250constexpr bool operator>=(const CustomizableOptional<T> &X, const T &Y) {
251 return !(X < Y);
252}
253
254template <typename T>
255constexpr bool operator>=(const T &X, const CustomizableOptional<T> &Y) {
256 return !(X < Y);
257}
258
259} // namespace clang
260
261#endif // CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
#define X(type, name)
Definition: Value.h:145
constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args)
constexpr T value_or(U &&alt) const &
CustomizableOptional & operator=(const CustomizableOptional &O)=default
void emplace(ArgTypes &&...Args)
Create a new object by constructing it in place with the given arguments.
constexpr bool has_value() const
constexpr CustomizableOptional(const CustomizableOptional &O)=default
constexpr CustomizableOptional(std::nullopt_t)
constexpr const T * operator->() const
CustomizableOptional & operator=(const T &y)
constexpr CustomizableOptional(std::optional< T > &&y)
constexpr const T & operator*() const &
CustomizableOptional & operator=(CustomizableOptional &&O)=default
CustomizableOptional & operator=(T &&y)
constexpr CustomizableOptional(const std::optional< T > &y)
constexpr CustomizableOptional()=default
constexpr CustomizableOptional(CustomizableOptional &&O)=default
constexpr CustomizableOptional(const T &y)
Code completion in a.
#define bool
Definition: gpuintrin.h:32
The JSON file list parser is used to communicate input to InstallAPI.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition: CallGraph.h:204
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool operator!=(CanQual< T > x, CanQual< U > y)
bool operator<=(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
bool operator>(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
const FunctionProtoType * T
bool operator>=(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)