traits.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef ANDROID_TRAITS_H
  17. #define ANDROID_TRAITS_H
  18. // -----------------------------------------------------------------------
  19. // Typelists
  20. namespace android {
  21. // end-of-list marker
  22. class NullType {};
  23. // type-list node
  24. template <typename T, typename U>
  25. struct TypeList {
  26. typedef T Head;
  27. typedef U Tail;
  28. };
  29. // helpers to build typelists
  30. #define TYPELIST_1(T1) TypeList<T1, NullType>
  31. #define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)>
  32. #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)>
  33. #define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4)>
  34. // typelists algorithms
  35. namespace TL {
  36. template <typename TList, typename T> struct IndexOf;
  37. template <typename T>
  38. struct IndexOf<NullType, T> {
  39. enum { value = -1 };
  40. };
  41. template <typename T, typename Tail>
  42. struct IndexOf<TypeList<T, Tail>, T> {
  43. enum { value = 0 };
  44. };
  45. template <typename Head, typename Tail, typename T>
  46. struct IndexOf<TypeList<Head, Tail>, T> {
  47. private:
  48. enum { temp = IndexOf<Tail, T>::value };
  49. public:
  50. enum { value = temp == -1 ? -1 : 1 + temp };
  51. };
  52. }; // namespace TL
  53. // type selection based on a boolean
  54. template <bool flag, typename T, typename U>
  55. struct Select {
  56. typedef T Result;
  57. };
  58. template <typename T, typename U>
  59. struct Select<false, T, U> {
  60. typedef U Result;
  61. };
  62. // -----------------------------------------------------------------------
  63. // Type traits
  64. template <typename T>
  65. class TypeTraits {
  66. typedef TYPELIST_4(
  67. unsigned char, unsigned short,
  68. unsigned int, unsigned long int) UnsignedInts;
  69. typedef TYPELIST_4(
  70. signed char, signed short,
  71. signed int, signed long int) SignedInts;
  72. typedef TYPELIST_1(
  73. bool) OtherInts;
  74. typedef TYPELIST_3(
  75. float, double, long double) Floats;
  76. template<typename U> struct PointerTraits {
  77. enum { result = false };
  78. typedef NullType PointeeType;
  79. };
  80. template<typename U> struct PointerTraits<U*> {
  81. enum { result = true };
  82. typedef U PointeeType;
  83. };
  84. public:
  85. enum { isStdUnsignedInt = TL::IndexOf<UnsignedInts, T>::value >= 0 };
  86. enum { isStdSignedInt = TL::IndexOf<SignedInts, T>::value >= 0 };
  87. enum { isStdIntegral = TL::IndexOf<OtherInts, T>::value >= 0 || isStdUnsignedInt || isStdSignedInt };
  88. enum { isStdFloat = TL::IndexOf<Floats, T>::value >= 0 };
  89. enum { isPointer = PointerTraits<T>::result };
  90. enum { isStdArith = isStdIntegral || isStdFloat };
  91. // best parameter type for given type
  92. typedef typename Select<isStdArith || isPointer, T, const T&>::Result ParameterType;
  93. };
  94. // -----------------------------------------------------------------------
  95. }; // namespace android
  96. #endif /* ANDROID_TRAITS_H */