mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1625138 - Part 3: Replace mozilla::IsEmpty with std::is_empty. r=froydnj
Differential Revision: https://phabricator.services.mozilla.com/D68357 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
48227ef019
commit
526c7e70fc
@ -9,6 +9,7 @@
|
||||
#ifndef mozilla_CompactPair_h
|
||||
#define mozilla_CompactPair_h
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
@ -27,13 +28,14 @@ enum StorageType { AsBase, AsMember };
|
||||
// The extra conditions on storage for B are necessary so that CompactPairHelper
|
||||
// won't ambiguously inherit from either A or B, such that one or the other base
|
||||
// class would be inaccessible.
|
||||
template <
|
||||
typename A, typename B,
|
||||
detail::StorageType = IsEmpty<A>::value ? detail::AsBase : detail::AsMember,
|
||||
detail::StorageType = IsEmpty<B>::value && !std::is_base_of<A, B>::value &&
|
||||
!std::is_base_of<B, A>::value
|
||||
? detail::AsBase
|
||||
: detail::AsMember>
|
||||
template <typename A, typename B,
|
||||
detail::StorageType =
|
||||
std::is_empty_v<A> ? detail::AsBase : detail::AsMember,
|
||||
detail::StorageType = std::is_empty_v<B> &&
|
||||
!std::is_base_of<A, B>::value &&
|
||||
!std::is_base_of<B, A>::value
|
||||
? detail::AsBase
|
||||
: detail::AsMember>
|
||||
struct CompactPairHelper;
|
||||
|
||||
template <typename A, typename B>
|
||||
|
@ -268,7 +268,7 @@ struct HasFreeLSB<T&> {
|
||||
template <typename V, typename E>
|
||||
struct SelectResultImpl {
|
||||
static const PackingStrategy value =
|
||||
(IsEmpty<V>::value && UnusedZero<E>::value)
|
||||
(std::is_empty_v<V> && UnusedZero<E>::value)
|
||||
? PackingStrategy::NullIsOk
|
||||
: (detail::HasFreeLSB<V>::value && detail::HasFreeLSB<E>::value)
|
||||
? PackingStrategy::LowBitTagIsError
|
||||
|
@ -400,61 +400,6 @@ struct IsPod<T*> : TrueType {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// __is_empty is a supported extension across all of our supported compilers:
|
||||
// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html
|
||||
// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits
|
||||
// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx
|
||||
template <typename T>
|
||||
struct IsEmptyHelper
|
||||
: IntegralConstant<bool, IsClass<T>::value&& __is_empty(T)> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* IsEmpty determines whether a type is a class (but not a union) that is empty.
|
||||
*
|
||||
* A class is empty iff it and all its base classes have no non-static data
|
||||
* members (except bit-fields of length 0) and no virtual member functions, and
|
||||
* no base class is empty or a virtual base class.
|
||||
*
|
||||
* Intuitively, empty classes don't have any data that has to be stored in
|
||||
* instances of those classes. (The size of the class must still be non-zero,
|
||||
* because distinct array elements of any type must have different addresses.
|
||||
* However, if the Empty Base Optimization is implemented by the compiler [most
|
||||
* compilers implement it, and in certain cases C++11 requires it], the size of
|
||||
* a class inheriting from an empty |Base| class need not be inflated by
|
||||
* |sizeof(Base)|.) And intuitively, non-empty classes have data members and/or
|
||||
* vtable pointers that must be stored in each instance for proper behavior.
|
||||
*
|
||||
* static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty");
|
||||
* union U1 { int x; };
|
||||
* static_assert(!mozilla::IsEmpty<U1>::value, "not a class => not empty");
|
||||
* struct E1 {};
|
||||
* struct E2 { int : 0 };
|
||||
* struct E3 : E1 {};
|
||||
* struct E4 : E2 {};
|
||||
* static_assert(mozilla::IsEmpty<E1>::value &&
|
||||
* mozilla::IsEmpty<E2>::value &&
|
||||
* mozilla::IsEmpty<E3>::value &&
|
||||
* mozilla::IsEmpty<E4>::value,
|
||||
* "all empty");
|
||||
* union U2 { E1 e1; };
|
||||
* static_assert(!mozilla::IsEmpty<U2>::value, "not a class => not empty");
|
||||
* struct NE1 { int x; };
|
||||
* struct NE2 : virtual E1 {};
|
||||
* struct NE3 : E2 { virtual ~NE3() {} };
|
||||
* struct NE4 { virtual void f() {} };
|
||||
* static_assert(!mozilla::IsEmpty<NE1>::value &&
|
||||
* !mozilla::IsEmpty<NE2>::value &&
|
||||
* !mozilla::IsEmpty<NE3>::value &&
|
||||
* !mozilla::IsEmpty<NE4>::value,
|
||||
* "all empty");
|
||||
*/
|
||||
template <typename T>
|
||||
struct IsEmpty : detail::IsEmptyHelper<typename RemoveCV<T>::Type> {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T, bool = IsFloatingPoint<T>::value,
|
||||
bool = IsIntegral<T>::value,
|
||||
typename NoCV = typename RemoveCV<T>::Type>
|
||||
|
@ -20,7 +20,6 @@ using mozilla::IsClass;
|
||||
using mozilla::IsConvertible;
|
||||
using mozilla::IsDefaultConstructible;
|
||||
using mozilla::IsDestructible;
|
||||
using mozilla::IsEmpty;
|
||||
using mozilla::IsFunction;
|
||||
using mozilla::IsPointer;
|
||||
using mozilla::IsSame;
|
||||
@ -138,45 +137,6 @@ static_assert(!IsClass<int>::value, "int isn't a class");
|
||||
static_assert(IsClass<const S1>::value, "S is a class");
|
||||
static_assert(!IsClass<U1>::value, "U isn't a class");
|
||||
|
||||
static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty");
|
||||
static_assert(!mozilla::IsEmpty<bool[5]>::value, "not a class => not empty");
|
||||
|
||||
static_assert(!mozilla::IsEmpty<U1>::value, "not a class => not empty");
|
||||
|
||||
struct E1 {};
|
||||
struct E2 {
|
||||
int : 0;
|
||||
};
|
||||
struct E3 : E1 {};
|
||||
struct E4 : E2 {};
|
||||
|
||||
static_assert(IsEmpty<const volatile S1>::value, "S should be empty");
|
||||
|
||||
static_assert(mozilla::IsEmpty<E1>::value && mozilla::IsEmpty<E2>::value &&
|
||||
mozilla::IsEmpty<E3>::value && mozilla::IsEmpty<E4>::value,
|
||||
"all empty");
|
||||
|
||||
union U2 {
|
||||
E1 e1;
|
||||
};
|
||||
static_assert(!mozilla::IsEmpty<U2>::value, "not a class => not empty");
|
||||
|
||||
struct NE1 {
|
||||
int mX;
|
||||
};
|
||||
struct NE2 : virtual E1 {};
|
||||
struct NE3 : E2 {
|
||||
virtual ~NE3() = default;
|
||||
};
|
||||
struct NE4 {
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
static_assert(!mozilla::IsEmpty<NE1>::value && !mozilla::IsEmpty<NE2>::value &&
|
||||
!mozilla::IsEmpty<NE3>::value &&
|
||||
!mozilla::IsEmpty<NE4>::value,
|
||||
"all empty");
|
||||
|
||||
static_assert(!IsSigned<bool>::value, "bool shouldn't be signed");
|
||||
static_assert(IsUnsigned<bool>::value, "bool should be unsigned");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user