[llvm] r218618 - Add getValueOr to llvm::Optional<T>.

Jordan Rose jordan_rose at apple.com
Mon Sep 29 11:56:08 PDT 2014


Author: jrose
Date: Mon Sep 29 13:56:08 2014
New Revision: 218618

URL: http://llvm.org/viewvc/llvm-project?rev=218618&view=rev
Log:
Add getValueOr to llvm::Optional<T>.

This takes a single argument convertible to T, and
- if the Optional has a value, returns the existing value,
- otherwise, constructs a T from the argument and returns that.

Inspired by std::experimental::optional from the "Library Fundamentals" C++ TS.

Modified:
    llvm/trunk/include/llvm/ADT/Optional.h
    llvm/trunk/unittests/ADT/OptionalTest.cpp

Modified: llvm/trunk/include/llvm/ADT/Optional.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Optional.h?rev=218618&r1=218617&r2=218618&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/Optional.h (original)
+++ llvm/trunk/include/llvm/ADT/Optional.h Mon Sep 29 13:56:08 2014
@@ -119,9 +119,19 @@ public:
   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
 };
 

Modified: llvm/trunk/unittests/ADT/OptionalTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/OptionalTest.cpp?rev=218618&r1=218617&r2=218618&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/OptionalTest.cpp (original)
+++ llvm/trunk/unittests/ADT/OptionalTest.cpp Mon Sep 29 13:56:08 2014
@@ -169,6 +169,14 @@ TEST_F(OptionalTest, NullCopyConstructio
   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;
@@ -278,5 +286,26 @@ TEST_F(OptionalTest, MoveOnlyAssigningAs
   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
 





More information about the llvm-commits mailing list