block_base.hpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* Copyright 2025 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See https://www.boost.org/libs/bloom for library home page.
  7. */
  8. #ifndef BOOST_BLOOM_DETAIL_BLOCK_BASE_HPP
  9. #define BOOST_BLOOM_DETAIL_BLOCK_BASE_HPP
  10. #include <boost/config.hpp>
  11. #include <boost/bloom/detail/constexpr_bit_width.hpp>
  12. #include <boost/bloom/detail/mulx64.hpp>
  13. #include <boost/bloom/detail/type_traits.hpp>
  14. #include <cstddef>
  15. #include <cstdint>
  16. namespace boost{
  17. namespace bloom{
  18. namespace detail{
  19. #if defined(BOOST_MSVC)
  20. #pragma warning(push)
  21. #pragma warning(disable:4714) /* marked as __forceinline not inlined */
  22. #endif
  23. /* Validates type Block and provides common looping facilities for block
  24. * and multiblock.
  25. */
  26. template<typename Block,std::size_t K>
  27. struct block_base
  28. {
  29. static_assert(
  30. is_unsigned_integral_or_extended_unsigned_integral<Block>::value||
  31. (
  32. is_array_of<
  33. Block,is_unsigned_integral_or_extended_unsigned_integral>::value&&
  34. is_power_of_two<array_size<Block>::value>::value
  35. ),
  36. "Block must be an (extended) unsigned integral type or an array T[N] "
  37. "with T an (extended) unsigned integral type and N a power of two");
  38. static constexpr std::size_t k=K;
  39. static constexpr std::size_t hash_width=sizeof(std::uint64_t)*CHAR_BIT;
  40. static constexpr std::size_t block_width=sizeof(Block)*CHAR_BIT;
  41. static constexpr std::size_t mask=block_width-1;
  42. static constexpr std::size_t shift=constexpr_bit_width(mask);
  43. static constexpr std::size_t rehash_k=(hash_width-shift)/shift;
  44. template<typename F>
  45. static BOOST_FORCEINLINE void loop(std::uint64_t hash,F f)
  46. {
  47. for(std::size_t i=0;i<k/rehash_k;++i){
  48. auto h=hash;
  49. for(std::size_t j=0;j<rehash_k;++j){
  50. h>>=shift;
  51. f(h);
  52. }
  53. hash=detail::mulx64(hash);
  54. }
  55. auto h=hash;
  56. for(std::size_t i=0;i<k%rehash_k;++i){
  57. h>>=shift;
  58. f(h);
  59. }
  60. }
  61. template<typename F>
  62. static BOOST_FORCEINLINE bool loop_while(std::uint64_t hash,F f)
  63. {
  64. for(std::size_t i=0;i<k/rehash_k;++i){
  65. auto h=hash;
  66. for(std::size_t j=0;j<rehash_k;++j){
  67. h>>=shift;
  68. if(!f(h))return false;
  69. }
  70. hash=detail::mulx64(hash);
  71. }
  72. auto h=hash;
  73. for(std::size_t i=0;i<k%rehash_k;++i){
  74. h>>=shift;
  75. if(!f(h))return false;
  76. }
  77. return true;
  78. }
  79. };
  80. #if defined(BOOST_MSVC)
  81. #pragma warning(pop) /* C4714 */
  82. #endif
  83. } /* namespace detail */
  84. } /* namespace bloom */
  85. } /* namespace boost */
  86. #endif