Implement value forward constructor.

So, older constructors taking const T& or T&& is removed.

BUG=784732
TEST=Ran trybot.

Change-Id: I806b1880bf3bd2bd25da764f7592299a1a742366
Reviewed-on: https://chromium-review.googlesource.com/856380
Commit-Queue: Hidehiko Abe <[email protected]>
Reviewed-by: danakj <[email protected]>
Cr-Commit-Position: refs/heads/master@{#538032}
diff --git a/base/optional_unittest.cc b/base/optional_unittest.cc
index da3ac2d..b098c0e 100644
--- a/base/optional_unittest.cc
+++ b/base/optional_unittest.cc
@@ -465,6 +465,83 @@
   }
 }
 
+TEST(OptionalTest, ForwardConstructor) {
+  {
+    Optional<double> a(1);
+    EXPECT_TRUE(a.has_value());
+    EXPECT_EQ(1.0, a.value());
+  }
+
+  // Test that default type of 'U' is value_type.
+  {
+    struct TestData {
+      int a;
+      double b;
+      bool c;
+    };
+
+    Optional<TestData> a({1, 2.0, true});
+    EXPECT_TRUE(a.has_value());
+    EXPECT_EQ(1, a->a);
+    EXPECT_EQ(2.0, a->b);
+    EXPECT_TRUE(a->c);
+  }
+
+  // If T has a constructor with a param Optional<U>, and another ctor with a
+  // param U, then T(Optional<U>) should be used for Optional<T>(Optional<U>)
+  // constructor.
+  {
+    enum class ParamType {
+      DEFAULT_CONSTRUCTED,
+      COPY_CONSTRUCTED,
+      MOVE_CONSTRUCTED,
+      INT,
+      IN_PLACE,
+      OPTIONAL_INT,
+    };
+    struct Test {
+      Test() : param_type(ParamType::DEFAULT_CONSTRUCTED) {}
+      Test(const Test& param) : param_type(ParamType::COPY_CONSTRUCTED) {}
+      Test(Test&& param) : param_type(ParamType::MOVE_CONSTRUCTED) {}
+      explicit Test(int param) : param_type(ParamType::INT) {}
+      explicit Test(in_place_t param) : param_type(ParamType::IN_PLACE) {}
+      explicit Test(Optional<int> param)
+          : param_type(ParamType::OPTIONAL_INT) {}
+
+      ParamType param_type;
+    };
+
+    // Overload resolution with copy-conversion constructor.
+    {
+      const Optional<int> arg(in_place, 1);
+      Optional<Test> testee(arg);
+      EXPECT_EQ(ParamType::OPTIONAL_INT, testee->param_type);
+    }
+
+    // Overload resolution with move conversion constructor.
+    {
+      Optional<Test> testee(Optional<int>(in_place, 1));
+      EXPECT_EQ(ParamType::OPTIONAL_INT, testee->param_type);
+    }
+
+    // Default constructor should be used.
+    {
+      Optional<Test> testee(in_place);
+      EXPECT_EQ(ParamType::DEFAULT_CONSTRUCTED, testee->param_type);
+    }
+  }
+
+  {
+    struct Test {
+      Test(int a) {}  // NOLINT(runtime/explicit)
+    };
+    // If T is convertible from U, it is not marked as explicit.
+    static_assert(std::is_convertible<int, Test>::value,
+                  "Int should be convertible to Test.");
+    ([](Optional<Test> param) {})(1);
+  }
+}
+
 TEST(OptionalTest, NulloptConstructor) {
   constexpr Optional<int> a(base::nullopt);
   EXPECT_FALSE(a);