xref: /third_party/node/deps/v8/include/v8-maybe.h (revision 1cb0ef41)
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
11namespace v8 {
12
13namespace api_internal {
14// Called when ToChecked is called on an empty Maybe.
15V8_EXPORT void FromJustIsNothing();
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 */
28template <class T>
29class 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 {
44    if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
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 {
61    if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
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
95template <class T>
96inline Maybe<T> Nothing() {
97  return Maybe<T>();
98}
99
100template <class T>
101inline 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.
106template <>
107class 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
133inline Maybe<void> JustVoid() { return Maybe<void>(Maybe<void>::JustTag()); }
134
135}  // namespace v8
136
137#endif  // INCLUDE_V8_MAYBE_H_
138