dynamic_bitset.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // -----------------------------------------------------------
  2. //
  3. // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
  4. // Copyright (c) 2003-2006, 2008 Gennaro Prota
  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. // -----------------------------------------------------------
  11. #ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
  12. #define BOOST_DETAIL_DYNAMIC_BITSET_HPP
  13. #include <cstddef>
  14. #include "boost/config.hpp"
  15. #include "boost/detail/workaround.hpp"
  16. namespace boost {
  17. namespace detail {
  18. namespace dynamic_bitset_impl {
  19. // Gives (read-)access to the object representation
  20. // of an object of type T (3.9p4). CANNOT be used
  21. // on a base sub-object
  22. //
  23. template <typename T>
  24. inline const unsigned char * object_representation (T* p)
  25. {
  26. return static_cast<const unsigned char *>(static_cast<const void *>(p));
  27. }
  28. template<typename T, int amount, int width /* = default */>
  29. struct shifter
  30. {
  31. static void left_shift(T & v) {
  32. amount >= width ? (v = 0)
  33. : (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount));
  34. }
  35. };
  36. // ------- count function implementation --------------
  37. typedef unsigned char byte_type;
  38. // These two entities
  39. //
  40. // enum mode { access_by_bytes, access_by_blocks };
  41. // template <mode> struct mode_to_type {};
  42. //
  43. // were removed, since the regression logs (as of 24 Aug 2008)
  44. // showed that several compilers had troubles with recognizing
  45. //
  46. // const mode m = access_by_bytes
  47. //
  48. // as a constant expression
  49. //
  50. // * So, we'll use bool, instead of enum *.
  51. //
  52. template <bool value>
  53. struct value_to_type
  54. {
  55. value_to_type() {}
  56. };
  57. const bool access_by_bytes = true;
  58. const bool access_by_blocks = false;
  59. // the table: wrapped in a class template, so
  60. // that it is only instantiated if/when needed
  61. //
  62. template <bool dummy_name = true>
  63. struct count_table { static const byte_type table[]; };
  64. template <>
  65. struct count_table<false> { /* no table */ };
  66. const unsigned int table_width = 8;
  67. template <bool b>
  68. const byte_type count_table<b>::table[] =
  69. {
  70. // Automatically generated by GPTableGen.exe v.1.0
  71. //
  72. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  73. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  74. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  75. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  76. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  77. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  78. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  79. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
  80. };
  81. // overload for access by bytes
  82. //
  83. template <typename Iterator>
  84. inline std::size_t do_count(Iterator first, std::size_t length,
  85. int /*dummy param*/,
  86. value_to_type<access_by_bytes>* )
  87. {
  88. std::size_t num = 0;
  89. if (length)
  90. {
  91. const byte_type * p = object_representation(&*first);
  92. length *= sizeof(*first);
  93. do {
  94. num += count_table<>::table[*p];
  95. ++p;
  96. --length;
  97. } while (length);
  98. }
  99. return num;
  100. }
  101. // overload for access by blocks
  102. //
  103. template <typename Iterator, typename ValueType>
  104. inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
  105. value_to_type<access_by_blocks>*)
  106. {
  107. std::size_t num = 0;
  108. while (length){
  109. ValueType value = *first;
  110. while (value) {
  111. num += count_table<>::table[value & ((1u<<table_width) - 1)];
  112. value >>= table_width;
  113. }
  114. ++first;
  115. --length;
  116. }
  117. return num;
  118. }
  119. // -------------------------------------------------------
  120. // Some library implementations simply return a dummy
  121. // value such as
  122. //
  123. // size_type(-1) / sizeof(T)
  124. //
  125. // from vector<>::max_size. This tries to get more
  126. // meaningful info.
  127. //
  128. template <typename T>
  129. typename T::size_type vector_max_size_workaround(const T & v) {
  130. typedef typename T::allocator_type allocator_type;
  131. const typename allocator_type::size_type alloc_max =
  132. v.get_allocator().max_size();
  133. const typename T::size_type container_max = v.max_size();
  134. return alloc_max < container_max?
  135. alloc_max :
  136. container_max;
  137. }
  138. // for static_asserts
  139. template <typename T>
  140. struct allowed_block_type {
  141. enum { value = T(-1) > 0 }; // ensure T has no sign
  142. };
  143. template <>
  144. struct allowed_block_type<bool> {
  145. enum { value = false };
  146. };
  147. template <typename T>
  148. struct is_numeric {
  149. enum { value = false };
  150. };
  151. # define BOOST_dynamic_bitset_is_numeric(x) \
  152. template<> \
  153. struct is_numeric< x > { \
  154. enum { value = true }; \
  155. } /**/
  156. BOOST_dynamic_bitset_is_numeric(bool);
  157. BOOST_dynamic_bitset_is_numeric(char);
  158. #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
  159. BOOST_dynamic_bitset_is_numeric(wchar_t);
  160. #endif
  161. BOOST_dynamic_bitset_is_numeric(signed char);
  162. BOOST_dynamic_bitset_is_numeric(short int);
  163. BOOST_dynamic_bitset_is_numeric(int);
  164. BOOST_dynamic_bitset_is_numeric(long int);
  165. BOOST_dynamic_bitset_is_numeric(unsigned char);
  166. BOOST_dynamic_bitset_is_numeric(unsigned short);
  167. BOOST_dynamic_bitset_is_numeric(unsigned int);
  168. BOOST_dynamic_bitset_is_numeric(unsigned long);
  169. #if defined(BOOST_HAS_LONG_LONG)
  170. BOOST_dynamic_bitset_is_numeric(::boost::long_long_type);
  171. BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type);
  172. #endif
  173. // intentionally omitted
  174. //BOOST_dynamic_bitset_is_numeric(float);
  175. //BOOST_dynamic_bitset_is_numeric(double);
  176. //BOOST_dynamic_bitset_is_numeric(long double);
  177. #undef BOOST_dynamic_bitset_is_numeric
  178. } // dynamic_bitset_impl
  179. } // namespace detail
  180. } // namespace boost
  181. #endif // include guard