diff options
author | 2022-08-23 08:36:32 -0700 | |
---|---|---|
committer | 2022-08-29 09:45:54 -0700 | |
commit | d48d801b0f7f8b34ae3e342f0fbfdb464a5ee780 (patch) | |
tree | ae5a78dfb2cf6f200285df4d7c6458e7760af663 | |
parent | a957c1c1dacc826df97fb20392ddeb44476f076f (diff) |
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
-rw-r--r-- | include/ftl/optional.h | 8 | ||||
-rw-r--r-- | libs/ftl/optional_test.cpp | 23 |
2 files changed, 30 insertions, 1 deletions
diff --git a/include/ftl/optional.h b/include/ftl/optional.h index a0a95c4b9a..626507fd8f 100644 --- a/include/ftl/optional.h +++ b/include/ftl/optional.h @@ -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 diff --git a/libs/ftl/optional_test.cpp b/libs/ftl/optional_test.cpp index ad8d3cf8ef..f7410c2aa9 100644 --- a/libs/ftl/optional_test.cpp +++ b/libs/ftl/optional_test.cpp @@ -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; })); |