Bug 1303302 - Add IsDestructible trait in TypeTraits and use it for refcounted type static check. r=froydnj

MozReview-Commit-ID: G3YFhrJngq0

--HG--
extra : rebase_source : da0aa325eb7772c1a156440ed46be9d0d429c91e
This commit is contained in:
Xidorn Quan 2016-09-16 17:23:55 +10:00
Родитель 4d43a4bbe3
Коммит 7d4ca9c88b
3 изменённых файлов: 44 добавлений и 50 удалений

Просмотреть файл

@ -572,6 +572,27 @@ struct IsUnsignedHelper<T, false, false, NoCV> : FalseType {};
template<typename T>
struct IsUnsigned : detail::IsUnsignedHelper<T> {};
namespace detail {
struct DoIsDestructibleImpl
{
template<typename T, typename = decltype(DeclVal<T&>().~T())>
static TrueType test(int);
template<typename T>
static FalseType test(...);
};
template<typename T>
struct IsDestructibleImpl : public DoIsDestructibleImpl
{
typedef decltype(test<T>(0)) Type;
};
} // namespace detail
template<typename T>
struct IsDestructible : public detail::IsDestructibleImpl<T>::Type {};
/* 20.9.5 Type property queries [meta.unary.prop.query] */
/* 20.9.6 Relationships between types [meta.rel] */

Просмотреть файл

@ -31,6 +31,7 @@ using mozilla::IsRvalueReference;
using mozilla::IsSame;
using mozilla::IsSigned;
using mozilla::IsUnsigned;
using mozilla::IsDestructible;
using mozilla::MakeSigned;
using mozilla::MakeUnsigned;
using mozilla::RemoveExtent;
@ -352,6 +353,27 @@ static_assert(!IsSigned<NotIntConstructible>::value,
static_assert(!IsUnsigned<NotIntConstructible>::value,
"non-arithmetic types are not unsigned");
class PublicDestructible
{
public:
~PublicDestructible();
};
class PrivateDestructible
{
private:
~PrivateDestructible();
};
class TrivialDestructible
{
};
static_assert(IsDestructible<PublicDestructible>::value,
"public destructible class is destructible");
static_assert(!IsDestructible<PrivateDestructible>::value,
"private destructible class is not destructible");
static_assert(IsDestructible<TrivialDestructible>::value,
"trivial destructible class is destructible");
namespace CPlusPlus11IsBaseOf {
// Adapted from C++11 § 20.9.6.

Просмотреть файл

@ -29,59 +29,10 @@
#include "mozilla/MacroForEach.h"
#include "mozilla/TypeTraits.h"
#if defined(__clang__)
// bug 1028428 shows that at least in FreeBSD 10.0 with Clang 3.4 and libc++ 3.4,
// std::is_destructible is buggy in that it returns false when it should return true
// on ipc::SharedMemory. On the other hand, all Clang versions currently in use
// seem to handle the fallback just fine.
# define MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK
#elif defined(__GNUC__)
// GCC 4.7 has buggy std::is_destructible.
# if MOZ_USING_LIBSTDCXX
# define MOZ_HAVE_STD_IS_DESTRUCTIBLE
# endif
// Some GCC versions have an ICE when using destructors in decltype().
// Works on GCC 4.8 at least.
# define MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK
#endif
#ifdef MOZ_HAVE_STD_IS_DESTRUCTIBLE
# include <type_traits>
# define MOZ_IS_DESTRUCTIBLE(X) (std::is_destructible<X>::value)
#elif defined MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK
namespace mozilla {
struct IsDestructibleFallbackImpl
{
template<typename T, typename = decltype(DeclVal<T>().~T())>
static TrueType Test(int);
template<typename>
static FalseType Test(...);
template<typename T>
struct Selector
{
typedef decltype(Test<T>(0)) type;
};
};
template<typename T>
struct IsDestructibleFallback
: IsDestructibleFallbackImpl::Selector<T>::type
{
};
} // namespace mozilla
# define MOZ_IS_DESTRUCTIBLE(X) (mozilla::IsDestructibleFallback<X>::value)
#endif
#ifdef MOZ_IS_DESTRUCTIBLE
#define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X) \
static_assert(!MOZ_IS_DESTRUCTIBLE(X), \
static_assert(!mozilla::IsDestructible<X>::value, \
"Reference-counted class " #X " should not have a public destructor. " \
"Make this class's destructor non-public");
#else
#define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X)
#endif
inline nsISupports*
ToSupports(nsISupports* aSupports)