math_functions.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Stephen Cleary 2000.
  4. // (C) Copyright Ion Gaztanaga 2007-2012.
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/interprocess for documentation.
  11. //
  12. // This file is a slightly modified file from Boost.Pool
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #ifndef BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP
  16. #define BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP
  17. #ifndef BOOST_CONFIG_HPP
  18. # include <boost/config.hpp>
  19. #endif
  20. #
  21. #if defined(BOOST_HAS_PRAGMA_ONCE)
  22. # pragma once
  23. #endif
  24. #include <climits>
  25. #include <boost/static_assert.hpp>
  26. namespace boost {
  27. namespace interprocess {
  28. namespace ipcdetail {
  29. // Greatest common divisor and least common multiple
  30. //
  31. // gcd is an algorithm that calculates the greatest common divisor of two
  32. // integers, using Euclid's algorithm.
  33. //
  34. // Pre: A > 0 && B > 0
  35. // Recommended: A > B
  36. template <typename Integer>
  37. inline Integer gcd(Integer A, Integer B)
  38. {
  39. do
  40. {
  41. const Integer tmp(B);
  42. B = A % B;
  43. A = tmp;
  44. } while (B != 0);
  45. return A;
  46. }
  47. //
  48. // lcm is an algorithm that calculates the least common multiple of two
  49. // integers.
  50. //
  51. // Pre: A > 0 && B > 0
  52. // Recommended: A > B
  53. template <typename Integer>
  54. inline Integer lcm(const Integer & A, const Integer & B)
  55. {
  56. Integer ret = A;
  57. ret /= gcd(A, B);
  58. ret *= B;
  59. return ret;
  60. }
  61. template <typename Integer>
  62. inline Integer log2_ceil(const Integer & A)
  63. {
  64. Integer i = 0;
  65. Integer power_of_2 = 1;
  66. while(power_of_2 < A){
  67. power_of_2 <<= 1;
  68. ++i;
  69. }
  70. return i;
  71. }
  72. template <typename Integer>
  73. inline Integer upper_power_of_2(const Integer & A)
  74. {
  75. Integer power_of_2 = 1;
  76. while(power_of_2 < A){
  77. power_of_2 <<= 1;
  78. }
  79. return power_of_2;
  80. }
  81. //This function uses binary search to discover the
  82. //highest set bit of the integer
  83. inline std::size_t floor_log2 (std::size_t x)
  84. {
  85. const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
  86. const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
  87. BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
  88. std::size_t n = x;
  89. std::size_t log2 = 0;
  90. for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
  91. std::size_t tmp = n >> shift;
  92. if (tmp)
  93. log2 += shift, n = tmp;
  94. }
  95. return log2;
  96. }
  97. } // namespace ipcdetail
  98. } // namespace interprocess
  99. } // namespace boost
  100. #endif