Commit 65902504 authored by Tudor Bosman's avatar Tudor Bosman Committed by Sara Golemon

Add Optional::value_or

Summary:
Common pattern: a function returns Optional<X>, indicating whether some X was
present or not; you want a default value if the X was not present. Requires
that X is copiable.

Test Plan: optional_test (test added)

Reviewed By: tjackson@fb.com

Subscribers: aalexandre, fjargsto, jhj, ntv, lesha, kma

FB internal diff: D1502397
parent 32a19232
......@@ -225,6 +225,17 @@ class Optional {
const Value* operator->() const { return &value(); }
Value* operator->() { return &value(); }
// Return a copy of the value if set, or a given default if not.
template <class U>
Value value_or(U&& dflt) const& {
return hasValue_ ? value_ : std::forward<U>(dflt);
}
template <class U>
Value value_or(U&& dflt) && {
return hasValue_ ? std::move(value_) : std::forward<U>(dflt);
}
private:
template<class... Args>
void construct(Args&&... args) {
......
......@@ -97,15 +97,49 @@ TEST(Optional, Const) {
TEST(Optional, Simple) {
Optional<int> opt;
EXPECT_FALSE(bool(opt));
EXPECT_EQ(42, opt.value_or(42));
opt = 4;
EXPECT_TRUE(bool(opt));
EXPECT_EQ(4, *opt);
EXPECT_EQ(4, opt.value_or(42));
opt = 5;
EXPECT_EQ(5, *opt);
opt.clear();
EXPECT_FALSE(bool(opt));
}
TEST(Optional, value_or_rvalue_arg) {
Optional<std::string> opt;
std::string dflt = "hello";
EXPECT_EQ("hello", opt.value_or(dflt));
EXPECT_EQ("hello", dflt);
EXPECT_EQ("hello", opt.value_or(std::move(dflt)));
EXPECT_EQ("", dflt);
EXPECT_EQ("world", opt.value_or("world"));
dflt = "hello";
// Make sure that the const overload works on const objects
const auto& optc = opt;
EXPECT_EQ("hello", optc.value_or(dflt));
EXPECT_EQ("hello", dflt);
EXPECT_EQ("hello", optc.value_or(std::move(dflt)));
EXPECT_EQ("", dflt);
EXPECT_EQ("world", optc.value_or("world"));
dflt = "hello";
opt = "meow";
EXPECT_EQ("meow", opt.value_or(dflt));
EXPECT_EQ("hello", dflt);
EXPECT_EQ("meow", opt.value_or(std::move(dflt)));
EXPECT_EQ("hello", dflt); // only moved if used
}
TEST(Optional, value_or_noncopyable) {
Optional<std::unique_ptr<int>> opt;
std::unique_ptr<int> dflt(new int(42));
EXPECT_EQ(42, *std::move(opt).value_or(std::move(dflt)));
}
TEST(Optional, EmptyConstruct) {
Optional<int> opt;
EXPECT_FALSE(bool(opt));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment