зеркало из https://github.com/mozilla/gecko-dev.git
Bug 953296 - Implement mozilla::MakeUnique. r=jcranmer
--HG-- extra : rebase_source : 6e25d80e697f1b00e1525f6b11221f4ed9cf965e
This commit is contained in:
Родитель
9b3cc8ddf5
Коммит
83843f0171
|
@ -569,6 +569,99 @@ operator!=(NullptrT n, const UniquePtr<T, D>& x)
|
|||
|
||||
// No operator<, operator>, operator<=, operator>= for now because simplicity.
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct UniqueSelector
|
||||
{
|
||||
typedef UniquePtr<T> SingleObject;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct UniqueSelector<T[]>
|
||||
{
|
||||
typedef UniquePtr<T[]> UnknownBound;
|
||||
};
|
||||
|
||||
template<typename T, decltype(sizeof(int)) N>
|
||||
struct UniqueSelector<T[N]>
|
||||
{
|
||||
typedef UniquePtr<T[N]> KnownBound;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// We don't have variadic template support everywhere, so just hard-code arities
|
||||
// 0-4 for now. If you need more arguments, feel free to add the extra
|
||||
// overloads.
|
||||
//
|
||||
// Beware! Due to lack of true nullptr support in gcc 4.4 and 4.5, passing
|
||||
// literal nullptr to MakeUnique will not work on some platforms. See Move.h
|
||||
// for more details.
|
||||
|
||||
template<typename T>
|
||||
typename detail::UniqueSelector<T>::SingleObject
|
||||
MakeUnique()
|
||||
{
|
||||
return UniquePtr<T>(new T());
|
||||
}
|
||||
|
||||
template<typename T, typename A1>
|
||||
typename detail::UniqueSelector<T>::SingleObject
|
||||
MakeUnique(A1&& a1)
|
||||
{
|
||||
return UniquePtr<T>(new T(Forward<A1>(a1)));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2>
|
||||
typename detail::UniqueSelector<T>::SingleObject
|
||||
MakeUnique(A1&& a1, A2&& a2)
|
||||
{
|
||||
return UniquePtr<T>(new T(Forward<A1>(a1), Forward<A2>(a2)));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3>
|
||||
typename detail::UniqueSelector<T>::SingleObject
|
||||
MakeUnique(A1&& a1, A2&& a2, A3&& a3)
|
||||
{
|
||||
return UniquePtr<T>(new T(Forward<A1>(a1), Forward<A2>(a2), Forward<A3>(a3)));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4>
|
||||
typename detail::UniqueSelector<T>::SingleObject
|
||||
MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4)
|
||||
{
|
||||
return UniquePtr<T>(new T(Forward<A1>(a1), Forward<A2>(a2), Forward<A3>(a3), Forward<A4>(a4)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename detail::UniqueSelector<T>::UnknownBound
|
||||
MakeUnique(decltype(sizeof(int)) n)
|
||||
{
|
||||
typedef typename RemoveExtent<T>::Type ArrayType;
|
||||
return UniquePtr<T>(new ArrayType[n]());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename detail::UniqueSelector<T>::KnownBound
|
||||
MakeUnique() MOZ_DELETE;
|
||||
|
||||
template<typename T, typename A1>
|
||||
typename detail::UniqueSelector<T>::KnownBound
|
||||
MakeUnique(A1&& a1) MOZ_DELETE;
|
||||
|
||||
template<typename T, typename A1, typename A2>
|
||||
typename detail::UniqueSelector<T>::KnownBound
|
||||
MakeUnique(A1&& a1, A2&& a2) MOZ_DELETE;
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3>
|
||||
typename detail::UniqueSelector<T>::KnownBound
|
||||
MakeUnique(A1&& a1, A2&& a2, A3&& a3) MOZ_DELETE;
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4>
|
||||
typename detail::UniqueSelector<T>::KnownBound
|
||||
MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4) MOZ_DELETE;
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_UniquePtr_h */
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
using mozilla::DefaultDelete;
|
||||
using mozilla::IsNullPointer;
|
||||
using mozilla::IsSame;
|
||||
using mozilla::MakeUnique;
|
||||
using mozilla::Swap;
|
||||
using mozilla::UniquePtr;
|
||||
using mozilla::Vector;
|
||||
|
@ -543,6 +544,48 @@ TestArray()
|
|||
return true;
|
||||
}
|
||||
|
||||
struct Q
|
||||
{
|
||||
Q() {}
|
||||
Q(const Q& q) {}
|
||||
|
||||
Q(Q& q, char c) {}
|
||||
|
||||
template<typename T>
|
||||
Q(Q q, T&& t, int i)
|
||||
{}
|
||||
|
||||
Q(int i, long j, double k, void* l) {}
|
||||
};
|
||||
|
||||
static int randomInt() { return 4; }
|
||||
|
||||
static bool
|
||||
TestMakeUnique()
|
||||
{
|
||||
UniquePtr<int> a1(MakeUnique<int>());
|
||||
UniquePtr<long> a2(MakeUnique<long>(4));
|
||||
|
||||
// no args, easy
|
||||
UniquePtr<Q> q0(MakeUnique<Q>());
|
||||
|
||||
// temporary bound to const lval ref
|
||||
UniquePtr<Q> q1(MakeUnique<Q>(Q()));
|
||||
|
||||
// passing through a non-const lval ref
|
||||
UniquePtr<Q> q2(MakeUnique<Q>(*q1, 'c'));
|
||||
|
||||
// pass by copying, forward a temporary, pass by value
|
||||
UniquePtr<Q> q3(MakeUnique<Q>(Q(), UniquePtr<int>(), randomInt()));
|
||||
|
||||
// various type mismatching to test "fuzzy" forwarding
|
||||
UniquePtr<Q> q4(MakeUnique<Q>('s', 66LL, 3.141592654, &q3));
|
||||
|
||||
UniquePtr<char[]> c1(MakeUnique<char[]>(5));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
|
@ -558,4 +601,6 @@ main()
|
|||
return 1;
|
||||
if (!TestArray())
|
||||
return 1;
|
||||
if (!TestMakeUnique())
|
||||
return 1;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче