00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #ifndef NVWA_BOOL_ARRAY_H
00038 #define NVWA_BOOL_ARRAY_H
00039
00040 #include <assert.h>
00041 #include <stdlib.h>
00042 #include <new>
00043 #include <stdexcept>
00044 #include <string>
00045 #include "_nvwa.h"
00046 #include "c++11.h"
00047
00048 NVWA_NAMESPACE_BEGIN
00049
00069 class bool_array
00070 {
00071 public:
00072 #if (defined(__x86_64) || defined(__ia64) || defined(__ppc64__) || \
00073 defined(_WIN64) || defined(_M_IA64)) && \
00074 !(defined(_LP64) || defined(__lp64))
00075
00076 typedef unsigned long long size_type;
00077 #else
00078
00079 typedef unsigned long size_type;
00080 #endif
00081
00082 private:
00084 typedef unsigned char byte;
00085
00087 template <typename _Byte_type>
00088 class _Element
00089 {
00090 public:
00091 _Element(_Byte_type* ptr, size_type pos);
00092 bool operator=(bool value);
00093 operator bool() const;
00094 private:
00095 _Byte_type* _M_byte_ptr;
00096 size_t _M_byte_pos;
00097 size_t _M_bit_pos;
00098 };
00099
00100 public:
00101 typedef _Element<byte> reference;
00102 typedef _Element<const byte> const_reference;
00103
00104 #if defined(_MSC_VER) && _MSC_VER < 1300
00105 enum { npos = (size_type)-1 };
00106 #else
00107
00108 static const size_type npos = (size_type)-1;
00109 #endif
00110
00111 bool_array() _NOEXCEPT;
00112 explicit bool_array(size_type size);
00113 bool_array(const void* ptr, size_type size);
00114 ~bool_array();
00115
00116 bool_array(const bool_array& rhs);
00117 bool_array& operator=(const bool_array& rhs);
00118
00119 bool create(size_type size) _NOEXCEPT;
00120 void initialize(bool value) _NOEXCEPT;
00121
00122 reference operator[](size_type pos);
00123 const_reference operator[](size_type pos) const;
00124
00125 bool at(size_type pos) const;
00126 void reset(size_type pos);
00127 void set(size_type pos);
00128
00129 size_type size() const _NOEXCEPT;
00130 size_type count() const _NOEXCEPT;
00131 size_type count(size_type begin, size_type end = npos) const;
00132 size_type find(bool value, size_type offset = 0) const;
00133 size_type find(bool value, size_type offset, size_type count) const;
00134 size_type find_until(bool value, size_type begin, size_type end) const;
00135
00136 void flip() _NOEXCEPT;
00137 void swap(bool_array& rhs) _NOEXCEPT;
00138 void merge_and(const bool_array& rhs,
00139 size_type begin = 0,
00140 size_type end = npos,
00141 size_type offset = 0);
00142 void merge_or (const bool_array& rhs,
00143 size_type begin = 0,
00144 size_type end = npos,
00145 size_type offset = 0);
00146 void copy_to_bitmap(void* dest, size_type begin = 0, size_type end = npos);
00147
00148 static size_t get_num_bytes_from_bits(size_type num_bits);
00149
00150 private:
00151 byte get_8bits(size_type offset, size_type end) const;
00152
00153 byte* _M_byte_ptr;
00154 size_type _M_length;
00155 static byte _S_bit_count[256];
00156 static byte _S_bit_ordinal[256];
00157 };
00158
00159
00160
00161
00168 template <typename _Byte_type>
00169 inline bool_array::_Element<_Byte_type>::_Element(
00170 _Byte_type* ptr,
00171 size_type pos)
00172 {
00173 _M_byte_ptr = ptr;
00174 _M_byte_pos = (size_t)(pos / 8);
00175 _M_bit_pos = (size_t)(pos % 8);
00176 }
00177
00184 template <typename _Byte_type>
00185 inline bool bool_array::_Element<_Byte_type>::operator=(bool value)
00186 {
00187 if (value)
00188 *(_M_byte_ptr + _M_byte_pos) |= 1 << _M_bit_pos;
00189 else
00190 *(_M_byte_ptr + _M_byte_pos) &= ~(1 << _M_bit_pos);
00191 return value;
00192 }
00193
00199 template <typename _Byte_type>
00200 inline bool_array::_Element<_Byte_type>::operator bool() const
00201 {
00202 return *(_M_byte_ptr + _M_byte_pos) & (1 << _M_bit_pos) ? true : false;
00203 }
00204
00208 inline bool_array::bool_array() _NOEXCEPT : _M_byte_ptr(NULL), _M_length(0)
00209 {
00210 }
00211
00215 inline bool_array::~bool_array()
00216 {
00217 if (_M_byte_ptr != NULL)
00218 free(_M_byte_ptr);
00219 }
00220
00227 inline bool_array::reference bool_array::operator[](size_type pos)
00228 {
00229 assert(_M_byte_ptr);
00230 assert(pos < _M_length);
00231 return reference(_M_byte_ptr, pos);
00232 }
00233
00240 inline bool_array::const_reference bool_array::operator[](size_type pos) const
00241 {
00242 assert(_M_byte_ptr);
00243 assert(pos < _M_length);
00244 return const_reference(_M_byte_ptr, pos);
00245 }
00246
00254 inline bool bool_array::at(size_type pos) const
00255 {
00256 size_t byte_pos, bit_pos;
00257 if (pos >= _M_length)
00258 throw std::out_of_range("invalid bool_array position");
00259 byte_pos = (size_t)(pos / 8);
00260 bit_pos = (size_t)(pos % 8);
00261 return *(_M_byte_ptr + byte_pos) & (1 << bit_pos) ? true : false;
00262 }
00263
00270 inline void bool_array::reset(size_type pos)
00271 {
00272 size_t byte_pos, bit_pos;
00273 if (pos >= _M_length)
00274 throw std::out_of_range("invalid bool_array position");
00275 byte_pos = (size_t)(pos / 8);
00276 bit_pos = (size_t)(pos % 8);
00277 *(_M_byte_ptr + byte_pos) &= ~(1 << bit_pos);
00278 }
00279
00286 inline void bool_array::set(size_type pos)
00287 {
00288 size_t byte_pos, bit_pos;
00289 if (pos >= _M_length)
00290 throw std::out_of_range("invalid bool_array position");
00291 byte_pos = (size_t)(pos / 8);
00292 bit_pos = (size_t)(pos % 8);
00293 *(_M_byte_ptr + byte_pos) |= 1 << bit_pos;
00294 }
00295
00301 inline bool_array::size_type bool_array::size() const _NOEXCEPT
00302 {
00303 return _M_length;
00304 }
00305
00315 inline bool_array::size_type bool_array::find(
00316 bool value,
00317 size_type offset) const
00318 {
00319 return find_until(value, offset, _M_length);
00320 }
00321
00333 inline bool_array::size_type bool_array::find(
00334 bool value,
00335 size_type offset,
00336 size_type count) const
00337 {
00338 return find_until(value, offset, offset + count);
00339 }
00340
00347 inline size_t bool_array::get_num_bytes_from_bits(size_type num_bits)
00348 {
00349 return (size_t)((num_bits + 7) / 8);
00350 }
00351
00358 inline void swap(bool_array& lhs, bool_array& rhs) _NOEXCEPT
00359 {
00360 lhs.swap(rhs);
00361 }
00362
00363 NVWA_NAMESPACE_END
00364
00365 #endif // NVWA_BOOL_ARRAY_H