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 namespace mojo { 9 namespace internal { 10 11 template<class T, T v> 12 struct IntegralConstant { 13 static const T value = v; 14 }; 15 16 template <class T, T v> const T IntegralConstant<T, v>::value; 17 18 typedef IntegralConstant<bool, true> TrueType; 19 typedef IntegralConstant<bool, false> FalseType; 20 21 template <class T> struct IsConst : FalseType {}; 22 template <class T> struct IsConst<const T> : TrueType {}; 23 24 template<bool B, typename T = void> 25 struct EnableIf {}; 26 27 template<typename T> 28 struct EnableIf<true, T> { typedef T type; }; 29 30 // Types YesType and NoType are guaranteed such that sizeof(YesType) < 31 // sizeof(NoType). 32 typedef char YesType; 33 34 struct NoType { 35 YesType dummy[2]; 36 }; 37 38 // A helper template to determine if given type is non-const move-only-type, 39 // i.e. if a value of the given type should be passed via .Pass() in a 40 // destructive way. 41 template <typename T> struct IsMoveOnlyType { 42 template <typename U> 43 static YesType Test(const typename U::MoveOnlyTypeForCPP03*); 44 45 template <typename U> 46 static NoType Test(...); 47 48 static const bool value = sizeof(Test<T>(0)) == sizeof(YesType) && 49 !IsConst<T>::value; 50 }; 51 52 template <typename T> 53 typename EnableIf<!IsMoveOnlyType<T>::value, T>::type& Forward(T& t) { 54 return t; 55 } 56 57 template <typename T> 58 typename EnableIf<IsMoveOnlyType<T>::value, T>::type Forward(T& t) { 59 return t.Pass(); 60 } 61 62 // This goop is a trick used to implement a template that can be used to 63 // determine if a given class is the base class of another given class. 64 template<typename, typename> struct IsSame { 65 static bool const value = false; 66 }; 67 template<typename A> struct IsSame<A, A> { 68 static bool const value = true; 69 }; 70 template<typename Base, typename Derived> struct IsBaseOf { 71 private: 72 // This class doesn't work correctly with forward declarations. 73 // Because sizeof cannot be applied to incomplete types, this line prevents us 74 // from passing in forward declarations. 75 typedef char (*EnsureTypesAreComplete)[sizeof(Base) + sizeof(Derived)]; 76 77 static Derived* CreateDerived(); 78 static char (&Check(Base*))[1]; 79 static char (&Check(...))[2]; 80 81 public: 82 static bool const value = sizeof Check(CreateDerived()) == 1 && 83 !IsSame<Base const, void const>::value; 84 }; 85 86 } // namespace internal 87 } // namespace mojo 88 89 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_TEMPLATE_UTIL_H_ 90