/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Template-based metaprogramming and type-testing facilities. */ #ifndef mozilla_TypeTraits_h_ #define mozilla_TypeTraits_h_ namespace mozilla { /* * IsBaseOf allows to know whether a given class is derived from another. * * Consider the following class definitions: * * class A {}; * class B : public A {}; * class C {}; * * mozilla::IsBaseOf::value is true; * mozilla::IsBaseOf::value is false; */ template class IsBaseOf { private: static char test(Base* b); static int test(...); public: static const bool value = sizeof(test(static_cast(0))) == sizeof(char); }; /* * IsConvertible determines whether a value of type From will implicitly convert * to a value of type To. For example: * * struct A {}; * struct B : public A {}; * struct C {}; * * mozilla::IsConvertible::value is true; * mozilla::IsConvertible::value is true; * mozilla::IsConvertible::value is true; * mozilla::IsConvertible::value is true; * mozilla::IsConvertible::value is false; * mozilla::IsConvertible::value is false; * mozilla::IsConvertible::value is false; * mozilla::IsConvertible::value is false. * * For obscure reasons, you can't use IsConvertible when the types being tested * are related through private inheritance, and you'll get a compile error if * you try. Just don't do it! */ template struct IsConvertible { private: static From create(); 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 struct Conditional { typedef A Type; }; template 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; * mozilla::EnableIf::Type is a compile-time error. * * Use this template to implement SFINAE-style (Substitution Failure Is not An * Error) requirements. For example, you might use it to impose a restriction * on a template parameter: * * template * class PodVector // vector optimized to store POD (memcpy-able) types * { * EnableIf, T>::Type* vector; * size_t length; * ... * }; */ template struct EnableIf {}; template struct EnableIf { typedef T Type; }; } /* namespace mozilla */ #endif /* mozilla_TypeTraits_h_ */