Bug 789077 - Sniff for a media only if the Content-Type is unknown or octet-stream...
[gecko.git] / mfbt / TypeTraits.h
blob8f04e7a4aca5f46eb8a6c8883580f7a2bb7e1efc
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /* Template-based metaprogramming and type-testing facilities. */
7 #ifndef mozilla_TypeTraits_h_
8 #define mozilla_TypeTraits_h_
10 namespace mozilla {
13 * IsBaseOf allows to know whether a given class is derived from another.
15 * Consider the following class definitions:
17 * class A {};
18 * class B : public A {};
19 * class C {};
21 * mozilla::IsBaseOf<A, B>::value is true;
22 * mozilla::IsBaseOf<A, C>::value is false;
24 template<class Base, class Derived>
25 class IsBaseOf
27 private:
28 static char test(Base* b);
29 static int test(...);
31 public:
32 static const bool value =
33 sizeof(test(static_cast<Derived*>(0))) == sizeof(char);
37 * IsConvertible determines whether a value of type From will implicitly convert
38 * to a value of type To. For example:
40 * struct A {};
41 * struct B : public A {};
42 * struct C {};
44 * mozilla::IsConvertible<A, A>::value is true;
45 * mozilla::IsConvertible<A*, A*>::value is true;
46 * mozilla::IsConvertible<B, A>::value is true;
47 * mozilla::IsConvertible<B*, A*>::value is true;
48 * mozilla::IsConvertible<C, A>::value is false;
49 * mozilla::IsConvertible<A, C>::value is false;
50 * mozilla::IsConvertible<A*, C*>::value is false;
51 * mozilla::IsConvertible<C*, A*>::value is false.
53 * For obscure reasons, you can't use IsConvertible when the types being tested
54 * are related through private inheritance, and you'll get a compile error if
55 * you try. Just don't do it!
57 template<typename From, typename To>
58 struct IsConvertible
60 private:
61 static From create();
63 template<typename From1, typename To1>
64 static char test(To to);
66 template<typename From1, typename To1>
67 static int test(...);
69 public:
70 static const bool value =
71 sizeof(test<From, To>(create())) == sizeof(char);
75 * Conditional selects a class between two, depending on a given boolean value.
77 * mozilla::Conditional<true, A, B>::Type is A;
78 * mozilla::Conditional<false, A, B>::Type is B;
80 template<bool condition, class A, class B>
81 struct Conditional
83 typedef A Type;
86 template<class A, class B>
87 struct Conditional<false, A, B>
89 typedef B Type;
93 * EnableIf is a struct containing a typedef of T if and only if B is true.
95 * mozilla::EnableIf<true, int>::Type is int;
96 * mozilla::EnableIf<false, int>::Type is a compile-time error.
98 * Use this template to implement SFINAE-style (Substitution Failure Is not An
99 * Error) requirements. For example, you might use it to impose a restriction
100 * on a template parameter:
102 * template<typename T>
103 * class PodVector // vector optimized to store POD (memcpy-able) types
105 * EnableIf<IsPodType<T>, T>::Type* vector;
106 * size_t length;
107 * ...
108 * };
110 template<bool B, typename T = void>
111 struct EnableIf
114 template<typename T>
115 struct EnableIf<true, T>
117 typedef T Type;
120 } /* namespace mozilla */
122 #endif /* mozilla_TypeTraits_h_ */