folly::make_optional
authorMike Curtiss <mcurtiss@fb.com>
Thu, 28 Feb 2013 03:53:14 +0000 (19:53 -0800)
committerJordan DeLong <jdelong@fb.com>
Tue, 19 Mar 2013 00:07:57 +0000 (17:07 -0700)
Summary:
Helper method for creating a folly::Optional<T> by just passing
in a T reference.  Analogous to boost::make_optional.

Test Plan: Added test case

Reviewed By: tjackson@fb.com

FB internal diff: D721762

folly/Optional.h
folly/test/OptionalTest.cpp

index 5b574f5b509dd557189a9aa3eb5f2836b9d4d37a..b168b59a768f825eb77c7e0334dc5fafdb99abea 100644 (file)
@@ -268,6 +268,12 @@ void swap(Optional<T>& a, Optional<T>& b) {
   }
 }
 
-}// namespace folly
+template<class T,
+         class Opt = Optional<typename std::decay<T>::type>>
+Opt make_optional(T&& v) {
+  return Opt(std::forward<T>(v));
+}
+
+} // namespace folly
 
 #endif//FOLLY_OPTIONAL_H_
index 0e240a0144b0e31ea1e7e8a44ebf4f0016fad993..4eb564176fc988cca7fc0461bd058f5ee2f84f25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -274,3 +274,38 @@ TEST(Optional, Pointee) {
   x = none;
   EXPECT_FALSE(get_pointer(x));
 }
+
+TEST(Optional, MakeOptional) {
+  // const L-value version
+  const std::string s("abc");
+  auto optStr = make_optional(s);
+  ASSERT_TRUE(optStr.hasValue());
+  EXPECT_EQ(*optStr, "abc");
+  *optStr = "cde";
+  EXPECT_EQ(s, "abc");
+  EXPECT_EQ(*optStr, "cde");
+
+  // L-value version
+  std::string s2("abc");
+  auto optStr2 = make_optional(s2);
+  ASSERT_TRUE(optStr2.hasValue());
+  EXPECT_EQ(*optStr2, "abc");
+  *optStr2 = "cde";
+  // it's vital to check that s2 wasn't clobbered
+  EXPECT_EQ(s2, "abc");
+
+  // L-value reference version
+  std::string& s3(s2);
+  auto optStr3 = make_optional(s3);
+  ASSERT_TRUE(optStr3.hasValue());
+  EXPECT_EQ(*optStr3, "abc");
+  *optStr3 = "cde";
+  EXPECT_EQ(s3, "abc");
+
+  // R-value ref version
+  unique_ptr<int> pInt(new int(3));
+  auto optIntPtr = make_optional(std::move(pInt));
+  EXPECT_TRUE(pInt.get() == nullptr);
+  ASSERT_TRUE(optIntPtr.hasValue());
+  EXPECT_EQ(**optIntPtr, 3);
+}