Bug 1255857 - Allow mozilla::UniquePtr's deleter template argument to customize the pointer type; r=froydnj

This commit is contained in:
Ehsan Akhgari 2016-03-11 14:48:58 -05:00
parent 70e702783f
commit 30ce323e87
2 changed files with 51 additions and 1 deletions

View File

@ -25,6 +25,39 @@ template<typename T, class D = DefaultDelete<T>> class UniquePtr;
namespace mozilla {
namespace detail {
struct HasPointerTypeHelper
{
template <class U> static double Test(...);
template <class U> static char Test(typename U::pointer* = 0);
};
template <class T>
class HasPointerType : public IntegralConstant<bool, sizeof(HasPointerTypeHelper::Test<T>(0)) == 1>
{
};
template <class T, class D, bool = HasPointerType<D>::value>
struct PointerTypeImpl
{
typedef typename D::pointer Type;
};
template <class T, class D>
struct PointerTypeImpl<T, D, false>
{
typedef T* Type;
};
template <class T, class D>
struct PointerType
{
typedef typename PointerTypeImpl<T, typename RemoveReference<D>::Type>::Type Type;
};
} // namespace detail
/**
* UniquePtr is a smart pointer that wholly owns a resource. Ownership may be
* transferred out of a UniquePtr through explicit action, but otherwise the
@ -154,9 +187,9 @@ template<typename T, class D>
class UniquePtr
{
public:
typedef T* Pointer;
typedef T ElementType;
typedef D DeleterType;
typedef typename detail::PointerType<T, DeleterType>::Type Pointer;
private:
Pair<Pointer, DeleterType> mTuple;

View File

@ -78,6 +78,21 @@ ReturnLocalA()
return Move(a);
}
static void
TestDeleterType()
{
// Make sure UniquePtr will use its deleter's pointer type if it defines one.
typedef int* Ptr;
struct Deleter {
typedef Ptr pointer;
Deleter() {}
void operator()(int*p) {
delete p;
}
};
UniquePtr<Ptr, Deleter> u(new int, Deleter());
}
static bool
TestDefaultFreeGuts()
{
@ -550,6 +565,8 @@ TestMakeUnique()
int
main()
{
TestDeleterType();
if (!TestDefaultFree()) {
return 1;
}