File indexing completed on 2026-09-15 09:13:52
0001
0002
0003
0004
0005 #ifndef INCLUDE_V8_MAYBE_H_
0006 #define INCLUDE_V8_MAYBE_H_
0007
0008 #include <type_traits>
0009 #include <utility>
0010
0011 #include "cppgc/internal/conditional-stack-allocated.h" // NOLINT(build/include_directory)
0012 #include "v8-internal.h" // NOLINT(build/include_directory)
0013 #include "v8config.h" // NOLINT(build/include_directory)
0014
0015 namespace v8 {
0016
0017 namespace internal {
0018 struct NullMaybeType {};
0019
0020 constexpr NullMaybeType kNullMaybe;
0021 }
0022
0023 namespace api_internal {
0024
0025 V8_EXPORT void FromJustIsNothing();
0026 }
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 template <class T>
0039 class Maybe : public cppgc::internal::ConditionalStackAllocatedBase<T> {
0040 public:
0041 constexpr Maybe() = default;
0042
0043 V8_INLINE Maybe(internal::NullMaybeType) {}
0044
0045 V8_INLINE bool IsNothing() const { return !has_value_; }
0046 V8_INLINE bool IsJust() const { return has_value_; }
0047
0048
0049
0050
0051
0052 V8_INLINE bool IsEmpty() const { return IsNothing(); }
0053
0054
0055
0056
0057 V8_INLINE T ToChecked() const { return FromJust(); }
0058
0059
0060
0061
0062
0063 V8_INLINE void Check() const {
0064 if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
0065 }
0066
0067
0068
0069
0070
0071 V8_WARN_UNUSED_RESULT V8_INLINE bool To(T* out) const {
0072 if (V8_LIKELY(IsJust())) *out = value_;
0073 return IsJust();
0074 }
0075
0076
0077
0078
0079
0080
0081 V8_WARN_UNUSED_RESULT V8_INLINE bool MoveTo(T* out) && {
0082 if (V8_LIKELY(IsJust())) *out = std::move(value_);
0083 return IsJust();
0084 }
0085
0086
0087
0088
0089
0090 V8_INLINE T FromJust() const& {
0091 if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
0092 return value_;
0093 }
0094
0095
0096
0097
0098
0099 V8_INLINE T FromJust() && {
0100 if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
0101 return std::move(value_);
0102 }
0103
0104
0105
0106
0107
0108 V8_INLINE T FromMaybe(const T& default_value) const {
0109 return has_value_ ? value_ : default_value;
0110 }
0111
0112 V8_INLINE bool operator==(const Maybe& other) const {
0113 return (IsJust() == other.IsJust()) &&
0114 (!IsJust() || FromJust() == other.FromJust());
0115 }
0116
0117 V8_INLINE bool operator!=(const Maybe& other) const {
0118 return !operator==(other);
0119 }
0120
0121 private:
0122 explicit Maybe(const T& t) : has_value_(true), value_(t) {}
0123 explicit Maybe(T&& t) : has_value_(true), value_(std::move(t)) {}
0124
0125 bool has_value_ = false;
0126 T value_;
0127
0128 template <class U>
0129 friend Maybe<U> Just(const U& u);
0130 template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
0131 friend Maybe<U> Just(U&& u);
0132 };
0133
0134 template <class T>
0135 inline constexpr Maybe<T> Nothing() {
0136 return {};
0137 }
0138
0139 template <class T>
0140 inline Maybe<T> Just(const T& t) {
0141 return Maybe<T>(t);
0142 }
0143
0144
0145
0146
0147 template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
0148 inline Maybe<T> Just(T&& t) {
0149 return Maybe<T>(std::move(t));
0150 }
0151
0152
0153 template <>
0154 class Maybe<void> {
0155 public:
0156 constexpr Maybe() = default;
0157 constexpr Maybe(internal::NullMaybeType) {}
0158
0159 V8_INLINE bool IsNothing() const { return !is_valid_; }
0160 V8_INLINE bool IsEmpty() const { return IsNothing(); }
0161 V8_INLINE bool IsJust() const { return is_valid_; }
0162
0163 V8_INLINE bool operator==(const Maybe& other) const {
0164 return IsJust() == other.IsJust();
0165 }
0166
0167 V8_INLINE bool operator!=(const Maybe& other) const {
0168 return !operator==(other);
0169 }
0170
0171 private:
0172 struct JustTag {};
0173
0174 explicit Maybe(JustTag) : is_valid_(true) {}
0175
0176 bool is_valid_ = false;
0177
0178 friend Maybe<void> JustVoid();
0179 };
0180
0181 inline Maybe<void> JustVoid() { return Maybe<void>(Maybe<void>::JustTag()); }
0182
0183 }
0184
0185 #endif