const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+ template <typename U>
+ constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
+ return hasValue() ? getValue() : std::forward<U>(value);
+ }
+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
T&& getValue() && { assert(hasVal); return std::move(*getPointer()); }
T&& operator*() && { assert(hasVal); return std::move(*getPointer()); }
+
+ template <typename U>
+ T getValueOr(U &&value) && {
+ return hasValue() ? std::move(getValue()) : std::forward<U>(value);
+ }
#endif
};
EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
}
+TEST_F(OptionalTest, GetValueOr) {
+ Optional<int> A;
+ EXPECT_EQ(42, A.getValueOr(42));
+
+ A = 5;
+ EXPECT_EQ(5, A.getValueOr(42));
+}
+
struct MoveOnly {
static unsigned MoveConstructions;
static unsigned Destructions;
EXPECT_EQ(1u, MoveOnly::Destructions);
}
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+
+TEST_F(OptionalTest, MoveGetValueOr) {
+ Optional<MoveOnly> A;
+
+ MoveOnly::ResetCounts();
+ EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
+ EXPECT_EQ(1u, MoveOnly::MoveConstructions);
+ EXPECT_EQ(0u, MoveOnly::MoveAssignments);
+ EXPECT_EQ(2u, MoveOnly::Destructions);
+
+ A = MoveOnly(5);
+ MoveOnly::ResetCounts();
+ EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
+ EXPECT_EQ(1u, MoveOnly::MoveConstructions);
+ EXPECT_EQ(0u, MoveOnly::MoveAssignments);
+ EXPECT_EQ(2u, MoveOnly::Destructions);
+}
+
+#endif // LLVM_HAS_RVALUE_REFERENCE_THIS
+
} // end anonymous namespace