diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -267,6 +267,14 @@ return hasValue() ? getValue() : std::forward(value); } + /// Returns the value contained in this as a ``U`` if present, otherwise + /// return \p Default. + template + constexpr std::enable_if_t::value, U> + getAsOr(U Default) const { + return hasValue() ? static_cast(getValue()) : std::forward(Default); + } + /// Apply a function to the value if present; otherwise return None. template auto map(const Function &F) const LLVM_LVALUE_FUNCTION diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -7,13 +7,14 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Optional.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest-spi.h" #include "gtest/gtest.h" #include - +#include using namespace llvm; @@ -193,6 +194,32 @@ EXPECT_EQ(5, A.getValueOr(42)); } +TEST_F(OptionalTest, GetAsOr) { + Optional String; + StringRef Default{"DefaultOverflowSmallStringOpt"}; + StringRef Value{"Value"}; + EXPECT_EQ(Default, String.getAsOr(Default)); + String.emplace(Value); + EXPECT_EQ(Value, String.getAsOr(Default)); + + int Item = 0; + ArrayRef OneItem = makeArrayRef(Item); + ArrayRef Empty; + + Optional> SmallVec; + EXPECT_EQ(SmallVec.getAsOr(Empty).size(), 0U); + EXPECT_EQ(SmallVec.getAsOr(ArrayRef{}).size(), 0U); + EXPECT_EQ(SmallVec.getAsOr(OneItem).size(), 1U); + SmallVec.emplace(std::initializer_list{0, 1, 2, 3}); + EXPECT_EQ(SmallVec.getAsOr(Empty).size(), 4U); + + Optional> Vector; + EXPECT_EQ(Vector.getAsOr(Empty).size(), 0U); + EXPECT_EQ(Vector.getAsOr(OneItem).size(), 1U); + Vector.emplace(std::initializer_list{0, 1, 2, 3}); + EXPECT_EQ(Vector.getAsOr(Empty).size(), 4U); +} + struct MultiArgConstructor { int x, y; MultiArgConstructor(int x, int y) : x(x), y(y) {}