Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d48d801b authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

FTL: Downcast to Optional<T> implicitly

The expression `ftl::Optional(std::optional(T()))` should not have type
`ftl::Optional<std::optional<T>>`.

Bug: 185536303
Test: ftl_test
Change-Id: I931cc58b985e7c41037ed50bc68abdc8028c4bdd
parent a957c1c1
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@ template <typename T>
struct Optional final : std::optional<T> {
  using std::optional<T>::optional;

  // Implicit downcast.
  Optional(std::optional<T> other) : std::optional<T>(std::move(other)) {}

  using std::optional<T>::has_value;
  using std::optional<T>::value;

@@ -94,8 +97,11 @@ struct Optional final : std::optional<T> {
  }
};

// Deduction guide.
// Deduction guides.
template <typename T>
Optional(T) -> Optional<T>;

template <typename T>
Optional(std::optional<T>) -> Optional<T>;

}  // namespace android::ftl
+23 −0
Original line number Diff line number Diff line
@@ -33,6 +33,29 @@ namespace android::test {
using ftl::Optional;
using ftl::StaticVector;

TEST(Optional, Construct) {
  // Empty.
  EXPECT_EQ(std::nullopt, Optional<int>());
  EXPECT_EQ(std::nullopt, Optional<std::string>(std::nullopt));

  // Value.
  EXPECT_EQ('?', Optional('?'));
  EXPECT_EQ(""s, Optional(std::string()));

  // In place.
  EXPECT_EQ("???"s, Optional<std::string>(std::in_place, 3u, '?'));
  EXPECT_EQ("abc"s, Optional<std::string>(std::in_place, {'a', 'b', 'c'}));

  // Implicit downcast.
  {
    Optional opt = std::optional("test"s);
    static_assert(std::is_same_v<decltype(opt), Optional<std::string>>);

    ASSERT_TRUE(opt);
    EXPECT_EQ(opt.value(), "test"s);
  }
}

TEST(Optional, Transform) {
  // Empty.
  EXPECT_EQ(std::nullopt, Optional<int>().transform([](int) { return 0; }));