Bug 1639637 - Add Maybe method to move out contents leaving Nothing() behind. r=froydnj

Add take() and extract() methods returning Maybe<T> and T respectively.

Differential Revision: https://phabricator.services.mozilla.com/D76526
This commit is contained in:
Jon Bauman 2020-05-22 19:46:07 +00:00
parent 501eb4718d
commit c3c1e322ad
2 changed files with 54 additions and 1 deletions

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -460,6 +460,24 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
*/
constexpr T value() const;
/**
* Move the contents of this Maybe<T> out of internal storage and return it
* without calling the destructor. The internal storage is also reset to
* avoid multiple calls. Unsafe unless |isSome()|.
*/
T extract() {
MOZ_DIAGNOSTIC_ASSERT(isSome());
auto v = std::move(mStorage.val);
reset();
return v;
}
/**
* Returns the value (possibly |Nothing()|) by moving it out of this Maybe<T>
* and leaving |Nothing()| in its place.
*/
Maybe<T> take() { return std::exchange(*this, Nothing()); }
/*
* Returns the contents of this Maybe<T> by value. If |isNothing()|, returns
* the default value provided.

View File

@ -302,6 +302,21 @@ static bool TestBasicFeatures() {
MOZ_RELEASE_ASSERT(mayCValue2.isSome());
MOZ_RELEASE_ASSERT(*mayCValue2 == BasicValue(6));
// Check that take works
mayValue = Some(BasicValue(6));
Maybe taken = mayValue.take();
MOZ_RELEASE_ASSERT(taken->GetStatus() == eWasMoveConstructed);
MOZ_RELEASE_ASSERT(taken == Some(BasicValue(6)));
MOZ_RELEASE_ASSERT(!mayValue.isSome());
MOZ_RELEASE_ASSERT(mayValue.take() == Nothing());
// Check that extract works
mayValue = Some(BasicValue(7));
BasicValue extracted = mayValue.extract();
MOZ_RELEASE_ASSERT(extracted.GetStatus() == eWasMoveConstructed);
MOZ_RELEASE_ASSERT(extracted == BasicValue(7));
MOZ_RELEASE_ASSERT(!mayValue.isSome());
return true;
}
@ -351,6 +366,26 @@ static void TestMoveMaybe() {
MOZ_RELEASE_ASSERT(1 == sUndestroyedObjects);
MOZ_RELEASE_ASSERT(dstMoveAssigned->GetStatus() == eWasMoveConstructed);
}
{
MOZ_RELEASE_ASSERT(0 == sUndestroyedObjects);
Maybe<T> src = Some(T());
Maybe<T> dstMoveConstructed = src.take();
MOZ_RELEASE_ASSERT(1 == sUndestroyedObjects);
MOZ_RELEASE_ASSERT(dstMoveConstructed->GetStatus() == eWasMoveConstructed);
}
{
MOZ_RELEASE_ASSERT(0 == sUndestroyedObjects);
Maybe<T> src = Some(T());
T dstMoveConstructed = src.extract();
MOZ_RELEASE_ASSERT(1 == sUndestroyedObjects);
MOZ_RELEASE_ASSERT(dstMoveConstructed.GetStatus() == eWasMoveConstructed);
}
}
static bool TestCopyAndMove() {