diff --git a/js/public/HashTable.h b/js/public/HashTable.h index c6cb3e098371..9d0933f7d8ca 100644 --- a/js/public/HashTable.h +++ b/js/public/HashTable.h @@ -580,17 +580,13 @@ class HashMapEntry namespace mozilla { -template -struct IsPod > -{ - static const bool value = IsPod::value; -}; +template +struct IsPod > : IsPod {}; -template +template struct IsPod > -{ - static const bool value = IsPod::value && IsPod::value; -}; + : IntegralConstant::value && IsPod::value> +{}; } // namespace mozilla diff --git a/js/src/frontend/ParseMaps.h b/js/src/frontend/ParseMaps.h index e0ca94f56119..89451c1d3ccd 100644 --- a/js/src/frontend/ParseMaps.h +++ b/js/src/frontend/ParseMaps.h @@ -421,10 +421,7 @@ typedef AtomDefnListMap::Range AtomDefnListRange; namespace mozilla { template <> -struct IsPod -{ - static const bool value = true; -}; +struct IsPod : TrueType {}; } /* namespace mozilla */ diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index c054ad59e235..8a38a826b083 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -1293,11 +1293,11 @@ void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc); namespace mozilla { -template <> struct IsPod { static const bool value = true; }; -template <> struct IsPod { static const bool value = true; }; -template <> struct IsPod { static const bool value = true; }; -template <> struct IsPod { static const bool value = true; }; -template <> struct IsPod { static const bool value = true; }; +template <> struct IsPod : TrueType {}; +template <> struct IsPod : TrueType {}; +template <> struct IsPod : TrueType {}; +template <> struct IsPod : TrueType {}; +template <> struct IsPod : TrueType {}; } /* namespace mozilla */ diff --git a/mfbt/TypeTraits.h b/mfbt/TypeTraits.h index 1422d446483f..8f2000217d6c 100644 --- a/mfbt/TypeTraits.h +++ b/mfbt/TypeTraits.h @@ -17,25 +17,77 @@ namespace mozilla { +/** + * Helper class used as a base for various type traits, exposed publicly + * because exposes it as well. + */ +template +struct IntegralConstant +{ + static const T value = Value; + typedef T ValueType; + typedef IntegralConstant Type; +}; + +/** Convenient aliases. */ +typedef IntegralConstant TrueType; +typedef IntegralConstant FalseType; + namespace detail { -/** - * The trickery used to implement IsBaseOf here makes it possible to use it for - * the cases of private and multiple inheritance. This code was inspired by the - * sample code here: - * - * http://stackoverflow.com/questions/2910979/how-is-base-of-works - */ +// The trickery used to implement IsBaseOf here makes it possible to use it for +// the cases of private and multiple inheritance. This code was inspired by the +// sample code here: +// +// http://stackoverflow.com/questions/2910979/how-is-base-of-works template -class IsBaseOfHelper +struct BaseOfHelper { public: operator Base*() const; operator Derived*(); }; +template +struct BaseOfTester +{ + private: + template + static char test(Derived*, T); + static int test(Base*, int); + + public: + static const bool value = + sizeof(test(BaseOfHelper(), int())) == sizeof(char); +}; + +template +struct BaseOfTester +{ + private: + template + static char test(Derived*, T); + static int test(Base*, int); + + public: + static const bool value = + sizeof(test(BaseOfHelper(), int())) == sizeof(char); +}; + +template +struct BaseOfTester : FalseType {}; + +template +struct BaseOfTester : TrueType {}; + +template +struct BaseOfTester : TrueType {}; + } /* namespace detail */ +template +struct Conditional; + /* * IsBaseOf allows to know whether a given class is derived from another. * @@ -49,53 +101,32 @@ class IsBaseOfHelper * mozilla::IsBaseOf::value is false; */ template -class IsBaseOf +struct IsBaseOf + : Conditional::value, TrueType, FalseType>::Type +{}; + +namespace detail { + +template +struct ConvertibleTester { private: - template - static char test(Derived*, T); - static int test(Base*, int); + static From create(); + + template + static char test(To to); + + template + static int test(...); public: static const bool value = - sizeof(test(detail::IsBaseOfHelper(), int())) == sizeof(char); + sizeof(test(create())) == sizeof(char); }; -template -class IsBaseOf -{ - private: - template - static char test(Derived*, T); - static int test(Base*, int); +} // namespace detail - public: - static const bool value = - sizeof(test(detail::IsBaseOfHelper(), int())) == sizeof(char); -}; - -template -class IsBaseOf -{ - public: - static const bool value = false; -}; - -template -class IsBaseOf -{ - public: - static const bool value = true; -}; - -template -class IsBaseOf -{ - public: - static const bool value = true; -}; - -/* +/** * IsConvertible determines whether a value of type From will implicitly convert * to a value of type To. For example: * @@ -118,28 +149,16 @@ class IsBaseOf */ template struct IsConvertible -{ - private: - static From create(); + : Conditional::value, TrueType, FalseType>::Type +{}; - template - static char test(To to); - - template - static int test(...); - - public: - static const bool value = - sizeof(test(create())) == sizeof(char); -}; - -/* +/** * Conditional selects a class between two, depending on a given boolean value. * * mozilla::Conditional::Type is A; * mozilla::Conditional::Type is B; */ -template +template struct Conditional { typedef A Type; @@ -151,7 +170,7 @@ struct Conditional typedef B Type; }; -/* +/** * EnableIf is a struct containing a typedef of T if and only if B is true. * * mozilla::EnableIf::Type is int; @@ -164,7 +183,7 @@ struct Conditional * template * class PodVector // vector optimized to store POD (memcpy-able) types * { - * EnableIf, T>::Type* vector; + * EnableIf::value, T>::Type* vector; * size_t length; * ... * }; @@ -190,42 +209,38 @@ struct EnableIf * mozilla::IsSame::value is true. */ template -struct IsSame -{ - static const bool value = false; -}; +struct IsSame : FalseType {}; template -struct IsSame -{ - static const bool value = true; -}; +struct IsSame : TrueType {}; -/* - * Traits class for identifying POD types. Until C++0x, there is no automatic - * way to detect PODs, so for the moment it is done manually. +/** + * Traits class for identifying POD types. Until C++11 there's no automatic + * way to detect PODs, so for the moment this is done manually. Users may + * define specializations of this class that inherit from mozilla::TrueType and + * mozilla::FalseType (or equivalently mozilla::IntegralConstant, or conveniently from mozilla::IsPod for composite types) as needed to + * ensure correct IsPod behavior. */ template -struct IsPod -{ - static const bool value = false; -}; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template<> struct IsPod { static const bool value = true; }; -template struct IsPod { static const bool value = true; }; +struct IsPod : public FalseType {}; + +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template<> struct IsPod : TrueType {}; +template struct IsPod : TrueType {}; /** * IsPointer determines whether a type is a pointer type (but not a pointer-to- @@ -238,15 +253,10 @@ template struct IsPod { static const bool value = true; }; * mozilla::IsPointer::value is false. */ template -struct IsPointer -{ - static const bool value = false; -}; +struct IsPointer : FalseType {}; + template -struct IsPointer -{ - static const bool value = true; -}; +struct IsPointer : TrueType {}; } /* namespace mozilla */