api: Allow v8::Maybe<MovableType>.
Change-Id: I29bcdf3302f37568e8c8925e70a01ba342c17925 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3606229 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Anton Bikineev <bikineev@chromium.org> Cr-Commit-Position: refs/heads/main@{#80288}
This commit is contained in:
parent
896f6e749a
commit
2655d3d18d
@ -5,6 +5,9 @@
|
|||||||
#ifndef INCLUDE_V8_MAYBE_H_
|
#ifndef INCLUDE_V8_MAYBE_H_
|
||||||
#define INCLUDE_V8_MAYBE_H_
|
#define INCLUDE_V8_MAYBE_H_
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "v8-internal.h" // NOLINT(build/include_directory)
|
#include "v8-internal.h" // NOLINT(build/include_directory)
|
||||||
#include "v8config.h" // NOLINT(build/include_directory)
|
#include "v8config.h" // NOLINT(build/include_directory)
|
||||||
|
|
||||||
@ -57,11 +60,20 @@ class Maybe {
|
|||||||
* Converts this Maybe<> to a value of type T. If this Maybe<> is
|
* Converts this Maybe<> to a value of type T. If this Maybe<> is
|
||||||
* nothing (empty), V8 will crash the process.
|
* nothing (empty), V8 will crash the process.
|
||||||
*/
|
*/
|
||||||
V8_INLINE T FromJust() const {
|
V8_INLINE T FromJust() const& {
|
||||||
if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
|
if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this Maybe<> to a value of type T. If this Maybe<> is
|
||||||
|
* nothing (empty), V8 will crash the process.
|
||||||
|
*/
|
||||||
|
V8_INLINE T FromJust() && {
|
||||||
|
if (V8_UNLIKELY(!IsJust())) api_internal::FromJustIsNothing();
|
||||||
|
return std::move(value_);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts this Maybe<> to a value of type T, using a default value if this
|
* Converts this Maybe<> to a value of type T, using a default value if this
|
||||||
* Maybe<> is nothing (empty).
|
* Maybe<> is nothing (empty).
|
||||||
@ -82,6 +94,7 @@ class Maybe {
|
|||||||
private:
|
private:
|
||||||
Maybe() : has_value_(false) {}
|
Maybe() : has_value_(false) {}
|
||||||
explicit Maybe(const T& t) : has_value_(true), value_(t) {}
|
explicit Maybe(const T& t) : has_value_(true), value_(t) {}
|
||||||
|
explicit Maybe(T&& t) : has_value_(true), value_(std::move(t)) {}
|
||||||
|
|
||||||
bool has_value_;
|
bool has_value_;
|
||||||
T value_;
|
T value_;
|
||||||
@ -90,6 +103,8 @@ class Maybe {
|
|||||||
friend Maybe<U> Nothing();
|
friend Maybe<U> Nothing();
|
||||||
template <class U>
|
template <class U>
|
||||||
friend Maybe<U> Just(const U& u);
|
friend Maybe<U> Just(const U& u);
|
||||||
|
template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
|
||||||
|
friend Maybe<U> Just(U&& u);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -102,6 +117,14 @@ inline Maybe<T> Just(const T& t) {
|
|||||||
return Maybe<T>(t);
|
return Maybe<T>(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't use forwarding references here but instead use two overloads.
|
||||||
|
// Forwarding references only work when type deduction takes place, which is not
|
||||||
|
// the case for callsites such as Just<Type>(t).
|
||||||
|
template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
|
||||||
|
inline Maybe<T> Just(T&& t) {
|
||||||
|
return Maybe<T>(std::move(t));
|
||||||
|
}
|
||||||
|
|
||||||
// A template specialization of Maybe<T> for the case of T = void.
|
// A template specialization of Maybe<T> for the case of T = void.
|
||||||
template <>
|
template <>
|
||||||
class Maybe<void> {
|
class Maybe<void> {
|
||||||
|
@ -216,6 +216,7 @@ v8_source_set("unittests_sources") {
|
|||||||
"api/isolate-unittest.cc",
|
"api/isolate-unittest.cc",
|
||||||
"api/remote-object-unittest.cc",
|
"api/remote-object-unittest.cc",
|
||||||
"api/resource-constraints-unittest.cc",
|
"api/resource-constraints-unittest.cc",
|
||||||
|
"api/v8-maybe-unittest.cc",
|
||||||
"api/v8-object-unittest.cc",
|
"api/v8-object-unittest.cc",
|
||||||
"base/address-region-unittest.cc",
|
"base/address-region-unittest.cc",
|
||||||
"base/atomic-utils-unittest.cc",
|
"base/atomic-utils-unittest.cc",
|
||||||
|
42
test/unittests/api/v8-maybe-unittest.cc
Normal file
42
test/unittests/api/v8-maybe-unittest.cc
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2022 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "include/v8-maybe.h"
|
||||||
|
|
||||||
|
#include "src/base/compiler-specific.h"
|
||||||
|
#include "src/base/macros.h"
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Movable {
|
||||||
|
Movable() = default;
|
||||||
|
|
||||||
|
Movable(const Movable&) = delete;
|
||||||
|
Movable& operator=(const Movable&) = delete;
|
||||||
|
|
||||||
|
Movable(Movable&&) V8_NOEXCEPT = default;
|
||||||
|
Movable& operator=(Movable&&) V8_NOEXCEPT = default;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(MaybeTest, AllowMovableTypes) {
|
||||||
|
Maybe<Movable> m1 = Just(Movable{});
|
||||||
|
EXPECT_TRUE(m1.IsJust());
|
||||||
|
|
||||||
|
Maybe<Movable> m2 = Just<Movable>({});
|
||||||
|
EXPECT_TRUE(m2.IsJust());
|
||||||
|
|
||||||
|
Maybe<Movable> m3 = Nothing<Movable>();
|
||||||
|
EXPECT_TRUE(m3.IsNothing());
|
||||||
|
|
||||||
|
Maybe<Movable> m4 = Just(Movable{});
|
||||||
|
Movable mm = std::move(m4).FromJust();
|
||||||
|
USE(mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace v8
|
Loading…
Reference in New Issue
Block a user