[PATCH] D85072: [ADT] Add getAsOr to Optional
Nathan James via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 1 03:23:48 PDT 2020
njames93 created this revision.
njames93 added reviewers: chandlerc, dblaikie, bkramer.
Herald added subscribers: llvm-commits, dexonsmith.
Herald added a project: LLVM.
njames93 requested review of this revision.
Adds a method `getAsOr` to `Optional`, This functions somewhat like `getValueOr` however it casts the value to a different type.
This is particularily useful if the type contained in the optional is expensive to construct.
Typical use cases would be for `Optional<std::string>`, It would often only be needed to access the value as a `StringRef`.
Similar approach can be made for `ArrayRef`.
This function is enabled for any type that can be statically casted from the type contained in the `Optional`
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D85072
Files:
llvm/include/llvm/ADT/Optional.h
llvm/unittests/ADT/OptionalTest.cpp
Index: llvm/unittests/ADT/OptionalTest.cpp
===================================================================
--- llvm/unittests/ADT/OptionalTest.cpp
+++ 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 <array>
-
+#include <initializer_list>
using namespace llvm;
@@ -193,6 +194,32 @@
EXPECT_EQ(5, A.getValueOr(42));
}
+TEST_F(OptionalTest, GetAsOr) {
+ Optional<std::string> 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<int> OneItem = makeArrayRef(Item);
+ ArrayRef<int> Empty;
+
+ Optional<llvm::SmallVector<int, 4>> SmallVec;
+ EXPECT_EQ(SmallVec.getAsOr(Empty).size(), 0U);
+ EXPECT_EQ(SmallVec.getAsOr(ArrayRef<int>{}).size(), 0U);
+ EXPECT_EQ(SmallVec.getAsOr(OneItem).size(), 1U);
+ SmallVec.emplace(std::initializer_list<int>{0, 1, 2, 3});
+ EXPECT_EQ(SmallVec.getAsOr(Empty).size(), 4U);
+
+ Optional<std::vector<int>> Vector;
+ EXPECT_EQ(Vector.getAsOr(Empty).size(), 0U);
+ EXPECT_EQ(Vector.getAsOr(OneItem).size(), 1U);
+ Vector.emplace(std::initializer_list<int>{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) {}
Index: llvm/include/llvm/ADT/Optional.h
===================================================================
--- llvm/include/llvm/ADT/Optional.h
+++ llvm/include/llvm/ADT/Optional.h
@@ -267,6 +267,14 @@
return hasValue() ? getValue() : std::forward<U>(value);
}
+ /// Returns the value contained in this as a ``U`` if present, otherwise
+ /// return \p Default.
+ template <typename U>
+ constexpr std::enable_if_t<std::is_convertible<T, U>::value, U>
+ getAsOr(U Default) const {
+ return hasValue() ? static_cast<U>(getValue()) : std::forward<U>(Default);
+ }
+
/// Apply a function to the value if present; otherwise return None.
template <class Function>
auto map(const Function &F) const LLVM_LVALUE_FUNCTION
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85072.282385.patch
Type: text/x-patch
Size: 2398 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200801/526367d6/attachment.bin>
More information about the llvm-commits
mailing list