Bug 1319673 - Make it compile error when instantiate a Variant with duplicate type. r?Waldo
MozReview-Commit-ID: IKoLU2FjtzA
--- a/mfbt/Variant.h
+++ b/mfbt/Variant.h
@@ -19,16 +19,44 @@
namespace mozilla {
template<typename... Ts>
class Variant;
namespace detail {
+template <typename...>
+struct FirstTypeIsInRest;
+
+template <typename First>
+struct FirstTypeIsInRest<First> : FalseType {};
+
+template <typename First, typename Second, typename... Rest>
+struct FirstTypeIsInRest<First, Second, Rest...>
+{
+ static constexpr bool value =
+ IsSame<First, Second>::value ||
+ FirstTypeIsInRest<First, Rest...>::value;
+};
+
+template <typename...>
+struct TypesAreDistinct;
+
+template <>
+struct TypesAreDistinct<> : TrueType { };
+
+template<typename First, typename... Rest>
+struct TypesAreDistinct<First, Rest...>
+{
+ static constexpr bool value =
+ !FirstTypeIsInRest<First, Rest...>::value &&
+ TypesAreDistinct<Rest...>::value;
+};
+
// MaxSizeOf computes the maximum sizeof(T) for each T in Ts.
template<typename T, typename... Ts>
struct MaxSizeOf
{
static const size_t size = sizeof(T) > MaxSizeOf<Ts...>::size
? sizeof(T)
: MaxSizeOf<Ts...>::size;
@@ -423,16 +451,17 @@ struct AsVariantTemporary
* Variant<const char*, UniquePtr<char[]>> string;
*
* ...
* };
*/
template<typename... Ts>
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Variant
{
+ static_assert(detail::TypesAreDistinct<Ts...>::value, "Variant with duplicate types is not supported");
using Tag = typename detail::VariantTag<Ts...>::Type;
using Impl = detail::VariantImplementation<Tag, 0, Ts...>;
using RawData = AlignedStorage<detail::MaxSizeOf<Ts...>::size>;
// Raw storage for the contained variant value.
RawData raw;
// Each type is given a unique tag value that lets us keep track of the