TemplateLib.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim: set ts=8 sts=2 et sw=2 tw=80: */
  3. /* This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. /*
  7. * Reusable template meta-functions on types and compile-time values. Meta-
  8. * functions are placed inside the 'tl' namespace to avoid conflict with non-
  9. * meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs.
  10. * mozilla::FloorLog2).
  11. *
  12. * When constexpr support becomes universal, we should probably use that instead
  13. * of some of these templates, for simplicity.
  14. */
  15. #ifndef mozilla_TemplateLib_h
  16. #define mozilla_TemplateLib_h
  17. #include <limits.h>
  18. #include <stddef.h>
  19. #include "mozilla/TypeTraits.h"
  20. namespace mozilla {
  21. namespace tl {
  22. /** Compute min/max. */
  23. template<size_t I, size_t J>
  24. struct Min
  25. {
  26. static const size_t value = I < J ? I : J;
  27. };
  28. template<size_t I, size_t J>
  29. struct Max
  30. {
  31. static const size_t value = I > J ? I : J;
  32. };
  33. /** Compute floor(log2(i)). */
  34. template<size_t I>
  35. struct FloorLog2
  36. {
  37. static const size_t value = 1 + FloorLog2<I / 2>::value;
  38. };
  39. template<> struct FloorLog2<0> { /* Error */ };
  40. template<> struct FloorLog2<1> { static const size_t value = 0; };
  41. /** Compute ceiling(log2(i)). */
  42. template<size_t I>
  43. struct CeilingLog2
  44. {
  45. static const size_t value = FloorLog2<2 * I - 1>::value;
  46. };
  47. /** Round up to the nearest power of 2. */
  48. template<size_t I>
  49. struct RoundUpPow2
  50. {
  51. static const size_t value = size_t(1) << CeilingLog2<I>::value;
  52. };
  53. template<>
  54. struct RoundUpPow2<0>
  55. {
  56. static const size_t value = 1;
  57. };
  58. /** Compute the number of bits in the given unsigned type. */
  59. template<typename T>
  60. struct BitSize
  61. {
  62. static const size_t value = sizeof(T) * CHAR_BIT;
  63. };
  64. /**
  65. * Produce an N-bit mask, where N <= BitSize<size_t>::value. Handle the
  66. * language-undefined edge case when N = BitSize<size_t>::value.
  67. */
  68. template<size_t N>
  69. struct NBitMask
  70. {
  71. // Assert the precondition. On success this evaluates to 0. Otherwise it
  72. // triggers divide-by-zero at compile time: a guaranteed compile error in
  73. // C++11, and usually one in C++98. Add this value to |value| to assure
  74. // its computation.
  75. static const size_t checkPrecondition =
  76. 0 / size_t(N < BitSize<size_t>::value);
  77. static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
  78. };
  79. template<>
  80. struct NBitMask<BitSize<size_t>::value>
  81. {
  82. static const size_t value = size_t(-1);
  83. };
  84. /**
  85. * For the unsigned integral type size_t, compute a mask M for N such that
  86. * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t)
  87. */
  88. template<size_t N>
  89. struct MulOverflowMask
  90. {
  91. static const size_t value =
  92. ~NBitMask<BitSize<size_t>::value - CeilingLog2<N>::value>::value;
  93. };
  94. template<> struct MulOverflowMask<0> { /* Error */ };
  95. template<> struct MulOverflowMask<1> { static const size_t value = 0; };
  96. /**
  97. * And<bool...> computes the logical 'and' of its argument booleans.
  98. *
  99. * Examples:
  100. * mozilla::t1::And<true, true>::value is true.
  101. * mozilla::t1::And<true, false>::value is false.
  102. * mozilla::t1::And<>::value is true.
  103. */
  104. template<bool...>
  105. struct And;
  106. template<>
  107. struct And<> : public TrueType { };
  108. template<bool C1, bool... Cn>
  109. struct And<C1, Cn...>
  110. : public Conditional<C1, And<Cn...>, FalseType>::Type { };
  111. } // namespace tl
  112. } // namespace mozilla
  113. #endif /* mozilla_TemplateLib_h */