return storage_.value;
}
- // TODO: This should return Value&& instead of Value. Like with
- // std::move, the calling code should decide whether it wants the move
- // to happen or not. See std::optional.
- Value value() && {
+ Value&& value() && {
+ require_value();
+ return std::move(storage_.value);
+ }
+
+ const Value&& value() const&& {
require_value();
return std::move(storage_.value);
}
return hasValue();
}
- const Value& operator*() const& { return value(); }
- Value& operator*() & { return value(); }
- // TODO: This should return Value&& instead of Value. Like with
- // std::move, the calling code should decide whether it wants the move
- // to happen or not. See std::optional.
- Value operator*() && { return std::move(value()); }
+ const Value& operator*() const& { return value(); }
+ Value& operator*() & { return value(); }
+ const Value&& operator*() const&& { return std::move(value()); }
+ Value&& operator*() && { return std::move(value()); }
const Value* operator->() const { return &value(); }
Value* operator->() { return &value(); }
}
};
-TEST(Optional, value_life_extention) {
- // Extends the life of the value.
- const auto& ptr = Optional<std::unique_ptr<int, ExpectingDeleter>>(
- {new int(42), ExpectingDeleter{1337}}).value();
- *ptr = 1337;
-}
-
TEST(Optional, value_move) {
auto ptr = Optional<std::unique_ptr<int, ExpectingDeleter>>(
{new int(42), ExpectingDeleter{1337}}).value();
*ptr = 1337;
}
-TEST(Optional, dereference_life_extention) {
- // Extends the life of the value.
- const auto& ptr = *Optional<std::unique_ptr<int, ExpectingDeleter>>(
- {new int(42), ExpectingDeleter{1337}});
- *ptr = 1337;
-}
-
TEST(Optional, dereference_move) {
auto ptr = *Optional<std::unique_ptr<int, ExpectingDeleter>>(
{new int(42), ExpectingDeleter{1337}});