v8 14.1.146 (node 25.0.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
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 <type_traits>
9#include <utility>
10
11#include "cppgc/internal/conditional-stack-allocated.h" // NOLINT(build/include_directory)
12#include "v8-internal.h" // NOLINT(build/include_directory)
13#include "v8config.h" // NOLINT(build/include_directory)
14
15namespace v8 {
16
17namespace internal {
18struct NullMaybeType {};
19
21} // namespace internal
22
23namespace api_internal {
24// Called when ToChecked is called on an empty Maybe.
26} // namespace api_internal
27
28/**
29 * A simple Maybe type, representing an object which may or may not have a
30 * value, see https://hackage.haskell.org/package/base/docs/Data-Maybe.html.
31 *
32 * If an API method returns a Maybe<>, the API method can potentially fail
33 * either because an exception is thrown, or because an exception is pending,
34 * e.g. because a previous API call threw an exception that hasn't been caught
35 * yet, or because a TerminateExecution exception was thrown. In that case, a
36 * "Nothing" value is returned.
37 */
38template <class T>
39class Maybe : public cppgc::internal::ConditionalStackAllocatedBase<T> {
40 public:
41 constexpr Maybe() = default;
42
44
45 V8_INLINE bool IsNothing() const { return !has_value_; }
46 V8_INLINE bool IsJust() const { return has_value_; }
47
48 /**
49 * Same as IsNothing(). It's useful for unified handling of empty states
50 * with v8::MaybeLocal<T>.
51 */
52 V8_INLINE bool IsEmpty() const { return IsNothing(); }
53
54 /**
55 * An alias for |FromJust|. Will crash if the Maybe<> is nothing.
56 */
57 V8_INLINE T ToChecked() const { return FromJust(); }
58
59 /**
60 * Short-hand for ToChecked(), which doesn't return a value. To be used, where
61 * the actual value of the Maybe is not needed like Object::Set.
62 */
63 V8_INLINE void Check() const {
65 }
66
67 /**
68 * Converts this Maybe<> to a value of type T. If this Maybe<> is
69 * nothing (empty), |false| is returned and |out| is left untouched.
70 */
71 V8_WARN_UNUSED_RESULT V8_INLINE bool To(T* out) const {
72 if (V8_LIKELY(IsJust())) *out = value_;
73 return IsJust();
74 }
75
76 /**
77 * Converts this Maybe<> to a value of type T, moving out of it. If this
78 * Maybe<> is nothing (empty), |false| is returned and |out| is left
79 * untouched.
80 */
82 if (V8_LIKELY(IsJust())) *out = std::move(value_);
83 return IsJust();
84 }
85
86 /**
87 * Converts this Maybe<> to a value of type T. If this Maybe<> is
88 * nothing (empty), V8 will crash the process.
89 */
90 V8_INLINE T FromJust() const& {
92 return value_;
93 }
94
95 /**
96 * Converts this Maybe<> to a value of type T. If this Maybe<> is
97 * nothing (empty), V8 will crash the process.
98 */
101 return std::move(value_);
102 }
103
104 /**
105 * Converts this Maybe<> to a value of type T, using a default value if this
106 * Maybe<> is nothing (empty).
107 */
108 V8_INLINE T FromMaybe(const T& default_value) const {
109 return has_value_ ? value_ : default_value;
110 }
111
112 V8_INLINE bool operator==(const Maybe& other) const {
113 return (IsJust() == other.IsJust()) &&
114 (!IsJust() || FromJust() == other.FromJust());
115 }
116
117 V8_INLINE bool operator!=(const Maybe& other) const {
118 return !operator==(other);
119 }
120
121 private:
122 explicit Maybe(const T& t) : has_value_(true), value_(t) {}
123 explicit Maybe(T&& t) : has_value_(true), value_(std::move(t)) {}
124
125 bool has_value_ = false;
126 T value_;
127
128 template <class U>
129 friend Maybe<U> Just(const U& u);
130 template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
131 friend Maybe<U> Just(U&& u);
132};
133
134template <class T>
135inline constexpr Maybe<T> Nothing() {
136 return {};
137}
138
139template <class T>
140inline Maybe<T> Just(const T& t) {
141 return Maybe<T>(t);
142}
143
144// Don't use forwarding references here but instead use two overloads.
145// Forwarding references only work when type deduction takes place, which is not
146// the case for callsites such as Just<Type>(t).
147template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
148inline Maybe<T> Just(T&& t) {
149 return Maybe<T>(std::move(t));
150}
151
152// A template specialization of Maybe<T> for the case of T = void.
153template <>
154class Maybe<void> {
155 public:
156 constexpr Maybe() = default;
158
159 V8_INLINE bool IsNothing() const { return !is_valid_; }
160 V8_INLINE bool IsEmpty() const { return IsNothing(); }
161 V8_INLINE bool IsJust() const { return is_valid_; }
162
163 V8_INLINE bool operator==(const Maybe& other) const {
164 return IsJust() == other.IsJust();
165 }
166
167 V8_INLINE bool operator!=(const Maybe& other) const {
168 return !operator==(other);
169 }
170
171 private:
172 struct JustTag {};
173
174 explicit Maybe(JustTag) : is_valid_(true) {}
175
176 bool is_valid_ = false;
177
178 friend Maybe<void> JustVoid();
179};
180
181inline Maybe<void> JustVoid() { return Maybe<void>(Maybe<void>::JustTag()); }
182
183} // namespace v8
184
185#endif // INCLUDE_V8_MAYBE_H_
friend Maybe< void > JustVoid()
Definition v8-maybe.h:181
V8_INLINE bool IsEmpty() const
Definition v8-maybe.h:160
V8_INLINE bool IsNothing() const
Definition v8-maybe.h:159
V8_INLINE bool operator!=(const Maybe &other) const
Definition v8-maybe.h:167
constexpr Maybe()=default
constexpr Maybe(internal::NullMaybeType)
Definition v8-maybe.h:157
V8_INLINE bool operator==(const Maybe &other) const
Definition v8-maybe.h:163
V8_INLINE bool IsJust() const
Definition v8-maybe.h:161
V8_INLINE bool IsEmpty() const
Definition v8-maybe.h:52
V8_INLINE bool IsNothing() const
Definition v8-maybe.h:45
friend Maybe< U > Just(U &&u)
V8_INLINE bool operator!=(const Maybe &other) const
Definition v8-maybe.h:117
V8_INLINE T FromJust() &&
Definition v8-maybe.h:99
constexpr Maybe()=default
V8_WARN_UNUSED_RESULT V8_INLINE bool MoveTo(T *out) &&
Definition v8-maybe.h:81
V8_INLINE Maybe(internal::NullMaybeType)
Definition v8-maybe.h:43
V8_WARN_UNUSED_RESULT V8_INLINE bool To(T *out) const
Definition v8-maybe.h:71
V8_INLINE void Check() const
Definition v8-maybe.h:63
friend Maybe< U > Just(const U &u)
V8_INLINE T FromJust() const &
Definition v8-maybe.h:90
V8_INLINE bool operator==(const Maybe &other) const
Definition v8-maybe.h:112
V8_INLINE bool IsJust() const
Definition v8-maybe.h:46
V8_INLINE T ToChecked() const
Definition v8-maybe.h:57
V8_INLINE T FromMaybe(const T &default_value) const
Definition v8-maybe.h:108
V8_EXPORT void FromJustIsNothing()
constexpr NullMaybeType kNullMaybe
Definition v8-maybe.h:20
Maybe< T > Just(const T &t)
Definition v8-maybe.h:140
constexpr Maybe< T > Nothing()
Definition v8-maybe.h:135
Maybe< T > Just(T &&t)
Definition v8-maybe.h:148
#define V8_EXPORT
Definition v8config.h:860
#define V8_INLINE
Definition v8config.h:513
#define V8_LIKELY(condition)
Definition v8config.h:674
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:684
#define V8_UNLIKELY(condition)
Definition v8config.h:673