mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 953296 - Implement mozilla::IsClass and mozilla::IsEmpty. r=jcranmer
This commit is contained in:
parent
12220c1619
commit
5ee5d4c63b
@ -169,6 +169,33 @@ struct IsEnum
|
||||
: detail::IsEnumHelper<typename RemoveCV<T>::Type>
|
||||
{};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// __is_class 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 IsClassHelper
|
||||
: IntegralConstant<bool, __is_class(T)>
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* IsClass determines whether a type is a class type (but not a union).
|
||||
*
|
||||
* struct S {};
|
||||
* union U {};
|
||||
* mozilla::IsClass<int>::value is false;
|
||||
* mozilla::IsClass<const S>::value is true;
|
||||
* mozilla::IsClass<U>::value is false;
|
||||
*/
|
||||
template<typename T>
|
||||
struct IsClass
|
||||
: detail::IsClassHelper<typename RemoveCV<T>::Type>
|
||||
{};
|
||||
|
||||
/* 20.9.4.2 Composite type traits [meta.unary.comp] */
|
||||
|
||||
/**
|
||||
@ -243,6 +270,64 @@ template<> struct IsPod<char16_t> : TrueType {};
|
||||
#endif
|
||||
template<typename T> 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>
|
||||
|
@ -7,13 +7,54 @@
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
using mozilla::IsBaseOf;
|
||||
using mozilla::IsClass;
|
||||
using mozilla::IsConvertible;
|
||||
using mozilla::IsEmpty;
|
||||
using mozilla::IsSame;
|
||||
using mozilla::IsSigned;
|
||||
using mozilla::IsUnsigned;
|
||||
using mozilla::MakeSigned;
|
||||
using mozilla::MakeUnsigned;
|
||||
|
||||
struct S1 {};
|
||||
union U1 { int x; };
|
||||
|
||||
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 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");
|
||||
|
||||
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