v8  10.1.124 (node 18.2.0)
V8 is Google's open source JavaScript engine
v8-maybe.h
Go to the documentation of this file.
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef INCLUDE_V8_MAYBE_H_
6 #define INCLUDE_V8_MAYBE_H_
7 
8 #include "v8-internal.h" // NOLINT(build/include_directory)
9 #include "v8config.h" // NOLINT(build/include_directory)
10 
11 namespace v8 {
12 
13 namespace api_internal {
14 // Called when ToChecked is called on an empty Maybe.
16 } // namespace api_internal
17 
18 /**
19  * A simple Maybe type, representing an object which may or may not have a
20  * value, see https://hackage.haskell.org/package/base/docs/Data-Maybe.html.
21  *
22  * If an API method returns a Maybe<>, the API method can potentially fail
23  * either because an exception is thrown, or because an exception is pending,
24  * e.g. because a previous API call threw an exception that hasn't been caught
25  * yet, or because a TerminateExecution exception was thrown. In that case, a
26  * "Nothing" value is returned.
27  */
28 template <class T>
29 class Maybe {
30  public:
31  V8_INLINE bool IsNothing() const { return !has_value_; }
32  V8_INLINE bool IsJust() const { return has_value_; }
33 
34  /**
35  * An alias for |FromJust|. Will crash if the Maybe<> is nothing.
36  */
37  V8_INLINE T ToChecked() const { return FromJust(); }
38 
39  /**
40  * Short-hand for ToChecked(), which doesn't return a value. To be used, where
41  * the actual value of the Maybe is not needed like Object::Set.
42  */
43  V8_INLINE void Check() const {
45  }
46 
47  /**
48  * Converts this Maybe<> to a value of type T. If this Maybe<> is
49  * nothing (empty), |false| is returned and |out| is left untouched.
50  */
51  V8_WARN_UNUSED_RESULT V8_INLINE bool To(T* out) const {
52  if (V8_LIKELY(IsJust())) *out = value_;
53  return IsJust();
54  }
55 
56  /**
57  * Converts this Maybe<> to a value of type T. If this Maybe<> is
58  * nothing (empty), V8 will crash the process.
59  */
60  V8_INLINE T FromJust() const {
62  return value_;
63  }
64 
65  /**
66  * Converts this Maybe<> to a value of type T, using a default value if this
67  * Maybe<> is nothing (empty).
68  */
69  V8_INLINE T FromMaybe(const T& default_value) const {
70  return has_value_ ? value_ : default_value;
71  }
72 
73  V8_INLINE bool operator==(const Maybe& other) const {
74  return (IsJust() == other.IsJust()) &&
75  (!IsJust() || FromJust() == other.FromJust());
76  }
77 
78  V8_INLINE bool operator!=(const Maybe& other) const {
79  return !operator==(other);
80  }
81 
82  private:
83  Maybe() : has_value_(false) {}
84  explicit Maybe(const T& t) : has_value_(true), value_(t) {}
85 
86  bool has_value_;
87  T value_;
88 
89  template <class U>
90  friend Maybe<U> Nothing();
91  template <class U>
92  friend Maybe<U> Just(const U& u);
93 };
94 
95 template <class T>
96 inline Maybe<T> Nothing() {
97  return Maybe<T>();
98 }
99 
100 template <class T>
101 inline Maybe<T> Just(const T& t) {
102  return Maybe<T>(t);
103 }
104 
105 // A template specialization of Maybe<T> for the case of T = void.
106 template <>
107 class Maybe<void> {
108  public:
109  V8_INLINE bool IsNothing() const { return !is_valid_; }
110  V8_INLINE bool IsJust() const { return is_valid_; }
111 
112  V8_INLINE bool operator==(const Maybe& other) const {
113  return IsJust() == other.IsJust();
114  }
115 
116  V8_INLINE bool operator!=(const Maybe& other) const {
117  return !operator==(other);
118  }
119 
120  private:
121  struct JustTag {};
122 
123  Maybe() : is_valid_(false) {}
124  explicit Maybe(JustTag) : is_valid_(true) {}
125 
126  bool is_valid_;
127 
128  template <class U>
129  friend Maybe<U> Nothing();
130  friend Maybe<void> JustVoid();
131 };
132 
133 inline Maybe<void> JustVoid() { return Maybe<void>(Maybe<void>::JustTag()); }
134 
135 } // namespace v8
136 
137 #endif // INCLUDE_V8_MAYBE_H_