File indexing completed on 2025-02-21 10:05:25
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 "v8-internal.h" // NOLINT(build/include_directory)
0012 #include "v8config.h" // NOLINT(build/include_directory)
0013
0014 namespace v8 {
0015
0016 namespace api_internal {
0017
0018 V8_EXPORT void FromJustIsNothing();
0019 }
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 template <class T>
0032 class Maybe {
0033 public:
0034 V8_INLINE bool IsNothing() const { return !has_value_; }
0035 V8_INLINE bool IsJust() const { return has_value_; }
0036
0037
0038
0039
0040 V8_INLINE T ToChecked() const { return FromJust(); }
0041
0042
0043
0044
0045
0046 V8_INLINE void Check() const {
0047 if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
0048 }
0049
0050
0051
0052
0053
0054 V8_WARN_UNUSED_RESULT V8_INLINE bool To(T* out) const {
0055 if (V8_LIKELY(IsJust())) *out = value_;
0056 return IsJust();
0057 }
0058
0059
0060
0061
0062
0063 V8_INLINE T FromJust() const& {
0064 if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
0065 return value_;
0066 }
0067
0068
0069
0070
0071
0072 V8_INLINE T FromJust() && {
0073 if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
0074 return std::move(value_);
0075 }
0076
0077
0078
0079
0080
0081 V8_INLINE T FromMaybe(const T& default_value) const {
0082 return has_value_ ? value_ : default_value;
0083 }
0084
0085 V8_INLINE bool operator==(const Maybe& other) const {
0086 return (IsJust() == other.IsJust()) &&
0087 (!IsJust() || FromJust() == other.FromJust());
0088 }
0089
0090 V8_INLINE bool operator!=(const Maybe& other) const {
0091 return !operator==(other);
0092 }
0093
0094 private:
0095 Maybe() : has_value_(false) {}
0096 explicit Maybe(const T& t) : has_value_(true), value_(t) {}
0097 explicit Maybe(T&& t) : has_value_(true), value_(std::move(t)) {}
0098
0099 bool has_value_;
0100 T value_;
0101
0102 template <class U>
0103 friend Maybe<U> Nothing();
0104 template <class U>
0105 friend Maybe<U> Just(const U& u);
0106 template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
0107 friend Maybe<U> Just(U&& u);
0108 };
0109
0110 template <class T>
0111 inline Maybe<T> Nothing() {
0112 return Maybe<T>();
0113 }
0114
0115 template <class T>
0116 inline Maybe<T> Just(const T& t) {
0117 return Maybe<T>(t);
0118 }
0119
0120
0121
0122
0123 template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
0124 inline Maybe<T> Just(T&& t) {
0125 return Maybe<T>(std::move(t));
0126 }
0127
0128
0129 template <>
0130 class Maybe<void> {
0131 public:
0132 V8_INLINE bool IsNothing() const { return !is_valid_; }
0133 V8_INLINE bool IsJust() const { return is_valid_; }
0134
0135 V8_INLINE bool operator==(const Maybe& other) const {
0136 return IsJust() == other.IsJust();
0137 }
0138
0139 V8_INLINE bool operator!=(const Maybe& other) const {
0140 return !operator==(other);
0141 }
0142
0143 private:
0144 struct JustTag {};
0145
0146 Maybe() : is_valid_(false) {}
0147 explicit Maybe(JustTag) : is_valid_(true) {}
0148
0149 bool is_valid_;
0150
0151 template <class U>
0152 friend Maybe<U> Nothing();
0153 friend Maybe<void> JustVoid();
0154 };
0155
0156 inline Maybe<void> JustVoid() { return Maybe<void>(Maybe<void>::JustTag()); }
0157
0158 }
0159
0160 #endif