00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
00012 #define BOOST_DETAIL_DYNAMIC_BITSET_HPP
00013
00014 #include "boost/config.hpp"
00015 #include "boost/detail/iterator.hpp"
00016
00017 #if !(defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || defined(__BORLANDC__))
00018 #define BOOST_DYN_BITSET_USE_FRIENDS
00019 #endif
00020
00021 namespace boost {
00022
00023 namespace detail {
00024
00025
00026 template <typename BlockInputIterator>
00027 std::size_t initial_num_blocks(BlockInputIterator first,
00028 BlockInputIterator last,
00029 std::input_iterator_tag);
00030 template <typename BlockForwardIterator>
00031 std::size_t initial_num_blocks(BlockForwardIterator first,
00032 BlockForwardIterator last,
00033 std::forward_iterator_tag);
00034
00035
00036
00037 template <typename Allocator>
00038 class dynamic_bitset_alloc_base {
00039 public:
00040 dynamic_bitset_alloc_base(const Allocator& alloc)
00041 : m_alloc(alloc) { }
00042 protected:
00043 Allocator m_alloc;
00044 };
00045
00046
00047 template <typename Block, typename Allocator>
00048 class dynamic_bitset_base :
00049 #ifdef BOOST_DYN_BITSET_USE_FRIENDS
00050 protected
00051 #else
00052 public
00053 #endif
00054 dynamic_bitset_alloc_base<Allocator>
00055 {
00056 typedef std::size_t size_type;
00057 #ifndef BOOST_DYN_BITSET_USE_FRIENDS
00058 public:
00059 #endif
00060 enum { bits_per_block = CHAR_BIT * sizeof(Block) };
00061 public:
00062 dynamic_bitset_base()
00063 : m_bits(0), m_num_bits(0), m_num_blocks(0) { }
00064
00065 dynamic_bitset_base(size_type num_bits, const Allocator& alloc)
00066 : dynamic_bitset_alloc_base<Allocator>(alloc),
00067 m_bits(dynamic_bitset_alloc_base<Allocator>::
00068 m_alloc.allocate(calc_num_blocks(num_bits), static_cast<void const *>(0))),
00069 m_num_bits(num_bits),
00070 m_num_blocks(calc_num_blocks(num_bits))
00071 {
00072 using namespace std;
00073 memset(m_bits, 0, m_num_blocks * sizeof(Block));
00074 }
00075 ~dynamic_bitset_base() {
00076 if (m_bits)
00077 this->m_alloc.deallocate(m_bits, m_num_blocks);
00078 }
00079 #ifdef BOOST_DYN_BITSET_USE_FRIENDS
00080 protected:
00081 #endif
00082 Block* m_bits;
00083 size_type m_num_bits;
00084 size_type m_num_blocks;
00085
00086 static size_type word(size_type bit) { return bit / bits_per_block; }
00087 static size_type offset(size_type bit){ return bit % bits_per_block; }
00088 static Block mask1(size_type bit) { return Block(1) << offset(bit); }
00089 static Block mask0(size_type bit) { return ~(Block(1) << offset(bit)); }
00090 static size_type calc_num_blocks(size_type num_bits)
00091 { return (num_bits + bits_per_block - 1) / bits_per_block; }
00092 };
00093
00094
00095
00096
00097 typedef unsigned char byte_t;
00098
00099
00100 #if 0
00101
00102 template <bool = true> struct count;
00103 template <> struct count <true> {
00104 #else
00105 template <bool bogus = true>
00106 struct count {
00107 #endif
00108 typedef byte_t element_type;
00109 static const byte_t table[];
00110 BOOST_STATIC_CONSTANT (unsigned int, max_bit = 8);
00111
00112 };
00113
00114
00115
00116
00117
00118
00119 #if 0
00120
00121 template <>
00122 const byte_t count <true>::table[] =
00123 #else
00124 template <bool bogus>
00125 const byte_t count<bogus>::table[] =
00126 #endif
00127 {
00128
00129
00130 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,
00131 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,
00132 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,
00133 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,
00134 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,
00135 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,
00136 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,
00137 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
00138 };
00139
00140
00141
00142
00143 template <typename BlockInputIterator>
00144 std::size_t initial_num_blocks(BlockInputIterator first,
00145 BlockInputIterator last,
00146 std::input_iterator_tag)
00147 {
00148 return 0;
00149 }
00150
00151 template <typename BlockForwardIterator>
00152 std::size_t initial_num_blocks(BlockForwardIterator first,
00153 BlockForwardIterator last,
00154 std::forward_iterator_tag)
00155 {
00156 std::size_t n = 0;
00157 while (first != last)
00158 ++first, ++n;
00159 return n;
00160 }
00161
00162 template <typename BlockInputIterator>
00163 std::size_t initial_num_blocks(BlockInputIterator first,
00164 BlockInputIterator last)
00165 {
00166 typename detail::iterator_traits<BlockInputIterator>::iterator_category cat;
00167 return initial_num_blocks(first, last, cat);
00168 }
00169
00170
00171 }
00172
00173 }
00174
00175 #endif // BOOST_DETAIL_DYNAMIC_BITSET_HPP
00176