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 8namespace mojo { 9namespace internal { 10 11template<class T, T v> 12struct IntegralConstant { 13 static const T value = v; 14}; 15 16template <class T, T v> const T IntegralConstant<T, v>::value; 17 18typedef IntegralConstant<bool, true> TrueType; 19typedef IntegralConstant<bool, false> FalseType; 20 21template <class T> struct IsConst : FalseType {}; 22template <class T> struct IsConst<const T> : TrueType {}; 23 24template<bool B, typename T = void> 25struct EnableIf {}; 26 27template<typename T> 28struct EnableIf<true, T> { typedef T type; }; 29 30// Types YesType and NoType are guaranteed such that sizeof(YesType) < 31// sizeof(NoType). 32typedef char YesType; 33 34struct 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. 41template <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 52template <typename T> 53typename EnableIf<!IsMoveOnlyType<T>::value, T>::type& Forward(T& t) { 54 return t; 55} 56 57template <typename T> 58typename 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. 64template<typename, typename> struct IsSame { 65 static bool const value = false; 66}; 67template<typename A> struct IsSame<A, A> { 68 static bool const value = true; 69}; 70template<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