In-place construction for Optional
authorYedidya Feldblum <yfeldblum@fb.com>
Sun, 2 Jul 2017 17:22:33 +0000 (10:22 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sun, 2 Jul 2017 17:40:23 +0000 (10:40 -0700)
Summary:
[Folly] In-place construction for `Optional`.

Using `in_place` as the first argument. Avoid move operations.

Reviewed By: Orvid, ot

Differential Revision: D5362563

fbshipit-source-id: 771db2556842d5dec35d1bf2ad6c23358a417d54

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

index 16cf86a10090d75575749c34fbad902f4c47d83f..c6980c186632a1f3183f9f5db93cb5e2b1ecc452 100644 (file)
@@ -61,6 +61,7 @@
 #include <utility>
 
 #include <folly/Portability.h>
+#include <folly/Utility.h>
 
 namespace folly {
 
@@ -126,6 +127,12 @@ class Optional {
     construct(newValue);
   }
 
+  template <typename... Args>
+  explicit Optional(in_place_t, Args&&... args)
+    noexcept(noexcept(::new (nullptr) Value(std::declval<Args&&>()...))) {
+    construct(std::forward<Args>(args)...);
+  }
+
   void assign(const None&) {
     clear();
   }
index ed84f753f9608e7cf3aa82c6e44d39aa9f121582..d075eeabd6a6cb4d342eb2a144cddc8fde75c317 100644 (file)
@@ -195,6 +195,21 @@ TEST(Optional, EmptyConstruct) {
   EXPECT_FALSE(bool(test2));
 }
 
+TEST(Optional, InPlaceConstruct) {
+  using A = std::pair<int, double>;
+  Optional<A> opt(in_place, 5, 3.2);
+  EXPECT_TRUE(bool(opt));
+  EXPECT_EQ(5, opt->first);
+}
+
+TEST(Optional, InPlaceNestedConstruct) {
+  using A = std::pair<int, double>;
+  Optional<Optional<A>> opt(in_place, in_place, 5, 3.2);
+  EXPECT_TRUE(bool(opt));
+  EXPECT_TRUE(bool(*opt));
+  EXPECT_EQ(5, (*opt)->first);
+}
+
 TEST(Optional, Unique) {
   Optional<unique_ptr<int>> opt;