LLVM  15.0.0git
Optional.h
Go to the documentation of this file.
1 //===- Optional.h - Simple variant for passing optional values --*- 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 provides Optional, a template class modeled in the spirit of
11 /// OCaml's 'opt' variant. The idea is to strongly type whether or not
12 /// a value can be optional.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_ADT_OPTIONAL_H
17 #define LLVM_ADT_OPTIONAL_H
18 
19 #include "llvm/ADT/Hashing.h"
20 #include "llvm/ADT/None.h"
22 #include "llvm/Support/Compiler.h"
24 #include <cassert>
25 #include <new>
26 #include <utility>
27 
28 namespace llvm {
29 
30 class raw_ostream;
31 
32 namespace optional_detail {
33 
34 /// Storage for any type.
35 //
36 // The specialization condition intentionally uses
37 // llvm::is_trivially_{copy/move}_constructible instead of
38 // std::is_trivially_{copy/move}_constructible. GCC versions prior to 7.4 may
39 // instantiate the copy/move constructor of `T` when
40 // std::is_trivially_{copy/move}_constructible is instantiated. This causes
41 // compilation to fail if we query the trivially copy/move constructible
42 // property of a class which is not copy/move constructible.
43 //
44 // The current implementation of OptionalStorage insists that in order to use
45 // the trivial specialization, the value_type must be trivially copy
46 // constructible and trivially copy assignable due to =default implementations
47 // of the copy/move constructor/assignment. It does not follow that this is
48 // necessarily the case std::is_trivially_copyable is true (hence the expanded
49 // specialization condition).
50 //
51 // The move constructible / assignable conditions emulate the remaining behavior
52 // of std::is_trivially_copyable.
53 template <typename T,
55  std::is_trivially_copy_assignable<T>::value &&
57  !std::is_move_constructible<T>::value) &&
58  (std::is_trivially_move_assignable<T>::value ||
59  !std::is_move_assignable<T>::value))>
61  union {
62  char empty;
64  };
65  bool hasVal = false;
66 
67 public:
68  ~OptionalStorage() { reset(); }
69 
70  constexpr OptionalStorage() noexcept : empty() {}
71 
72  constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
73  if (other.hasValue()) {
74  emplace(other.value);
75  }
76  }
78  if (other.hasValue()) {
79  emplace(std::move(other.value));
80  }
81  }
82 
83  template <class... Args>
84  constexpr explicit OptionalStorage(in_place_t, Args &&...args)
85  : value(std::forward<Args>(args)...), hasVal(true) {}
86 
87  void reset() noexcept {
88  if (hasVal) {
89  value.~T();
90  hasVal = false;
91  }
92  }
93 
94  constexpr bool hasValue() const noexcept { return hasVal; }
95 
96  T &getValue() &noexcept {
97  assert(hasVal);
98  return value;
99  }
100  constexpr T const &getValue() const &noexcept {
101  assert(hasVal);
102  return value;
103  }
104  T &&getValue() &&noexcept {
105  assert(hasVal);
106  return std::move(value);
107  }
108 
109  template <class... Args> void emplace(Args &&...args) {
110  reset();
111  ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
112  hasVal = true;
113  }
114 
116  if (hasValue()) {
117  value = y;
118  } else {
119  ::new ((void *)std::addressof(value)) T(y);
120  hasVal = true;
121  }
122  return *this;
123  }
125  if (hasValue()) {
126  value = std::move(y);
127  } else {
128  ::new ((void *)std::addressof(value)) T(std::move(y));
129  hasVal = true;
130  }
131  return *this;
132  }
133 
135  if (other.hasValue()) {
136  if (hasValue()) {
137  value = other.value;
138  } else {
139  ::new ((void *)std::addressof(value)) T(other.value);
140  hasVal = true;
141  }
142  } else {
143  reset();
144  }
145  return *this;
146  }
147 
149  if (other.hasValue()) {
150  if (hasValue()) {
151  value = std::move(other.value);
152  } else {
153  ::new ((void *)std::addressof(value)) T(std::move(other.value));
154  hasVal = true;
155  }
156  } else {
157  reset();
158  }
159  return *this;
160  }
161 };
162 
163 template <typename T> class OptionalStorage<T, true> {
164  union {
165  char empty;
167  };
168  bool hasVal = false;
169 
170 public:
171  ~OptionalStorage() = default;
172 
173  constexpr OptionalStorage() noexcept : empty{} {}
174 
175  constexpr OptionalStorage(OptionalStorage const &other) = default;
176  constexpr OptionalStorage(OptionalStorage &&other) = default;
177 
178  OptionalStorage &operator=(OptionalStorage const &other) = default;
179  OptionalStorage &operator=(OptionalStorage &&other) = default;
180 
181  template <class... Args>
182  constexpr explicit OptionalStorage(in_place_t, Args &&... args)
183  : value(std::forward<Args>(args)...), hasVal(true) {}
184 
185  void reset() noexcept {
186  if (hasVal) {
187  value.~T();
188  hasVal = false;
189  }
190  }
191 
192  constexpr bool hasValue() const noexcept { return hasVal; }
193 
194  T &getValue() &noexcept {
195  assert(hasVal);
196  return value;
197  }
198  constexpr T const &getValue() const &noexcept {
199  assert(hasVal);
200  return value;
201  }
202  T &&getValue() &&noexcept {
203  assert(hasVal);
204  return std::move(value);
205  }
206 
207  template <class... Args> void emplace(Args &&...args) {
208  reset();
209  ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
210  hasVal = true;
211  }
212 
214  if (hasValue()) {
215  value = y;
216  } else {
217  ::new ((void *)std::addressof(value)) T(y);
218  hasVal = true;
219  }
220  return *this;
221  }
223  if (hasValue()) {
224  value = std::move(y);
225  } else {
226  ::new ((void *)std::addressof(value)) T(std::move(y));
227  hasVal = true;
228  }
229  return *this;
230  }
231 };
232 
233 } // namespace optional_detail
234 
235 template <typename T> class Optional {
236  optional_detail::OptionalStorage<T> Storage;
237 
238 public:
239  using value_type = T;
240 
241  constexpr Optional() = default;
242  constexpr Optional(NoneType) {}
243 
244  constexpr Optional(const T &y) : Storage(in_place, y) {}
245  constexpr Optional(const Optional &O) = default;
246 
247  constexpr Optional(T &&y) : Storage(in_place, std::move(y)) {}
248  constexpr Optional(Optional &&O) = default;
249 
250  template <typename... ArgTypes>
251  constexpr Optional(in_place_t, ArgTypes &&...Args)
252  : Storage(in_place, std::forward<ArgTypes>(Args)...) {}
253 
255  Storage = std::move(y);
256  return *this;
257  }
258  Optional &operator=(Optional &&O) = default;
259 
260  /// Create a new object by constructing it in place with the given arguments.
261  template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
262  Storage.emplace(std::forward<ArgTypes>(Args)...);
263  }
264 
265  static constexpr Optional create(const T *y) {
266  return y ? Optional(*y) : Optional();
267  }
268 
269  Optional &operator=(const T &y) {
270  Storage = y;
271  return *this;
272  }
273  Optional &operator=(const Optional &O) = default;
274 
275  void reset() { Storage.reset(); }
276 
277  constexpr const T *getPointer() const { return &Storage.getValue(); }
278  T *getPointer() { return &Storage.getValue(); }
279  constexpr const T &getValue() const & { return Storage.getValue(); }
280  T &getValue() & { return Storage.getValue(); }
281 
282  constexpr explicit operator bool() const { return hasValue(); }
283  constexpr bool hasValue() const { return Storage.hasValue(); }
284  constexpr const T *operator->() const { return getPointer(); }
285  T *operator->() { return getPointer(); }
286  constexpr const T &operator*() const & { return getValue(); }
287  T &operator*() & { return getValue(); }
288 
289  template <typename U> constexpr T getValueOr(U &&value) const & {
290  return hasValue() ? getValue() : std::forward<U>(value);
291  }
292 
293  /// Apply a function to the value if present; otherwise return None.
294  template <class Function>
295  auto map(const Function &F) const & -> Optional<decltype(F(getValue()))> {
296  if (*this)
297  return F(getValue());
298  return None;
299  }
300 
301  T &&getValue() && { return std::move(Storage.getValue()); }
302  T &&operator*() && { return std::move(Storage.getValue()); }
303 
304  template <typename U> T getValueOr(U &&value) && {
305  return hasValue() ? std::move(getValue()) : std::forward<U>(value);
306  }
307 
308  /// Apply a function to the value if present; otherwise return None.
309  template <class Function>
310  auto map(const Function &F)
311  && -> Optional<decltype(F(std::move(*this).getValue()))> {
312  if (*this)
313  return F(std::move(*this).getValue());
314  return None;
315  }
316 };
317 
318 template <class T> llvm::hash_code hash_value(const Optional<T> &O) {
319  return O ? hash_combine(true, *O) : hash_value(false);
320 }
321 
322 template <typename T, typename U>
323 constexpr bool operator==(const Optional<T> &X, const Optional<U> &Y) {
324  if (X && Y)
325  return *X == *Y;
326  return X.hasValue() == Y.hasValue();
327 }
328 
329 template <typename T, typename U>
330 constexpr bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
331  return !(X == Y);
332 }
333 
334 template <typename T, typename U>
335 constexpr bool operator<(const Optional<T> &X, const Optional<U> &Y) {
336  if (X && Y)
337  return *X < *Y;
338  return X.hasValue() < Y.hasValue();
339 }
340 
341 template <typename T, typename U>
342 constexpr bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
343  return !(Y < X);
344 }
345 
346 template <typename T, typename U>
347 constexpr bool operator>(const Optional<T> &X, const Optional<U> &Y) {
348  return Y < X;
349 }
350 
351 template <typename T, typename U>
352 constexpr bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
353  return !(X < Y);
354 }
355 
356 template <typename T>
357 constexpr bool operator==(const Optional<T> &X, NoneType) {
358  return !X;
359 }
360 
361 template <typename T>
362 constexpr bool operator==(NoneType, const Optional<T> &X) {
363  return X == None;
364 }
365 
366 template <typename T>
367 constexpr bool operator!=(const Optional<T> &X, NoneType) {
368  return !(X == None);
369 }
370 
371 template <typename T>
372 constexpr bool operator!=(NoneType, const Optional<T> &X) {
373  return X != None;
374 }
375 
376 template <typename T> constexpr bool operator<(const Optional<T> &, NoneType) {
377  return false;
378 }
379 
380 template <typename T> constexpr bool operator<(NoneType, const Optional<T> &X) {
381  return X.hasValue();
382 }
383 
384 template <typename T>
385 constexpr bool operator<=(const Optional<T> &X, NoneType) {
386  return !(None < X);
387 }
388 
389 template <typename T>
390 constexpr bool operator<=(NoneType, const Optional<T> &X) {
391  return !(X < None);
392 }
393 
394 template <typename T> constexpr bool operator>(const Optional<T> &X, NoneType) {
395  return None < X;
396 }
397 
398 template <typename T> constexpr bool operator>(NoneType, const Optional<T> &X) {
399  return X < None;
400 }
401 
402 template <typename T>
403 constexpr bool operator>=(const Optional<T> &X, NoneType) {
404  return None <= X;
405 }
406 
407 template <typename T>
408 constexpr bool operator>=(NoneType, const Optional<T> &X) {
409  return X <= None;
410 }
411 
412 template <typename T>
413 constexpr bool operator==(const Optional<T> &X, const T &Y) {
414  return X && *X == Y;
415 }
416 
417 template <typename T>
418 constexpr bool operator==(const T &X, const Optional<T> &Y) {
419  return Y && X == *Y;
420 }
421 
422 template <typename T>
423 constexpr bool operator!=(const Optional<T> &X, const T &Y) {
424  return !(X == Y);
425 }
426 
427 template <typename T>
428 constexpr bool operator!=(const T &X, const Optional<T> &Y) {
429  return !(X == Y);
430 }
431 
432 template <typename T>
433 constexpr bool operator<(const Optional<T> &X, const T &Y) {
434  return !X || *X < Y;
435 }
436 
437 template <typename T>
438 constexpr bool operator<(const T &X, const Optional<T> &Y) {
439  return Y && X < *Y;
440 }
441 
442 template <typename T>
443 constexpr bool operator<=(const Optional<T> &X, const T &Y) {
444  return !(Y < X);
445 }
446 
447 template <typename T>
448 constexpr bool operator<=(const T &X, const Optional<T> &Y) {
449  return !(Y < X);
450 }
451 
452 template <typename T>
453 constexpr bool operator>(const Optional<T> &X, const T &Y) {
454  return Y < X;
455 }
456 
457 template <typename T>
458 constexpr bool operator>(const T &X, const Optional<T> &Y) {
459  return Y < X;
460 }
461 
462 template <typename T>
463 constexpr bool operator>=(const Optional<T> &X, const T &Y) {
464  return !(X < Y);
465 }
466 
467 template <typename T>
468 constexpr bool operator>=(const T &X, const Optional<T> &Y) {
469  return !(X < Y);
470 }
471 
472 raw_ostream &operator<<(raw_ostream &OS, NoneType);
473 
474 template <typename T, typename = decltype(std::declval<raw_ostream &>()
475  << std::declval<const T &>())>
476 raw_ostream &operator<<(raw_ostream &OS, const Optional<T> &O) {
477  if (O)
478  OS << *O;
479  else
480  OS << None;
481  return OS;
482 }
483 
484 } // end namespace llvm
485 
486 #endif // LLVM_ADT_OPTIONAL_H
llvm::Optional::map
auto map(const Function &F) &&-> Optional< decltype(F(std::move(*this).getValue()))>
Apply a function to the value if present; otherwise return None.
Definition: Optional.h:310
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage(OptionalStorage &&other)
Definition: Optional.h:77
llvm::Optional::operator*
T && operator*() &&
Definition: Optional.h:302
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::Optional::Optional
constexpr Optional(NoneType)
Definition: Optional.h:242
llvm::Function
Definition: Function.h:60
llvm::operator<=
bool operator<=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:337
llvm::Optional::Optional
constexpr Optional(const T &y)
Definition: Optional.h:244
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(OptionalStorage &&other)
Definition: Optional.h:148
llvm::optional_detail::OptionalStorage::value
T value
Definition: Optional.h:63
llvm::Optional::operator=
Optional & operator=(T &&y)
Definition: Optional.h:254
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1909
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage() noexcept
Definition: Optional.h:70
llvm::Optional::getValue
T & getValue() &
Definition: Optional.h:280
llvm::operator!=
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2004
llvm::optional_detail::OptionalStorage< T, true >::getValue
T & getValue() &noexcept
Definition: Optional.h:194
llvm::Optional
Definition: APInt.h:33
T
#define T
Definition: Mips16ISelLowering.cpp:341
Hashing.h
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage(in_place_t, Args &&...args)
Definition: Optional.h:84
llvm::hash_value
hash_code hash_value(const APFloat &Arg)
See friend declarations above.
Definition: APFloat.cpp:4821
new
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
Definition: README.txt:125
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::Optional::getPointer
constexpr const T * getPointer() const
Definition: Optional.h:277
llvm::Optional::hasValue
constexpr bool hasValue() const
Definition: Optional.h:283
llvm::Optional::getValueOr
T getValueOr(U &&value) &&
Definition: Optional.h:304
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
llvm::Optional::getValueOr
constexpr T getValueOr(U &&value) const &
Definition: Optional.h:289
llvm::optional_detail::OptionalStorage< T, true >::emplace
void emplace(Args &&...args)
Definition: Optional.h:207
llvm::Optional::operator*
T & operator*() &
Definition: Optional.h:287
llvm::Optional::map
auto map(const Function &F) const &-> Optional< decltype(F(getValue()))>
Apply a function to the value if present; otherwise return None.
Definition: Optional.h:295
llvm::optional_detail::OptionalStorage::OptionalStorage
constexpr OptionalStorage(OptionalStorage const &other)
Definition: Optional.h:72
STLForwardCompat.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::Optional::create
static constexpr Optional create(const T *y)
Definition: Optional.h:265
llvm::None
const NoneType None
Definition: None.h:24
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::Optional::Optional
constexpr Optional(T &&y)
Definition: Optional.h:247
llvm::operator>=
bool operator>=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:338
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:239
llvm::optional_detail::OptionalStorage::getValue
T & getValue() &noexcept
Definition: Optional.h:96
uint64_t
llvm::optional_detail::OptionalStorage< T, true >::OptionalStorage
constexpr OptionalStorage(in_place_t, Args &&... args)
Definition: Optional.h:182
llvm::Optional::reset
void reset()
Definition: Optional.h:275
llvm::Optional::getValue
T && getValue() &&
Definition: Optional.h:301
llvm::NoneType
NoneType
A simple null object to allow implicit construction of Optional<T> and similar types without having t...
Definition: None.h:23
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::Optional::emplace
void emplace(ArgTypes &&... Args)
Create a new object by constructing it in place with the given arguments.
Definition: Optional.h:261
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:339
llvm::Optional::getPointer
T * getPointer()
Definition: Optional.h:278
llvm::optional_detail::OptionalStorage< T, true >::hasValue
constexpr bool hasValue() const noexcept
Definition: Optional.h:192
llvm::Optional::Optional
constexpr Optional(in_place_t, ArgTypes &&...Args)
Definition: Optional.h:251
llvm::optional_detail::OptionalStorage< T, true >::getValue
constexpr const T & getValue() const &noexcept
Definition: Optional.h:198
llvm::is_trivially_move_constructible
An implementation of std::is_trivially_move_constructible since we have users with STLs that don't ye...
Definition: type_traits.h:109
llvm::optional_detail::OptionalStorage::~OptionalStorage
~OptionalStorage()
Definition: Optional.h:68
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1663
llvm::Optional::getValue
constexpr const T & getValue() const &
Definition: Optional.h:279
llvm::operator==
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:2002
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(T const &y)
Definition: Optional.h:115
llvm::in_place
constexpr in_place_t in_place
Definition: STLForwardCompat.h:53
llvm::optional_detail::OptionalStorage< T, true >::OptionalStorage
constexpr OptionalStorage() noexcept
Definition: Optional.h:173
None.h
llvm::optional_detail::OptionalStorage::getValue
T && getValue() &&noexcept
Definition: Optional.h:104
llvm::optional_detail::OptionalStorage::reset
void reset() noexcept
Definition: Optional.h:87
Compiler.h
llvm::is_trivially_copy_constructible
An implementation of std::is_trivially_copy_constructible since we have users with STLs that don't ye...
Definition: type_traits.h:98
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(OptionalStorage const &other)
Definition: Optional.h:134
llvm::Optional::operator->
constexpr const T * operator->() const
Definition: Optional.h:284
llvm::optional_detail::OptionalStorage::hasValue
constexpr bool hasValue() const noexcept
Definition: Optional.h:94
llvm::optional_detail::OptionalStorage< T, true >::operator=
OptionalStorage & operator=(T &&y)
Definition: Optional.h:222
llvm::cl::Optional
@ Optional
Definition: CommandLine.h:115
llvm::optional_detail::OptionalStorage::getValue
constexpr const T & getValue() const &noexcept
Definition: Optional.h:100
llvm::empty
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Definition: STLExtras.h:268
std
Definition: BitVector.h:851
type_traits.h
llvm::optional_detail::OptionalStorage< T, true >::value
T value
Definition: Optional.h:166
llvm::optional_detail::OptionalStorage::operator=
OptionalStorage & operator=(T &&y)
Definition: Optional.h:124
llvm::Optional::operator->
T * operator->()
Definition: Optional.h:285
y
into llvm powi allowing the code generator to produce balanced multiplication trees the intrinsic needs to be extended to support and second the code generator needs to be enhanced to lower these to multiplication trees Interesting testcase for add shift mul int y
Definition: README.txt:61
llvm::optional_detail::OptionalStorage::empty
char empty
Definition: Optional.h:62
llvm::in_place_t
Definition: STLForwardCompat.h:48
llvm::optional_detail::OptionalStorage::emplace
void emplace(Args &&...args)
Definition: Optional.h:109
llvm::hash_combine
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:605
llvm::Optional::operator=
Optional & operator=(const T &y)
Definition: Optional.h:269
llvm::operator>
bool operator>(int64_t V1, const APSInt &V2)
Definition: APSInt.h:340
llvm::optional_detail::OptionalStorage< T, true >::empty
char empty
Definition: Optional.h:165
llvm::optional_detail::OptionalStorage< T, true >::getValue
T && getValue() &&noexcept
Definition: Optional.h:202
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::optional_detail::OptionalStorage< T, true >::reset
void reset() noexcept
Definition: Optional.h:185
llvm::Optional::Optional
constexpr Optional()=default
llvm::optional_detail::OptionalStorage< T, true >::operator=
OptionalStorage & operator=(T const &y)
Definition: Optional.h:213
llvm::optional_detail::OptionalStorage
Storage for any type.
Definition: Optional.h:60
llvm::hash_code
An opaque object representing a hash code.
Definition: Hashing.h:73
llvm::Optional::operator*
constexpr const T & operator*() const &
Definition: Optional.h:286