This commit is contained in:
Johannes Kroll 2015-10-27 23:29:24 +01:00
commit a28e0b1588

View file

@ -240,6 +240,19 @@ struct variant_helper<T, Types...>
variant_helper<Types...>::copy(old_id, old_value, new_value);
}
}
VARIANT_INLINE static void direct_swap(const std::size_t id, void * lhs, void * rhs)
{
using std::swap; //enable ADL
if (id == sizeof...(Types))
{
// both lhs and rhs hold T
swap(*reinterpret_cast<T*>(lhs), *reinterpret_cast<T*>(rhs));
}
else
{
variant_helper<Types...>::direct_swap(id, lhs, rhs);
}
}
};
template<> struct variant_helper<>
@ -247,6 +260,7 @@ template<> struct variant_helper<>
VARIANT_INLINE static void destroy(const std::size_t, void *) {}
VARIANT_INLINE static void move(const std::size_t, void *, void *) {}
VARIANT_INLINE static void copy(const std::size_t, const void *, void *) {}
VARIANT_INLINE static void direct_swap(const std::size_t, void *, void *) {}
};
namespace detail {
@ -595,16 +609,24 @@ public:
helper_type::move(old.type_index, &old.data, &data);
}
friend void swap(variant<Types...> & first, variant<Types...> & second)
void assign(variant<Types...> & rhs)
{
using std::swap; //enable ADL
swap(first.type_index, second.type_index);
swap(first.data, second.data);
if (type_index == rhs.type_index)
{
helper_type::direct_swap(rhs.type_index, &rhs.data, &data);
}
else
{
helper_type::destroy(type_index, &data);
type_index = detail::invalid_value;
helper_type::copy(rhs.type_index, &rhs.data, &data);
type_index = rhs.type_index;
}
}
VARIANT_INLINE variant<Types...>& operator=(variant<Types...> other)
{
swap(*this, other);
assign(other);
return *this;
}
@ -614,7 +636,7 @@ public:
VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
{
variant<Types...> temp(std::forward<T>(rhs));
swap(*this, temp);
assign(temp);
return *this;
}
@ -623,7 +645,7 @@ public:
VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
{
variant<Types...> temp(rhs);
swap(*this, temp);
assign(temp);
return *this;
}