[ constructors ] prevent empty optional access

optional types being taken in were forwarding their values without checking, resulting in segfaults on optional<U> -> optional<T> conversions. This fixes those problems in the constructors.
This commit is contained in:
The Phantom Derpstorm
2019-02-13 09:00:07 -05:00
committed by GitHub
parent 5d3d6c399a
commit 1de2f2a49c

View File

@@ -1190,16 +1190,20 @@ public:
class U, detail::enable_from_other<T, U, const U &> * = nullptr, class U, detail::enable_from_other<T, U, const U &> * = nullptr,
detail::enable_if_t<std::is_convertible<const U &, T>::value> * = nullptr> detail::enable_if_t<std::is_convertible<const U &, T>::value> * = nullptr>
optional(const optional<U> &rhs) { optional(const optional<U> &rhs) {
if (rhs.has_value()) {
this->construct(*rhs); this->construct(*rhs);
} }
}
/// \exclude /// \exclude
template <class U, detail::enable_from_other<T, U, const U &> * = nullptr, template <class U, detail::enable_from_other<T, U, const U &> * = nullptr,
detail::enable_if_t<!std::is_convertible<const U &, T>::value> * = detail::enable_if_t<!std::is_convertible<const U &, T>::value> * =
nullptr> nullptr>
explicit optional(const optional<U> &rhs) { explicit optional(const optional<U> &rhs) {
if (rhs.has_value()) {
this->construct(*rhs); this->construct(*rhs);
} }
}
/// Converting move constructor. /// Converting move constructor.
/// \synopsis template <class U> optional(optional<U> &&rhs); /// \synopsis template <class U> optional(optional<U> &&rhs);
@@ -1207,16 +1211,20 @@ public:
class U, detail::enable_from_other<T, U, U &&> * = nullptr, class U, detail::enable_from_other<T, U, U &&> * = nullptr,
detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr> detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr>
optional(optional<U> &&rhs) { optional(optional<U> &&rhs) {
if (rhs.has_value()) {
this->construct(std::move(*rhs)); this->construct(std::move(*rhs));
} }
}
/// \exclude /// \exclude
template < template <
class U, detail::enable_from_other<T, U, U &&> * = nullptr, class U, detail::enable_from_other<T, U, U &&> * = nullptr,
detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr> detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr>
explicit optional(optional<U> &&rhs) { explicit optional(optional<U> &&rhs) {
if (rhs.has_value()) {
this->construct(std::move(*rhs)); this->construct(std::move(*rhs));
} }
}
/// Destroys the stored value if there is one. /// Destroys the stored value if there is one.
~optional() = default; ~optional() = default;