Assignment

This commit is contained in:
Simon Brand
2017-10-01 15:02:52 +01:00
parent 94e83f04e1
commit da52667ac8

View File

@ -397,12 +397,95 @@ class optional : private detail::optional_storage_base<T> {
~optional() = default; ~optional() = default;
// [optional.assign], assignment // [optional.assign], assignment
optional& operator=(nullopt_t) noexcept; optional& operator=(nullopt_t) noexcept {
optional& operator=(const optional&); if (has_value()) {
optional& operator=(optional&&) noexcept; this->m_value.~T();
template <class U = T> optional& operator=(U&&); this->m_has_value = false;
template <class U> optional& operator=(const optional<U>&); }
template <class U> optional& operator=(optional<U>&&); }
// TODO conditionally delete, check exception guarantee
optional& operator=(const optional& rhs) {
if (has_value()) {
if (rhs.has_value()) {
this->m_value = rhs.m_value;
}
else {
this->m_value.~T();
this->m_has_value = false;
}
}
if (rhs.has_value()) {
new (std::addressof(this->m_value)) T (rhs.m_value);
this->m_has_value = true;
}
}
// TODO conditionally delete, check exception guarantee
optional& operator=(optional&& rhs) noexcept {
if (has_value()) {
if (rhs.has_value()) {
this->m_value = std::move(rhs.m_value);
}
else {
this->m_value.~T();
this->m_has_value = false;
}
}
if (rhs.has_value()) {
new (std::addressof(this->m_value)) T (std::move(rhs.m_value));
this->m_has_value = true;
}
}
// TODO conditionally delete, check exception guarantee
template <class U = T> optional& operator=(U&& u) {
if (has_value()) {
this->m_value = std::forward<U>(u);
}
else {
new (std::addressof(this->m_value)) T (std::forward<U>(u));
this->m_has_value = true;
}
}
// TODO SFINAE, check exception guarantee
template <class U> optional& operator=(const optional<U>& rhs) {
if (has_value()) {
if (rhs.has_value()) {
this->m_value = rhs.m_value;
}
else {
this->m_value.~T();
this->m_has_value = false;
}
}
if (rhs.has_value()) {
new (std::addressof(this->m_value)) T (rhs.m_value);
this->m_has_value = true;
}
}
// TODO SFINAE, check exception guarantee
template <class U> optional& operator=(optional<U>&& rhs) {
if (has_value()) {
if (rhs.has_value()) {
this->m_value = std::move(rhs.m_value);
}
else {
this->m_value.~T();
this->m_has_value = false;
}
}
if (rhs.has_value()) {
new (std::addressof(this->m_value)) T (std::move(rhs.m_value));
this->m_has_value = true;
}
}
template <class... Args> T& emplace(Args&&... args) { template <class... Args> T& emplace(Args&&... args) {
static_assert(std::is_constructible<T, Args&&...>::value, static_assert(std::is_constructible<T, Args&&...>::value,