Nvwa  1.1
bool_array.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
2 // vim:tabstop=4:shiftwidth=4:expandtab:
3 
4 /*
5  * Copyright (C) 2004-2014 Wu Yongwei <adah at users dot sourceforge dot net>
6  *
7  * This software is provided 'as-is', without any express or implied
8  * warranty. In no event will the authors be held liable for any
9  * damages arising from the use of this software.
10  *
11  * Permission is granted to anyone to use this software for any purpose,
12  * including commercial applications, and to alter it and redistribute
13  * it freely, subject to the following restrictions:
14  *
15  * 1. The origin of this software must not be misrepresented; you must
16  * not claim that you wrote the original software. If you use this
17  * software in a product, an acknowledgement in the product
18  * documentation would be appreciated but is not required.
19  * 2. Altered source versions must be plainly marked as such, and must
20  * not be misrepresented as being the original software.
21  * 3. This notice may not be removed or altered from any source
22  * distribution.
23  *
24  * This file is part of Stones of Nvwa:
25  * http://sourceforge.net/projects/nvwa
26  *
27  */
28 
37 #ifndef NVWA_BOOL_ARRAY_H
38 #define NVWA_BOOL_ARRAY_H
39 
40 #include <assert.h> // assert
41 #include <stdlib.h> // exit/free/NULL
42 #include <new> // std::bad_alloc
43 #include <stdexcept> // std::out_of_range
44 #include <string> // for exception constructors
45 #include "_nvwa.h" // NVWA_NAMESPACE_*
46 #include "c++11.h" // _NOEXCEPT/_NULLPTR
47 
48 NVWA_NAMESPACE_BEGIN
49 
70 {
71 public:
72 #if (defined(__x86_64) || defined(__ia64) || defined(__ppc64__) || \
73  defined(_WIN64) || defined(_M_IA64)) && \
74  !(defined(_LP64) || defined(__lp64))
75 
76  typedef unsigned long long size_type;
77 #else
78 
79  typedef unsigned long size_type;
80 #endif
81 
82 private:
84  typedef unsigned char byte;
85 
87  template <typename _Byte_type>
88  class _Element
89  {
90  public:
91  _Element(_Byte_type* ptr, size_type pos);
92  bool operator=(bool value);
93  operator bool() const;
94  private:
95  _Byte_type* _M_byte_ptr;
96  size_t _M_byte_pos;
97  size_t _M_bit_pos;
98  };
99 
100 public:
103 
104 #if defined(_MSC_VER) && _MSC_VER < 1300
105  enum { npos = (size_type)-1 };
106 #else
107 
108  static const size_type npos = (size_type)-1;
109 #endif
110 
111  bool_array() _NOEXCEPT;
112  explicit bool_array(size_type size);
113  bool_array(const void* ptr, size_type size);
114  ~bool_array();
115 
116  bool_array(const bool_array& rhs);
117  bool_array& operator=(const bool_array& rhs);
118 
119  bool create(size_type size) _NOEXCEPT;
120  void initialize(bool value) _NOEXCEPT;
121 
122  reference operator[](size_type pos);
123  const_reference operator[](size_type pos) const;
124 
125  bool at(size_type pos) const;
126  void reset(size_type pos);
127  void set(size_type pos);
128 
129  size_type size() const _NOEXCEPT;
130  size_type count() const _NOEXCEPT;
131  size_type count(size_type begin, size_type end = npos) const;
132  size_type find(bool value, size_type offset = 0) const;
133  size_type find(bool value, size_type offset, size_type count) const;
134  size_type find_until(bool value, size_type begin, size_type end) const;
135 
136  void flip() _NOEXCEPT;
137  void swap(bool_array& rhs) _NOEXCEPT;
138  void merge_and(const bool_array& rhs,
139  size_type begin = 0,
140  size_type end = npos,
141  size_type offset = 0);
142  void merge_or (const bool_array& rhs,
143  size_type begin = 0,
144  size_type end = npos,
145  size_type offset = 0);
146  void copy_to_bitmap(void* dest, size_type begin = 0, size_type end = npos);
147 
148  static size_t get_num_bytes_from_bits(size_type num_bits);
149 
150 private:
151  byte get_8bits(size_type offset, size_type end) const;
152 
153  byte* _M_byte_ptr;
154  size_type _M_length;
155  static byte _S_bit_count[256];
156  static byte _S_bit_ordinal[256];
157 };
158 
159 
160 /* Inline functions */
161 
168 template <typename _Byte_type>
169 inline bool_array::_Element<_Byte_type>::_Element(
170  _Byte_type* ptr,
171  size_type pos)
172 {
173  _M_byte_ptr = ptr;
174  _M_byte_pos = (size_t)(pos / 8);
175  _M_bit_pos = (size_t)(pos % 8);
176 }
177 
184 template <typename _Byte_type>
186 {
187  if (value)
188  *(_M_byte_ptr + _M_byte_pos) |= 1 << _M_bit_pos;
189  else
190  *(_M_byte_ptr + _M_byte_pos) &= ~(1 << _M_bit_pos);
191  return value;
192 }
193 
199 template <typename _Byte_type>
201 {
202  return *(_M_byte_ptr + _M_byte_pos) & (1 << _M_bit_pos) ? true : false;
203 }
204 
208 inline bool_array::bool_array() _NOEXCEPT : _M_byte_ptr(_NULLPTR), _M_length(0)
209 {
210 }
211 
215 inline bool_array::~bool_array()
216 {
217  if (_M_byte_ptr != _NULLPTR)
218  free(_M_byte_ptr);
219 }
220 
227 inline bool_array::reference bool_array::operator[](size_type pos)
228 {
229  assert(_M_byte_ptr);
230  assert(pos < _M_length);
231  return reference(_M_byte_ptr, pos);
232 }
233 
240 inline bool_array::const_reference bool_array::operator[](size_type pos) const
241 {
242  assert(_M_byte_ptr);
243  assert(pos < _M_length);
244  return const_reference(_M_byte_ptr, pos);
245 }
246 
254 inline bool bool_array::at(size_type pos) const
255 {
256  size_t byte_pos, bit_pos;
257  if (pos >= _M_length)
258  throw std::out_of_range("invalid bool_array position");
259  byte_pos = (size_t)(pos / 8);
260  bit_pos = (size_t)(pos % 8);
261  return *(_M_byte_ptr + byte_pos) & (1 << bit_pos) ? true : false;
262 }
263 
270 inline void bool_array::reset(size_type pos)
271 {
272  size_t byte_pos, bit_pos;
273  if (pos >= _M_length)
274  throw std::out_of_range("invalid bool_array position");
275  byte_pos = (size_t)(pos / 8);
276  bit_pos = (size_t)(pos % 8);
277  *(_M_byte_ptr + byte_pos) &= ~(1 << bit_pos);
278 }
279 
286 inline void bool_array::set(size_type pos)
287 {
288  size_t byte_pos, bit_pos;
289  if (pos >= _M_length)
290  throw std::out_of_range("invalid bool_array position");
291  byte_pos = (size_t)(pos / 8);
292  bit_pos = (size_t)(pos % 8);
293  *(_M_byte_ptr + byte_pos) |= 1 << bit_pos;
294 }
295 
301 inline bool_array::size_type bool_array::size() const _NOEXCEPT
302 {
303  return _M_length;
304 }
305 
315 inline bool_array::size_type bool_array::find(
316  bool value,
317  size_type offset) const
318 {
319  return find_until(value, offset, _M_length);
320 }
321 
333 inline bool_array::size_type bool_array::find(
334  bool value,
335  size_type offset,
336  size_type count) const
337 {
338  return find_until(value, offset, offset + count);
339 }
340 
347 inline size_t bool_array::get_num_bytes_from_bits(size_type num_bits)
348 {
349  return (size_t)((num_bits + 7) / 8);
350 }
351 
358 inline void swap(bool_array& lhs, bool_array& rhs) _NOEXCEPT
359 {
360  lhs.swap(rhs);
361 }
362 
363 NVWA_NAMESPACE_END
364 
365 #endif // NVWA_BOOL_ARRAY_H
_Element< const byte > const_reference
Type of const reference.
Definition: bool_array.h:102
unsigned long size_type
Type of array indices.
Definition: bool_array.h:79
Class to represent a packed boolean array.
Definition: bool_array.h:69
void swap(bool_array &lhs, bool_array &rhs) noexcept
Exchanges the content of two bool_arrays.
Definition: bool_array.h:358
unsigned char byte
Private definition of byte to avoid polluting the global namespace.
Definition: bool_array.h:84
Class to represent a reference to an array element.
Definition: bool_array.h:88
C++11 feature detection macros and workarounds.
_Element< byte > reference
Type of reference.
Definition: bool_array.h:101
Common definitions for preprocessing.