/* 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_ */