1 // -----------------------------------------------------------
\r
3 // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
\r
4 // Copyright (c) 2003-2006, 2008 Gennaro Prota
\r
6 // Distributed under the Boost Software License, Version 1.0.
\r
7 // (See accompanying file LICENSE_1_0.txt or copy at
\r
8 // http://www.boost.org/LICENSE_1_0.txt)
\r
10 // -----------------------------------------------------------
\r
12 #ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
\r
13 #define BOOST_DETAIL_DYNAMIC_BITSET_HPP
\r
16 #include "boost/config.hpp"
\r
17 #include "boost/detail/workaround.hpp"
\r
23 namespace dynamic_bitset_impl {
\r
25 // Gives (read-)access to the object representation
\r
26 // of an object of type T (3.9p4). CANNOT be used
\r
27 // on a base sub-object
\r
29 template <typename T>
\r
30 inline const unsigned char * object_representation (T* p)
\r
32 return static_cast<const unsigned char *>(static_cast<const void *>(p));
\r
35 template<typename T, int amount, int width /* = default */>
\r
38 static void left_shift(T & v) {
\r
39 amount >= width ? (v = 0)
\r
40 : (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount));
\r
44 // ------- count function implementation --------------
\r
46 typedef unsigned char byte_type;
\r
48 // These two entities
\r
50 // enum mode { access_by_bytes, access_by_blocks };
\r
51 // template <mode> struct mode_to_type {};
\r
53 // were removed, since the regression logs (as of 24 Aug 2008)
\r
54 // showed that several compilers had troubles with recognizing
\r
56 // const mode m = access_by_bytes
\r
58 // as a constant expression
\r
60 // * So, we'll use bool, instead of enum *.
\r
62 template <bool value>
\r
63 struct value_to_type
\r
67 const bool access_by_bytes = true;
\r
68 const bool access_by_blocks = false;
\r
71 // the table: wrapped in a class template, so
\r
72 // that it is only instantiated if/when needed
\r
74 template <bool dummy_name = true>
\r
75 struct count_table { static const byte_type table[]; };
\r
78 struct count_table<false> { /* no table */ };
\r
81 const unsigned int table_width = 8;
\r
83 const byte_type count_table<b>::table[] =
\r
85 // Automatically generated by GPTableGen.exe v.1.0
\r
87 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,
\r
88 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,
\r
89 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,
\r
90 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,
\r
91 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,
\r
92 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,
\r
93 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,
\r
94 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
\r
98 // overload for access by bytes
\r
101 template <typename Iterator>
\r
102 inline std::size_t do_count(Iterator first, std::size_t length,
\r
103 int /*dummy param*/,
\r
104 value_to_type<access_by_bytes>* )
\r
106 std::size_t num = 0;
\r
109 const byte_type * p = object_representation(&*first);
\r
110 length *= sizeof(*first);
\r
113 num += count_table<>::table[*p];
\r
124 // overload for access by blocks
\r
126 template <typename Iterator, typename ValueType>
\r
127 inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
\r
128 value_to_type<access_by_blocks>*)
\r
130 std::size_t num = 0;
\r
133 ValueType value = *first;
\r
135 num += count_table<>::table[value & ((1u<<table_width) - 1)];
\r
136 value >>= table_width;
\r
146 // -------------------------------------------------------
\r
149 // Some library implementations simply return a dummy
\r
152 // size_type(-1) / sizeof(T)
\r
154 // from vector<>::max_size. This tries to get more
\r
155 // meaningful info.
\r
157 template <typename T>
\r
158 typename T::size_type vector_max_size_workaround(const T & v) {
\r
160 typedef typename T::allocator_type allocator_type;
\r
162 const typename allocator_type::size_type alloc_max =
\r
163 v.get_allocator().max_size();
\r
164 const typename T::size_type container_max = v.max_size();
\r
166 return alloc_max < container_max?
\r
171 // for static_asserts
\r
172 template <typename T>
\r
173 struct allowed_block_type {
\r
174 enum { value = T(-1) > 0 }; // ensure T has no sign
\r
178 struct allowed_block_type<bool> {
\r
179 enum { value = false };
\r
183 template <typename T>
\r
184 struct is_numeric {
\r
185 enum { value = false };
\r
188 # define BOOST_dynamic_bitset_is_numeric(x) \
\r
190 struct is_numeric< x > { \
\r
191 enum { value = true }; \
\r
194 BOOST_dynamic_bitset_is_numeric(bool);
\r
195 BOOST_dynamic_bitset_is_numeric(char);
\r
197 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
\r
198 BOOST_dynamic_bitset_is_numeric(wchar_t);
\r
201 BOOST_dynamic_bitset_is_numeric(signed char);
\r
202 BOOST_dynamic_bitset_is_numeric(short int);
\r
203 BOOST_dynamic_bitset_is_numeric(int);
\r
204 BOOST_dynamic_bitset_is_numeric(long int);
\r
206 BOOST_dynamic_bitset_is_numeric(unsigned char);
\r
207 BOOST_dynamic_bitset_is_numeric(unsigned short);
\r
208 BOOST_dynamic_bitset_is_numeric(unsigned int);
\r
209 BOOST_dynamic_bitset_is_numeric(unsigned long);
\r
211 #if defined(BOOST_HAS_LONG_LONG)
\r
212 BOOST_dynamic_bitset_is_numeric(::boost::long_long_type);
\r
213 BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type);
\r
216 // intentionally omitted
\r
217 //BOOST_dynamic_bitset_is_numeric(float);
\r
218 //BOOST_dynamic_bitset_is_numeric(double);
\r
219 //BOOST_dynamic_bitset_is_numeric(long double);
\r
221 #undef BOOST_dynamic_bitset_is_numeric
\r
223 } // dynamic_bitset_impl
\r
224 } // namespace detail
\r
226 } // namespace boost
\r
228 #endif // include guard
\r