зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1246841 - Allow construction of Variant values using type inference. r=waldo
--HG-- extra : rebase_source : 7d596149e6d3c630d62aab0d65d5a826af731bf5
This commit is contained in:
Родитель
4052eca615
Коммит
27ae3900e1
|
@ -247,6 +247,39 @@ struct VariantImplementation<N, T, Ts...>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* AsVariantTemporary stores a value of type T to allow construction of a
|
||||
* Variant value via type inference. Because T is copied and there's no
|
||||
* guarantee that the copy can be elided, AsVariantTemporary is best used with
|
||||
* primitive or very small types.
|
||||
*/
|
||||
template <typename T>
|
||||
struct AsVariantTemporary
|
||||
{
|
||||
explicit AsVariantTemporary(const T& aValue)
|
||||
: mValue(aValue)
|
||||
{}
|
||||
|
||||
template<typename U>
|
||||
explicit AsVariantTemporary(U&& aValue)
|
||||
: mValue(Forward<U>(aValue))
|
||||
{}
|
||||
|
||||
AsVariantTemporary(const AsVariantTemporary& aOther)
|
||||
: mValue(aOther.mValue)
|
||||
{}
|
||||
|
||||
AsVariantTemporary(AsVariantTemporary&& aOther)
|
||||
: mValue(Move(aOther.mValue))
|
||||
{}
|
||||
|
||||
AsVariantTemporary() = delete;
|
||||
void operator=(const AsVariantTemporary&) = delete;
|
||||
void operator=(AsVariantTemporary&&) = delete;
|
||||
|
||||
typename RemoveConst<typename RemoveReference<T>::Type>::Type mValue;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
|
@ -270,6 +303,18 @@ struct VariantImplementation<N, T, Ts...>
|
|||
* Variant<char, uint32_t> v1('a');
|
||||
* Variant<UniquePtr<A>, B, C> v2(MakeUnique<A>());
|
||||
*
|
||||
* Because specifying the full type of a Variant value is often verbose,
|
||||
* AsVariant() can be used to construct a Variant value using type inference in
|
||||
* contexts such as expressions or when returning values from functions. Because
|
||||
* AsVariant() must copy or move the value into a temporary and this cannot
|
||||
* necessarily be elided by the compiler, it's mostly appropriate only for use
|
||||
* with primitive or very small types.
|
||||
*
|
||||
*
|
||||
* Variant<char, uint32_t> Foo() { return AsVariant('x'); }
|
||||
* // ...
|
||||
* Variant<char, uint32_t> v1 = Foo(); // v1 holds char('x').
|
||||
*
|
||||
* All access to the contained value goes through type-safe accessors.
|
||||
*
|
||||
* void
|
||||
|
@ -391,6 +436,19 @@ public:
|
|||
new (ptr()) T(Forward<T>(aT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs this Variant from an AsVariantTemporary<T> such that T can be
|
||||
* stored in one of the types allowable in this Variant. This is used in the
|
||||
* implementation of AsVariant().
|
||||
*/
|
||||
template<typename RefT,
|
||||
typename T = typename detail::SelectVariantType<RefT, Ts...>::Type>
|
||||
MOZ_IMPLICIT Variant(detail::AsVariantTemporary<RefT>&& aValue)
|
||||
: tag(Impl::template tag<T>())
|
||||
{
|
||||
new (ptr()) T(Move(aValue.mValue));
|
||||
}
|
||||
|
||||
/** Copy construction. */
|
||||
Variant(const Variant& aRhs)
|
||||
: tag(aRhs.tag)
|
||||
|
@ -421,6 +479,15 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
/** Move assignment from AsVariant(). */
|
||||
template <typename T>
|
||||
Variant& operator=(detail::AsVariantTemporary<T>&& aValue)
|
||||
{
|
||||
this->~Variant();
|
||||
new (this) Variant(Move(aValue));
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Variant()
|
||||
{
|
||||
Impl::destroy(*this);
|
||||
|
@ -502,6 +569,26 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* AsVariant() is used to construct a Variant<T,...> value containing the
|
||||
* provided T value using type inference. It can be used to construct Variant
|
||||
* values in expressions or return them from functions without specifying the
|
||||
* entire Variant type.
|
||||
*
|
||||
* Because AsVariant() must copy or move the value into a temporary and this
|
||||
* cannot necessarily be elided by the compiler, it's mostly appropriate only
|
||||
* for use with primitive or very small types.
|
||||
*
|
||||
* AsVariant() returns a AsVariantTemporary value which is implicitly
|
||||
* convertible to any Variant that can hold a value of type T.
|
||||
*/
|
||||
template<typename T>
|
||||
detail::AsVariantTemporary<T>
|
||||
AsVariant(T&& aValue)
|
||||
{
|
||||
return detail::AsVariantTemporary<T>(Forward<T>(aValue));
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_Variant_h */
|
||||
|
|
Загрузка…
Ссылка в новой задаче