cm::optional: Fix move assignment
This commit is contained in:
parent
ccd313a074
commit
0668120398
@ -82,6 +82,18 @@ public:
|
||||
int Value = 0;
|
||||
};
|
||||
|
||||
class NoMoveAssignEventLogger : public EventLogger
|
||||
{
|
||||
public:
|
||||
using EventLogger::EventLogger;
|
||||
|
||||
NoMoveAssignEventLogger(const NoMoveAssignEventLogger&) = default;
|
||||
NoMoveAssignEventLogger(NoMoveAssignEventLogger&&) = default;
|
||||
|
||||
NoMoveAssignEventLogger& operator=(const NoMoveAssignEventLogger&) = default;
|
||||
NoMoveAssignEventLogger& operator=(NoMoveAssignEventLogger&&) = delete;
|
||||
};
|
||||
|
||||
#define ASSERT_TRUE(x) \
|
||||
do { \
|
||||
if (!(x)) { \
|
||||
@ -328,12 +340,28 @@ static bool testCopyAssign(std::vector<Event>& expected)
|
||||
o1 = o4; // Intentionally duplicated to test assigning an empty optional to
|
||||
// an empty optional
|
||||
|
||||
cm::optional<NoMoveAssignEventLogger> o5{ 1 };
|
||||
auto const* v5 = &*o5;
|
||||
const cm::optional<NoMoveAssignEventLogger> o6{ 2 };
|
||||
auto const* v6 = &*o6;
|
||||
o5 = std::move(o6);
|
||||
const NoMoveAssignEventLogger e7{ 3 };
|
||||
o5 = std::move(e7);
|
||||
|
||||
expected = {
|
||||
{ Event::VALUE_CONSTRUCT, v2, nullptr, 4 },
|
||||
{ Event::COPY_CONSTRUCT, v1, v2, 4 },
|
||||
{ Event::VALUE_CONSTRUCT, v3, nullptr, 5 },
|
||||
{ Event::COPY_ASSIGN, v1, v3, 5 },
|
||||
{ Event::DESTRUCT, v1, nullptr, 5 },
|
||||
{ Event::VALUE_CONSTRUCT, v5, nullptr, 1 },
|
||||
{ Event::VALUE_CONSTRUCT, v6, nullptr, 2 },
|
||||
{ Event::COPY_ASSIGN, v5, v6, 2 },
|
||||
{ Event::VALUE_CONSTRUCT, &e7, nullptr, 3 },
|
||||
{ Event::COPY_ASSIGN, v5, &e7, 3 },
|
||||
{ Event::DESTRUCT, &e7, nullptr, 3 },
|
||||
{ Event::DESTRUCT, v6, nullptr, 2 },
|
||||
{ Event::DESTRUCT, v5, nullptr, 3 },
|
||||
{ Event::DESTRUCT, v3, nullptr, 5 },
|
||||
{ Event::DESTRUCT, v2, nullptr, 4 },
|
||||
};
|
||||
|
@ -68,16 +68,22 @@ public:
|
||||
|
||||
optional& operator=(nullopt_t) noexcept;
|
||||
optional& operator=(const optional& other);
|
||||
optional& operator=(optional&& other) noexcept;
|
||||
|
||||
template <
|
||||
typename U = T,
|
||||
typename = typename std::enable_if<
|
||||
!std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
|
||||
std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value &&
|
||||
template <typename U = T>
|
||||
typename std::enable_if<std::is_constructible<T, U&&>::value &&
|
||||
std::is_assignable<T&, U&&>::value,
|
||||
optional&>::type
|
||||
operator=(optional<U>&& other) noexcept;
|
||||
|
||||
template <typename U = T>
|
||||
typename std::enable_if<
|
||||
!std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
|
||||
std::is_constructible<T, U&&>::value &&
|
||||
std::is_assignable<T&, U&&>::value &&
|
||||
(!std::is_scalar<T>::value ||
|
||||
!std::is_same<typename std::decay<U>::type, T>::value)>::type>
|
||||
optional& operator=(U&& v);
|
||||
!std::is_same<typename std::decay<U>::type, T>::value),
|
||||
optional&>::type
|
||||
operator=(U&& v);
|
||||
|
||||
const T* operator->() const;
|
||||
T* operator->();
|
||||
@ -140,13 +146,17 @@ optional<T>::optional(nullopt_t) noexcept
|
||||
template <typename T>
|
||||
optional<T>::optional(const optional& other)
|
||||
{
|
||||
*this = other;
|
||||
if (other.has_value()) {
|
||||
this->emplace(*other);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
optional<T>::optional(optional&& other) noexcept
|
||||
{
|
||||
*this = std::move(other);
|
||||
if (other.has_value()) {
|
||||
this->emplace(std::move(*other));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -192,7 +202,11 @@ optional<T>& optional<T>::operator=(const optional& other)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
optional<T>& optional<T>::operator=(optional&& other) noexcept
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_constructible<T, U&&>::value &&
|
||||
std::is_assignable<T&, U&&>::value,
|
||||
optional<T>&>::type
|
||||
optional<T>::operator=(optional<U>&& other) noexcept
|
||||
{
|
||||
if (other.has_value()) {
|
||||
if (this->has_value()) {
|
||||
@ -207,8 +221,15 @@ optional<T>& optional<T>::operator=(optional&& other) noexcept
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, typename>
|
||||
optional<T>& optional<T>::operator=(U&& v)
|
||||
template <typename U>
|
||||
typename std::enable_if<
|
||||
!std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
|
||||
std::is_constructible<T, U&&>::value &&
|
||||
std::is_assignable<T&, U&&>::value &&
|
||||
(!std::is_scalar<T>::value ||
|
||||
!std::is_same<typename std::decay<U>::type, T>::value),
|
||||
optional<T>&>::type
|
||||
optional<T>::operator=(U&& v)
|
||||
{
|
||||
if (this->has_value()) {
|
||||
this->value() = v;
|
||||
|
Loading…
Reference in New Issue
Block a user