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