Add expected<void,E>

Result<void> could be used instead of Result<Success>.

Bug: 132145659
Test: libbase_test
Change-Id: I7f079a94d06c5ecb8b0303ced981f0995253dc40
diff --git a/base/expected_test.cpp b/base/expected_test.cpp
index 490ced4..a74bc1d 100644
--- a/base/expected_test.cpp
+++ b/base/expected_test.cpp
@@ -29,6 +29,7 @@
 typedef expected<double, double> exp_double;
 typedef expected<std::string, std::string> exp_string;
 typedef expected<std::pair<std::string, int>, int> exp_pair;
+typedef expected<void, int> exp_void;
 
 struct T {
   int a;
@@ -59,6 +60,9 @@
   exp_complex e2;
   EXPECT_TRUE(e2.has_value());
   EXPECT_EQ(T(0,0), e2.value());
+
+  exp_void e3;
+  EXPECT_TRUE(e3.has_value());
 }
 
 TEST(Expected, testCopyConstructible) {
@@ -69,6 +73,11 @@
   EXPECT_TRUE(e2.has_value());
   EXPECT_EQ(0, e.value());
   EXPECT_EQ(0, e2.value());
+
+  exp_void e3;
+  exp_void e4 = e3;
+  EXPECT_TRUE(e3.has_value());
+  EXPECT_TRUE(e4.has_value());
 }
 
 TEST(Expected, testMoveConstructible) {
@@ -87,6 +96,11 @@
   EXPECT_TRUE(e4.has_value());
   EXPECT_EQ("", e3.value()); // e3 is moved
   EXPECT_EQ("hello", e4.value());
+
+  exp_void e5;
+  exp_void e6 = std::move(e5);
+  EXPECT_TRUE(e5.has_value());
+  EXPECT_TRUE(e6.has_value());
 }
 
 TEST(Expected, testCopyConstructibleFromConvertibleType) {
@@ -114,11 +128,13 @@
   exp_double e2 = 5.5f;
   exp_string e3 = std::string("hello");
   exp_complex e4 = T(10, 20);
+  exp_void e5 = {};
 
   EXPECT_TRUE(e.has_value());
   EXPECT_TRUE(e2.has_value());
   EXPECT_TRUE(e3.has_value());
   EXPECT_TRUE(e4.has_value());
+  EXPECT_TRUE(e5.has_value());
   EXPECT_EQ(3, e.value());
   EXPECT_EQ(5.5f, e2.value());
   EXPECT_EQ("hello", e3.value());
@@ -154,25 +170,33 @@
   exp_string::unexpected_type unexp3 = unexpected(std::string("error"));
   exp_string e3 = unexp3;
 
+  exp_void::unexpected_type unexp4 = unexpected(10);
+  exp_void e4 = unexp4;
+
   EXPECT_FALSE(e.has_value());
   EXPECT_FALSE(e2.has_value());
   EXPECT_FALSE(e3.has_value());
+  EXPECT_FALSE(e4.has_value());
   EXPECT_EQ(10, e.error());
   EXPECT_EQ(10.5f, e2.error());
   EXPECT_EQ("error", e3.error());
+  EXPECT_EQ(10, e4.error());
 }
 
 TEST(Expected, testMoveConstructibleFromUnexpected) {
   exp_int e = unexpected(10);
   exp_double e2 = unexpected(10.5f);
   exp_string e3 = unexpected(std::string("error"));
+  exp_void e4 = unexpected(10);
 
   EXPECT_FALSE(e.has_value());
   EXPECT_FALSE(e2.has_value());
   EXPECT_FALSE(e3.has_value());
+  EXPECT_FALSE(e4.has_value());
   EXPECT_EQ(10, e.error());
   EXPECT_EQ(10.5f, e2.error());
   EXPECT_EQ("error", e3.error());
+  EXPECT_EQ(10, e4.error());
 }
 
 TEST(Expected, testConstructibleByForwarding) {
@@ -188,6 +212,9 @@
   EXPECT_TRUE(e3.has_value());
   EXPECT_EQ("hello",e3->first);
   EXPECT_EQ(30,e3->second);
+
+  exp_void e4({});
+  EXPECT_TRUE(e4.has_value());
 }
 
 TEST(Expected, testDestructible) {
@@ -217,6 +244,14 @@
 
   EXPECT_EQ(20, e3.value());
   EXPECT_EQ(20, e4.value());
+
+  exp_void e5 = unexpected(10);
+  ASSERT_FALSE(e5.has_value());
+  exp_void e6;
+  e5 = e6;
+
+  EXPECT_TRUE(e5.has_value());
+  EXPECT_TRUE(e6.has_value());
 }
 
 TEST(Expected, testAssignableFromValue) {
@@ -231,6 +266,11 @@
   exp_string e3 = "hello";
   e3 = "world";
   EXPECT_EQ("world", e3.value());
+
+  exp_void e4 = unexpected(10);
+  ASSERT_FALSE(e4.has_value());
+  e4 = {};
+  EXPECT_TRUE(e4.has_value());
 }
 
 TEST(Expected, testAssignableFromUnexpected) {
@@ -248,6 +288,11 @@
   e3 = unexpected("world");
   EXPECT_FALSE(e3.has_value());
   EXPECT_EQ("world", e3.error());
+
+  exp_void e4 = {};
+  e4 = unexpected(10);
+  EXPECT_FALSE(e4.has_value());
+  EXPECT_EQ(10, e4.error());
 }
 
 TEST(Expected, testAssignableFromMovedValue) {
@@ -285,6 +330,11 @@
   EXPECT_EQ(10.5f, t.b);
   EXPECT_EQ(3, exp.value().a);
   EXPECT_EQ(10.5, exp.value().b);
+
+  exp_void e = unexpected(10);
+  ASSERT_FALSE(e.has_value());
+  e.emplace();
+  EXPECT_TRUE(e.has_value());
 }
 
 TEST(Expected, testSwapExpectedExpected) {
@@ -296,6 +346,13 @@
   EXPECT_TRUE(e2.has_value());
   EXPECT_EQ(20, e.value());
   EXPECT_EQ(10, e2.value());
+
+  exp_void e3;
+  exp_void e4;
+  e3.swap(e4);
+
+  EXPECT_TRUE(e3.has_value());
+  EXPECT_TRUE(e4.has_value());
 }
 
 TEST(Expected, testSwapUnexpectedUnexpected) {
@@ -306,6 +363,14 @@
   EXPECT_FALSE(e2.has_value());
   EXPECT_EQ(20, e.error());
   EXPECT_EQ(10, e2.error());
+
+  exp_void e3 = unexpected(10);
+  exp_void e4 = unexpected(20);
+  e3.swap(e4);
+  EXPECT_FALSE(e3.has_value());
+  EXPECT_FALSE(e4.has_value());
+  EXPECT_EQ(20, e3.error());
+  EXPECT_EQ(10, e4.error());
 }
 
 TEST(Expected, testSwapExpectedUnepected) {
@@ -316,6 +381,13 @@
   EXPECT_TRUE(e2.has_value());
   EXPECT_EQ(30, e.error());
   EXPECT_EQ(10, e2.value());
+
+  exp_void e3;
+  exp_void e4 = unexpected(10);
+  e3.swap(e4);
+  EXPECT_FALSE(e3.has_value());
+  EXPECT_TRUE(e4.has_value());
+  EXPECT_EQ(10, e3.error());
 }
 
 TEST(Expected, testDereference) {
@@ -361,6 +433,13 @@
   EXPECT_TRUE(e2 == e);
   EXPECT_FALSE(e != e2);
   EXPECT_FALSE(e2 != e);
+
+  exp_void e3;
+  exp_void e4;
+  EXPECT_TRUE(e3 == e4);
+  EXPECT_TRUE(e4 == e3);
+  EXPECT_FALSE(e3 != e4);
+  EXPECT_FALSE(e4 != e3);
 }
 
 TEST(Expected, testDifferentValues) {
@@ -379,6 +458,13 @@
   EXPECT_FALSE(e2 == e);
   EXPECT_TRUE(e != e2);
   EXPECT_TRUE(e2 != e);
+
+  exp_void e3;
+  exp_void e4 = unexpected(10);
+  EXPECT_FALSE(e3 == e4);
+  EXPECT_FALSE(e4 == e3);
+  EXPECT_TRUE(e3 != e4);
+  EXPECT_TRUE(e4 != e3);
 }
 
 TEST(Expected, testSameErrors) {
@@ -388,6 +474,13 @@
   EXPECT_TRUE(e2 == e);
   EXPECT_FALSE(e != e2);
   EXPECT_FALSE(e2 != e);
+
+  exp_void e3 = unexpected(10);
+  exp_void e4 = unexpected(10);
+  EXPECT_TRUE(e3 == e4);
+  EXPECT_TRUE(e4 == e3);
+  EXPECT_FALSE(e3 != e4);
+  EXPECT_FALSE(e4 != e3);
 }
 
 TEST(Expected, testDifferentErrors) {
@@ -397,6 +490,13 @@
   EXPECT_FALSE(e2 == e);
   EXPECT_TRUE(e != e2);
   EXPECT_TRUE(e2 != e);
+
+  exp_void e3 = unexpected(10);
+  exp_void e4 = unexpected(20);
+  EXPECT_FALSE(e3 == e4);
+  EXPECT_FALSE(e4 == e3);
+  EXPECT_TRUE(e3 != e4);
+  EXPECT_TRUE(e4 != e3);
 }
 
 TEST(Expected, testCompareWithSameValue) {
@@ -424,6 +524,13 @@
   EXPECT_TRUE(error == e);
   EXPECT_FALSE(e != error);
   EXPECT_FALSE(error != e);
+
+  exp_void e2 = unexpected(10);
+  exp_void::unexpected_type error2 = 10;
+  EXPECT_TRUE(e2 == error2);
+  EXPECT_TRUE(error2 == e2);
+  EXPECT_FALSE(e2 != error2);
+  EXPECT_FALSE(error2 != e2);
 }
 
 TEST(Expected, testCompareWithDifferentError) {
@@ -433,6 +540,32 @@
   EXPECT_FALSE(error == e);
   EXPECT_TRUE(e != error);
   EXPECT_TRUE(error != e);
+
+  exp_void e2 = unexpected(10);
+  exp_void::unexpected_type error2 = 20;
+  EXPECT_FALSE(e2 == error2);
+  EXPECT_FALSE(error2 == e2);
+  EXPECT_TRUE(e2 != error2);
+  EXPECT_TRUE(error2 != e2);
+}
+
+TEST(Expected, testCompareDifferentType) {
+  expected<int,int> e = 10;
+  expected<int32_t, int> e2 = 10;
+  EXPECT_TRUE(e == e2);
+  e2 = 20;
+  EXPECT_FALSE(e == e2);
+
+  expected<std::string_view,int> e3 = "hello";
+  expected<std::string,int> e4 = "hello";
+  EXPECT_TRUE(e3 == e4);
+  e4 = "world";
+  EXPECT_FALSE(e3 == e4);
+
+  expected<void,int> e5;
+  expected<int,int> e6 = 10;
+  EXPECT_FALSE(e5 == e6);
+  EXPECT_FALSE(e6 == e5);
 }
 
 TEST(Expected, testDivideExample) {
@@ -478,6 +611,22 @@
   EXPECT_EQ("yes", r->first);
 }
 
+TEST(Expected, testVoid) {
+  auto test = [](bool ok) -> exp_void {
+    if (ok) {
+      return {};
+    } else {
+      return unexpected(10);
+    }
+  };
+
+  auto r = test(true);
+  EXPECT_TRUE(r);
+  r = test(false);
+  EXPECT_FALSE(r);
+  EXPECT_EQ(10, r.error());
+}
+
 // copied from result_test.cpp
 struct ConstructorTracker {
   static size_t constructor_called;