1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_ 7 8 #include <type_traits> 9 10 namespace mojo { 11 namespace internal { 12 13 template <class T, T v> 14 struct IntegralConstant { 15 static const T value = v; 16 }; 17 18 template <class T, T v> 19 const T IntegralConstant<T, v>::value; 20 21 typedef IntegralConstant<bool, true> TrueType; 22 typedef IntegralConstant<bool, false> FalseType; 23 24 template <class T> 25 struct IsConst : FalseType {}; 26 template <class T> 27 struct IsConst<const T> : TrueType {}; 28 29 template <class T> 30 struct IsPointer : FalseType {}; 31 template <class T> 32 struct IsPointer<T*> : TrueType {}; 33 34 template <bool B, typename T = void> 35 struct EnableIf {}; 36 37 template <typename T> 38 struct EnableIf<true, T> { 39 typedef T type; 40 }; 41 42 // Types YesType and NoType are guaranteed such that sizeof(YesType) < 43 // sizeof(NoType). 44 typedef char YesType; 45 46 struct NoType { 47 YesType dummy[2]; 48 }; 49 50 // A helper template to determine if given type is non-const move-only-type, 51 // i.e. if a value of the given type should be passed via std::move() in a 52 // destructive way. 53 template <typename T> 54 struct IsMoveOnlyType { 55 static const bool value = std::is_constructible<T, T&&>::value && 56 !std::is_constructible<T, const T&>::value; 57 }; 58 59 // This goop is a trick used to implement a template that can be used to 60 // determine if a given class is the base class of another given class. 61 template <typename, typename> 62 struct IsSame { 63 static bool const value = false; 64 }; 65 template <typename A> 66 struct IsSame<A, A> { 67 static bool const value = true; 68 }; 69 70 template <typename T> 71 struct EnsureTypeIsComplete { 72 // sizeof() cannot be applied to incomplete types, this line will fail 73 // compilation if T is forward declaration. 74 using CheckSize = char (*)[sizeof(T)]; 75 }; 76 77 template <typename Base, typename Derived> 78 struct IsBaseOf { 79 private: 80 static Derived* CreateDerived(); 81 static char(&Check(Base*))[1]; 82 static char(&Check(...))[2]; 83 84 EnsureTypeIsComplete<Base> check_base_; 85 EnsureTypeIsComplete<Derived> check_derived_; 86 87 public: 88 static bool const value = sizeof Check(CreateDerived()) == 1 && 89 !IsSame<Base const, void const>::value; 90 }; 91 92 template <class T> 93 struct RemovePointer { 94 typedef T type; 95 }; 96 template <class T> 97 struct RemovePointer<T*> { 98 typedef T type; 99 }; 100 101 template <template <typename...> class Template, typename T> 102 struct IsSpecializationOf : FalseType {}; 103 104 template <template <typename...> class Template, typename... Args> 105 struct IsSpecializationOf<Template, Template<Args...>> : TrueType {}; 106 107 template <bool B, typename T, typename F> 108 struct Conditional { 109 typedef T type; 110 }; 111 112 template <typename T, typename F> 113 struct Conditional<false, T, F> { 114 typedef F type; 115 }; 116 117 template <typename T> 118 struct AlwaysFalse { 119 static const bool value = false; 120 }; 121 122 } // namespace internal 123 } // namespace mojo 124 125 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_ 126