1 /* ///////////////////////////////////////////////////////////////////////
7 * Brief: The bit_array class
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
13 #ifndef EXTL_CONTAINER_BIT_ARRAY_H
14 #define EXTL_CONTAINER_BIT_ARRAY_H
18 * \brief bit_array class
21 /* ///////////////////////////////////////////////////////////////////////
25 #include "../algorithm/algorithm.h"
26 #include "detail/bit_array_iterator.h"
27 #include "../memory/buffer.h"
28 #include "../string/string.h"
30 /* ///////////////////////////////////////////////////////////////////////
37 * \param Fld The field type
38 * \param Buf The buffer type
40 * \ingroup extl_group_container
42 #ifdef EXTL_TEMPLATE_CLASS_DEFAULT_ARGUMENT_SUPPORT
43 template< typename_param_k Fld
= e_size_t
44 , typename_param_k Buf
= typename_type_def_k buffer_selector
<Fld
>::buffer_type
47 template< typename_param_k Fld
48 , typename_param_k Buf
56 typedef bit_array class_type
;
57 typedef e_bool_t bool_type
;
58 typedef e_size_t size_type
;
59 typedef e_char_t achar_type
;
60 typedef e_wchar_t wchar_type
;
61 typedef size_type index_type
;
62 typedef bool_type value_type
;
63 typedef value_type
* pointer
;
64 typedef value_type
const* const_pointer
;
65 typedef value_type
& reference
;
66 typedef value_type
const& const_reference
;
67 typedef Fld field_type
;
68 typedef Buf buffer_type
;
69 typedef typename_type_k
buffer_type::allocator_type allocator_type
;
70 typedef EXTL_NS_DETAIL(const_bit_array_iterator
)<field_type
, buffer_type
> const_iterator
;
80 enum { en_field_bit_count
= 8 * sizeof(field_type
) };
82 /// \name Constructors
85 /// Default Constructor
91 bit_array(class_type
const& rhs
)
95 /// Constructs with n-bits values from the given array
96 bit_array(class_type
const& rhs
, size_type n
)
100 /// Constructs with n-bits default values
101 explicit_k
bit_array(size_type n
)
103 assign(value_type(), n
);
105 /// Constructs with n-bits given values
106 bit_array(const_reference value
, size_type n
)
110 /// Constructs with n-bits values from bool array
111 bit_array(const_pointer p
, size_type n
)
115 /// Constructs from ascii string with null-terminator
116 explicit_k
bit_array(achar_type
const* s
)
120 /// Constructs from unicode string with null-terminator
121 explicit_k
bit_array(wchar_type
const* s
)
125 /// Constructs with n-bits values from ascii string
126 bit_array(achar_type
const* s
, size_type n
)
130 /// Constructs with n-bits values from unicode string
131 bit_array(wchar_type
const* s
, size_type n
)
140 /// Returns the allocator of the array
141 allocator_type
allocator() const { return buffer().allocator(); }
142 /// Returns the bit count
143 size_type
size() const { return m_size
; }
144 /// Returns the reserved bit count in the array
145 size_type
capacity() const { return (buffer().capacity() * en_field_bit_count
); }
146 /// Return \c true if size() == 0
147 bool_type
is_empty() const { return 0 == m_size
; }
148 /// Return \c true if size() == 0
149 bool_type
empty() const { return is_empty(); }
150 /// Return the maximum bit count of the array
151 size_type
max_size() { return (buffer().max_size() * en_field_bit_count
); }
157 /// Returns the const begin iterator
158 const_iterator
begin() const { return const_iterator(&buffer(), 0); }
159 /// Returns the const end iterator
160 const_iterator
end() const { return const_iterator(&buffer(), size()); }
166 /// Returns the field value
167 field_type
const* data() const { return buffer().data(); }
168 /// Returns the field value
169 field_type
const* fields() const { return buffer().data(); }
170 /// Returns the numeric of this field
171 field_type
numeric() const;
172 /// Returns const value at the given index
173 value_type
const operator[](index_type index
) const { return get(index
); }
174 /// Returns const value at the given index and throws index_error() if index >= size()
175 value_type
const at(index_type index
) const;
176 /// Returns const value at the given index
177 value_type
const get(index_type index
) const;
178 /// Returns const value at the front of field
179 value_type
const front() const { return at(0); }
180 /// Returns const value at the back of field
181 value_type
const back() const { return at(size() - 1); }
187 /// Clears the field e.g. 001101 => null
188 void clear() { buffer().clear(); m_size
= 0; }
189 /// Cleans the field e.g. 001101 => 000000
190 void clean() { buffer().clean(); }
191 /// Swaps the content of array
192 void swap(class_type
& rhs
) { buffer().swap(rhs
.buffer()); std_swap(m_size
, rhs
.m_size
); }
193 /// Sets the value at the given position
194 void set(index_type index
, const_reference value
);
195 /// Resizes the bit count of the array
196 void resize(size_type n
, const_reference new_value
= value_type());
197 /// Pushes back the given value
198 void push_back(const_reference value
) { resize(size() + 1, value
); }
199 /// Pops back from this array
200 void pop_back() { resize(size() - 1); }
202 void numeric(field_type num
) { buffer().assign(num
, 1u); xtl_min(size_type(en_field_bit_count
), size()); }
205 /// \name Assignments
208 /// Assigns from the given value
209 class_type
& assign(const_reference value
) { return assign(value
, 1u); }
210 /// Assigns with n-bits given values
211 class_type
& assign(const_reference value
, size_type n
);
212 /// Assigns with n-bits values from bool array
213 class_type
& assign(const_pointer p
, size_type n
);
214 /// Assigns with n-bits values from ascii string
215 class_type
& assign(achar_type
const* s
, size_type n
);
216 /// Assigns with n-bits values from unicode string
217 class_type
& assign(wchar_type
const* s
, size_type n
);
218 /// Assigns from ascii string with null-terminator
219 class_type
& assign(achar_type
const* s
) { return assign(s
, (NULL
!= s
)? std_strlen(s
) : 0); }
220 /// Assigns from unicode string with null-terminator
221 class_type
& assign(wchar_type
const* s
) { return assign(s
, (NULL
!= s
)? std_strlen(s
) : 0); }
222 /// Assigns from the given field
223 class_type
& assign(class_type
const& rhs
, size_type n
);
224 /// Assigns from the given field
225 class_type
& assign(class_type
const& rhs
) { return assign(rhs
, rhs
.size()); }
226 /// Assigns from the given field
227 class_type
& operator =(class_type
const& rhs
) { return assign(rhs
); }
228 /// Assigns from the given value(fill all)
229 class_type
& operator =(const_reference value
) { return assign(value
); }
230 /// Assigns from ascii string with null-terminator
231 class_type
& operator =(achar_type
const* s
) { return assign(s
); }
232 /// Assigns from unicode string with null-terminator
233 class_type
& operator =(wchar_type
const* s
) { return assign(s
); }
239 /// Appends from the given value
240 class_type
& append(const_reference value
) { return append(value
, 1); }
241 /// Appends with n-bits given values
242 class_type
& append(const_reference value
, size_type n
);
243 /// Appends with n-bits values from bool array
244 class_type
& append(const_pointer p
, size_type n
);
245 /// Appends with n-bits values from ascii string
246 class_type
& append(achar_type
const* s
, size_type n
);
247 /// Appends with n-bits values from unicode string
248 class_type
& append(wchar_type
const* s
, size_type n
);
249 /// Appends from ascii string with null-terminator
250 class_type
& append(achar_type
const* s
) { return append(s
, (NULL
!= s
)? std_strlen(s
) : 0); }
251 /// Appends from unicode string with null-terminator
252 class_type
& append(wchar_type
const* s
) { return append(s
, (NULL
!= s
)? std_strlen(s
) : 0); }
253 /// Appends from the given field
254 class_type
& append(class_type
const& rhs
, size_type n
);
255 /// Appends from the given field
256 class_type
& append(class_type
const& rhs
) { return append(rhs
, rhs
.size()); }
257 /// Appends from the given field
258 class_type
& operator +=(class_type
const& rhs
) { return append(rhs
); }
259 /// Appends from the given value
260 class_type
& operator +=(const_reference value
) { return append(value
); }
261 /// Appends from ascii string with null-terminator
262 class_type
& operator +=(achar_type
const* s
) { return append(s
); }
263 /// Appends from unicode string with null-terminator
264 class_type
& operator +=(wchar_type
const* s
) { return append(s
); }
267 /// \name Replacements
270 /// Replaces the given range [pos, pos + old_n) with the given bool array with n characters
271 class_type
& replace(size_type pos
, size_type old_n
, const_pointer p
, size_type n
);
272 /// Replaces the given range [pos, pos + old_n) with the given n values
273 class_type
& replace(size_type pos
, size_type old_n
, const_reference value
, size_type n
);
274 /// Replaces the given range [pos, pos + old_n) with the given ascii string with n characters
275 class_type
& replace(size_type pos
, size_type old_n
, achar_type
const* s
, size_type n
);
276 /// Replaces the given range [pos, pos + old_n) with the given unicode string with n characters
277 class_type
& replace(size_type pos
, size_type old_n
, wchar_type
const* s
, size_type n
);
278 /// Replaces the given range [pos, pos + old_n) with the given value
279 class_type
& replace(size_type pos
, size_type old_n
, const_reference value
) { return replace(pos
, old_n
, value
, 1u); }
280 /// Replaces the given range [pos, pos + old_n) with the given ascii string
281 class_type
& replace(size_type pos
, size_type old_n
, achar_type
const* s
) { return replace(pos
, old_n
, s
, (NULL
!= s
)? std_strlen(s
) : 0); }
282 /// Replaces the given range [pos, pos + old_n) with the given unicode string
283 class_type
& replace(size_type pos
, size_type old_n
, wchar_type
const* s
) { return replace(pos
, old_n
, s
, (NULL
!= s
)? std_strlen(s
) : 0); }
289 /// Inserts the given bool array with n characters into the given position *this[pos]
290 class_type
& insert(size_type pos
, const_pointer p
, size_type n
) { return replace(pos
, 0, p
, n
); }
291 /// Inserts the given n values into the given position *this[pos]
292 class_type
& insert(size_type pos
, const_reference value
, size_type n
) { return replace(pos
, 0, value
, n
); }
293 /// Inserts the given ascii string with n characters into the given position *this[pos]
294 class_type
& insert(size_type pos
, achar_type
const* s
, size_type n
) { return replace(pos
, 0, s
, n
); }
295 /// Inserts the given unicode string with n characters into the given position *this[pos]
296 class_type
& insert(size_type pos
, wchar_type
const* s
, size_type n
) { return replace(pos
, 0, s
, n
); }
297 /// Inserts the given value into the given position *this[pos]
298 class_type
& insert(size_type pos
, const_reference value
) { return replace(pos
, 0, value
); }
299 /// Inserts the given ascii string into the given position *this[pos]
300 class_type
& insert(size_type pos
, achar_type
const* s
) { return replace(pos
, 0, s
); }
301 /// Inserts the given unicode string into the given position *this[pos]
302 class_type
& insert(size_type pos
, wchar_type
const* s
) { return replace(pos
, 0, s
); }
308 /// Erases the given range [pos, pos + n)
309 class_type
& erase(size_type pos
, size_type n
= 1u);
315 /// Reverses this bit array with the given range [pos, pos + n)
316 class_type
& reverse(size_type pos
, size_type n
);
317 /// Reverses the whole bit array
318 class_type
& reverse() { return reverse(0, size()); }
321 /// \name Static Methods
324 /// Makes numeric from bool array
325 /// \param is_left_low true: low bit=> high bit & false: high bit <= low bit
326 static field_type
make_numeric(const_pointer p
, size_type n
, bool_type is_left_low
= e_false_v
);
327 /// Makes numeric from ascii string with n-characters
328 /// \param is_left_low true: low bit=> high bit & false: high bit <= low bit
329 static field_type
make_numeric(achar_type
const* s
, size_type n
, bool_type is_left_low
= e_false_v
);
330 /// Makes numeric from unicode string with n-characters
331 /// \param is_left_low true: low bit=> high bit & false: high bit <= low bit
332 static field_type
make_numeric(wchar_type
const* s
, size_type n
, bool_type is_left_low
= e_false_v
);
333 /// Makes numeric from ascii string with null-terminator
334 /// \param is_left_low true: low bit=> high bit & false: high bit <= low bit
335 static field_type
make_numeric(achar_type
const* s
, bool_type is_left_low
= e_false_v
) { return make_numeric(s
, (NULL
!= s
)? std_strlen(s
) : 0, is_left_low
); }
336 /// Makes numeric from unicode string with null-terminator
337 /// \param is_left_low true: low bit=> high bit & false: high bit <= low bit
338 static field_type
make_numeric(wchar_type
const* s
, bool_type is_left_low
= e_false_v
) { return make_numeric(s
, (NULL
!= s
)? std_strlen(s
) : 0, is_left_low
); }
344 /// Return the copy of ~(*this)
345 class_type
operator ~();
346 /// Return \c true if *this == rhs
347 bool_type
operator ==(class_type
const& rhs
) const;
348 /// Return \c true if *this != rhs
349 bool_type
operator !=(class_type
const& rhs
) const { return !((*this) == rhs
); }
351 class_type
& operator &=(class_type
const& rhs
);
353 class_type
const operator &(class_type
const& rhs
) const;
355 class_type
& operator |=(class_type
const& rhs
);
357 class_type
const operator |(class_type
const& rhs
) const;
359 class_type
& operator ^=(class_type
const& rhs
);
361 class_type
const operator ^(class_type
const& rhs
) const;
367 buffer_type
const& buffer() const { return m_buffer
; }
368 buffer_type
& buffer() { return m_buffer
; }
372 /* ///////////////////////////////////////////////////////////////////////
377 template< typename_param_k Fld
378 , typename_param_k Buf
380 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
381 value_type
const bit_array
<Fld
, Buf
>::at(index_type index
) const
383 EXTL_ASSERT_THROW((index
/ en_field_bit_count
) < size(), index_error("out of range"));
387 template< typename_param_k Fld
388 , typename_param_k Buf
389 >inline typename_type_ret_k bit_array
<Fld
, Buf
>::
390 value_type
const bit_array
<Fld
, Buf
>::get(index_type index
) const
392 // low bit => high bit
393 EXTL_ASSERT((index
/ en_field_bit_count
) < buffer().size());
394 return (field_type(0x1) == ((buffer()[index
/ en_field_bit_count
] >> (index
% en_field_bit_count
)) & field_type(0x1)));
397 template< typename_param_k Fld
398 , typename_param_k Buf
400 inline void bit_array
<Fld
, Buf
>::set(index_type index
, const_reference value
)
402 index_type i
= index
/ en_field_bit_count
;
403 index_type n
= index
% en_field_bit_count
;
405 EXTL_ASSERT(i
< size());
407 // low bit => high bit
408 buffer()[i
] &= ~(field_type(0x1) << n
);
409 buffer()[i
] |= (static_cast<field_type
>(value
) << n
);
413 template< typename_param_k Fld
414 , typename_param_k Buf
416 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
417 class_type
& bit_array
<Fld
, Buf
>::replace(size_type pos
, size_type old_n
, const_pointer p
, size_type n
)
419 EXTL_ASSERT(NULL
!= p
);
420 EXTL_ASSERT(pos
>= 0 && pos
< size());
424 EXTL_ASSERT((pos
+ n
) <= size());
425 for (index_type i
= 0; i
< n
; ++i
)
430 class_type
tmp(*this);
432 if (pos
+ old_n
> size()) old_n
= size() - pos
;
434 size_type new_n
= size() - (old_n
- n
);
435 EXTL_ASSERT(new_n
<= max_size());
438 for (index_type i
= 0; i
< n
; ++i
)
441 size_type left_n
= tmp
.size() - pos
- old_n
;
442 for (index_type j
= 0; j
< left_n
; ++j
)
443 set(pos
+ n
+ j
, tmp
[pos
+ old_n
+ j
]);
449 template< typename_param_k Fld
450 , typename_param_k Buf
452 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
453 class_type
& bit_array
<Fld
, Buf
>::replace(size_type pos
, size_type old_n
, const_reference value
, size_type n
)
455 EXTL_ASSERT(pos
>= 0 && pos
< size());
458 EXTL_ASSERT((pos
+ n
) <= size());
459 for (index_type i
= 0; i
< n
; ++i
)
464 class_type
tmp(*this);
466 if (pos
+ old_n
> size()) old_n
= size() - pos
;
468 size_type new_n
= size() - (old_n
- n
);
469 EXTL_ASSERT(new_n
<= max_size());
472 for (index_type i
= 0; i
< n
; ++i
)
475 size_type left_n
= tmp
.size() - pos
- old_n
;
476 for (index_type j
= 0; j
< left_n
; ++j
)
477 set(pos
+ n
+ j
, tmp
[pos
+ old_n
+ j
]);
483 template< typename_param_k Fld
484 , typename_param_k Buf
485 >inline typename_type_ret_k bit_array
<Fld
, Buf
>::
486 class_type
& bit_array
<Fld
, Buf
>::replace(size_type pos
, size_type old_n
, achar_type
const* s
, size_type n
)
488 EXTL_ASSERT(NULL
!= s
);
489 EXTL_ASSERT(pos
>= 0 && pos
< size());
493 EXTL_ASSERT((pos
+ n
) <= size());
494 for (index_type i
= 0; i
< n
; ++i
)
495 set(pos
+ i
, s
[i
] != '0');
499 class_type
tmp(*this);
501 if (pos
+ old_n
> size()) old_n
= size() - pos
;
503 size_type new_n
= size() - (old_n
- n
);
504 EXTL_ASSERT(new_n
<= max_size());
507 for (index_type i
= 0; i
< n
; ++i
)
508 set(pos
+ i
, s
[i
] != '0');
510 size_type left_n
= tmp
.size() - pos
- old_n
;
511 for (index_type j
= 0; j
< left_n
; ++j
)
512 set(pos
+ n
+ j
, tmp
[pos
+ old_n
+ j
]);
518 template< typename_param_k Fld
519 , typename_param_k Buf
521 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
522 class_type
& bit_array
<Fld
, Buf
>::replace(size_type pos
, size_type old_n
, wchar_type
const* s
, size_type n
)
524 EXTL_ASSERT(NULL
!= s
);
525 EXTL_ASSERT(pos
>= 0 && pos
< size());
529 EXTL_ASSERT((pos
+ n
) <= size());
530 for (index_type i
= 0; i
< n
; ++i
)
531 set(pos
+ i
, s
[i
] != L
'0');
535 class_type
tmp(*this);
537 if (pos
+ old_n
> size()) old_n
= size() - pos
;
539 size_type new_n
= size() - (old_n
- old_n
);
540 EXTL_ASSERT(new_n
<= max_size());
543 for (index_type i
= 0; i
< n
; ++i
)
544 set(pos
+ i
, s
[i
] != L
'0');
546 size_type left_n
= tmp
.size() - pos
- old_n
;
547 for (index_type j
= 0; j
< left_n
; ++j
)
548 set(pos
+ n
+ j
, tmp
[pos
+ old_n
+ j
]);
555 template< typename_param_k Fld
556 , typename_param_k Buf
558 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
559 class_type
& bit_array
<Fld
, Buf
>::assign(const_reference value
, size_type n
)
561 EXTL_ASSERT(n
<= max_size());
564 for (index_type i
= 0; i
< n
; ++i
)
570 template< typename_param_k Fld
571 , typename_param_k Buf
573 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
574 class_type
& bit_array
<Fld
, Buf
>::assign(const_pointer p
, size_type n
)
576 EXTL_ASSERT(n
<= max_size());
577 EXTL_ASSERT(NULL
!= p
);
580 for (index_type i
= 0; i
< n
; ++i
)
586 template< typename_param_k Fld
587 , typename_param_k Buf
589 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
590 class_type
& bit_array
<Fld
, Buf
>::assign(achar_type
const* s
, size_type n
)
592 EXTL_ASSERT(n
<= max_size());
593 EXTL_ASSERT(NULL
!= s
);
596 for (index_type i
= 0; i
< n
; ++i
)
602 template< typename_param_k Fld
603 , typename_param_k Buf
605 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
606 class_type
& bit_array
<Fld
, Buf
>::assign(wchar_type
const* s
, size_type n
)
608 EXTL_ASSERT(n
<= max_size());
609 EXTL_ASSERT(NULL
!= s
);
612 for (index_type i
= 0; i
< n
; ++i
)
613 set(i
, s
[i
] != L
'0');
617 template< typename_param_k Fld
618 , typename_param_k Buf
620 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
621 class_type
& bit_array
<Fld
, Buf
>::assign(class_type
const& rhs
, size_type n
)
623 EXTL_ASSERT(n
<= max_size());
624 EXTL_ASSERT(n
<= rhs
.size());
628 buffer().assign(rhs
.buffer(), EXTL_ALIGN(n
, en_field_bit_count
) / en_field_bit_count
);
634 template< typename_param_k Fld
635 , typename_param_k Buf
637 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
638 class_type
& bit_array
<Fld
, Buf
>::append(const_reference value
, size_type n
)
640 size_type bit_n
= size() + n
;
641 EXTL_ASSERT(bit_n
<= max_size());
643 resize(bit_n
, value
);
647 template< typename_param_k Fld
648 , typename_param_k Buf
650 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
651 class_type
& bit_array
<Fld
, Buf
>::append(const_pointer p
, size_type n
)
653 size_type bit_n
= size();
654 EXTL_ASSERT((bit_n
+ n
) <= max_size());
655 EXTL_ASSERT(NULL
!= p
);
658 for (index_type i
= 0; i
< n
; ++i
)
659 set(bit_n
+ i
, p
[i
]);
664 template< typename_param_k Fld
665 , typename_param_k Buf
667 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
668 class_type
& bit_array
<Fld
, Buf
>::append(achar_type
const* s
, size_type n
)
670 size_type bit_n
= size();
671 EXTL_ASSERT((bit_n
+ n
) <= max_size());
672 EXTL_ASSERT(NULL
!= s
);
675 for (index_type i
= 0; i
< n
; ++i
)
676 set(bit_n
+ i
, s
[i
] != '0');
681 template< typename_param_k Fld
682 , typename_param_k Buf
684 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
685 class_type
& bit_array
<Fld
, Buf
>::append(wchar_type
const* s
, size_type n
)
687 size_type bit_n
= size();
688 EXTL_ASSERT((bit_n
+ n
) <= max_size());
689 EXTL_ASSERT(NULL
!= s
);
692 for (index_type i
= 0; i
< n
; ++i
)
693 set(bit_n
+ i
, s
[i
] != L
'0');
698 template< typename_param_k Fld
699 , typename_param_k Buf
701 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
702 class_type
& bit_array
<Fld
, Buf
>::append(class_type
const& rhs
, size_type n
)
704 size_type bit_n
= size();
705 EXTL_ASSERT((bit_n
+ n
) <= max_size());
706 EXTL_ASSERT(n
<= rhs
.size());
709 for (index_type i
= 0; i
< n
; ++i
)
710 set(bit_n
+ i
, rhs
[i
]);
715 template< typename_param_k Fld
716 , typename_param_k Buf
718 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
719 class_type
& bit_array
<Fld
, Buf
>::erase(size_type pos
, size_type n
)
722 EXTL_ASSERT(pos
>= 0 && pos
< size());
724 if (pos
+ n
> size()) n
= size() - pos
;
726 if ((0 == pos
) && (n
== size()))
730 else if (!(pos
% en_field_bit_count
) && !(n
% en_field_bit_count
))
732 buffer().erase(pos
/ en_field_bit_count
, n
/ en_field_bit_count
);
737 class_type
tmp(*this);
739 size_type left_n
= tmp
.size() - pos
- n
;
740 for (index_type i
= 0; i
< left_n
; ++i
)
741 set(pos
+ i
, tmp
[pos
+ n
+ i
]);
746 template< typename_param_k Fld
747 , typename_param_k Buf
749 inline void bit_array
<Fld
, Buf
>::resize(size_type n
, const_reference new_value
)
751 EXTL_ASSERT(n
<= max_size());
756 buffer().resize((n
/ en_field_bit_count
) + 1);
760 index_type i
= m_size
;
762 buffer().resize((n
/ en_field_bit_count
) + 1);
768 template< typename_param_k Fld
769 , typename_param_k Buf
771 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
772 class_type
& bit_array
<Fld
, Buf
>::reverse(size_type pos
, size_type n
)
774 EXTL_ASSERT(pos
>= 0 && (pos
+ n
) <= size());
777 index_type begin
= 0;
778 index_type end
= n
- 1;
782 value_type tmp
= get(begin
);
783 set(begin
++, get(end
));
790 template< typename_param_k Fld
791 , typename_param_k Buf
793 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
794 field_type bit_array
<Fld
, Buf
>::numeric() const
799 size_type n
= xtl_min(size_type(en_field_bit_count
), size());
800 for (index_type i
= 0; i
< n
; ++i
)
809 template< typename_param_k Fld
810 , typename_param_k Buf
812 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
813 field_type bit_array
<Fld
, Buf
>::make_numeric(const_pointer p
, size_type n
, bool_type is_left_low
)
815 EXTL_ASSERT(NULL
!= p
);
822 for (index_type i
= 0; i
< n
; ++i
)
830 for (index_type i
= 0; i
< n
; ++i
)
832 num
+= p
[n
- i
- 1] * p2
;
839 template< typename_param_k Fld
840 , typename_param_k Buf
842 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
843 field_type bit_array
<Fld
, Buf
>::make_numeric(achar_type
const* s
, size_type n
, bool_type is_left_low
)
845 EXTL_ASSERT(NULL
!= s
);
852 for (index_type i
= 0; i
< n
; ++i
)
854 num
+= (s
[i
] != '0') * p2
;
860 for (index_type i
= 0; i
< n
; ++i
)
862 num
+= (s
[n
- i
- 1] != '0') * p2
;
869 template< typename_param_k Fld
870 , typename_param_k Buf
872 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
873 field_type bit_array
<Fld
, Buf
>::make_numeric(wchar_type
const* s
, size_type n
, bool_type is_left_low
)
875 EXTL_ASSERT(NULL
!= s
);
882 for (index_type i
= 0; i
< n
; ++i
)
884 num
+= (s
[i
] != L
'0') * p2
;
890 for (index_type i
= 0; i
< n
; ++i
)
892 num
+= (s
[n
- i
- 1] != L
'0') * p2
;
899 template< typename_param_k Fld
900 , typename_param_k Buf
902 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
903 class_type bit_array
<Fld
, Buf
>::operator ~()
905 class_type
tmp(*this);
906 size_type n
= tmp
.buffer().size();
907 for (index_type i
= 0; i
< n
; ++i
)
909 tmp
.buffer()[i
] = ~tmp
.buffer()[i
];
914 template< typename_param_k Fld
915 , typename_param_k Buf
917 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
918 bool_type bit_array
<Fld
, Buf
>::operator ==(class_type
const& rhs
) const
920 size_type bit_n
= size();
921 if (bit_n
!= rhs
.size()) return e_false_v
;
923 size_type n
= buffer().size();
924 for (index_type i
= 0; i
< (n
- 1); ++i
)
926 if (buffer()[i
] != rhs
.buffer()[i
])
930 for (index_type j
= (n
- 1) * en_field_bit_count
; j
< bit_n
; ++j
)
932 if (get(j
) != rhs
.get(j
))
939 template< typename_param_k Fld
940 , typename_param_k Buf
942 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
943 class_type
& bit_array
<Fld
, Buf
>::operator &=(class_type
const& rhs
)
945 EXTL_ASSERT(size() == rhs
.size());
947 size_type n
= buffer().size();
948 for (index_type i
= 0; i
< n
; ++i
)
950 buffer()[i
] &= rhs
.buffer()[i
];
956 template< typename_param_k Fld
957 , typename_param_k Buf
959 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
960 class_type
const bit_array
<Fld
, Buf
>::operator &(class_type
const& rhs
) const
962 return (class_type(rhs
) &= rhs
);
965 template< typename_param_k Fld
966 , typename_param_k Buf
968 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
969 class_type
& bit_array
<Fld
, Buf
>::operator |=(class_type
const& rhs
)
971 EXTL_ASSERT(size() == rhs
.size());
973 size_type n
= buffer().size();
974 for (index_type i
= 0; i
< n
; ++i
)
976 buffer()[i
] |= rhs
.buffer()[i
];
982 template< typename_param_k Fld
983 , typename_param_k Buf
985 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
986 class_type
const bit_array
<Fld
, Buf
>::operator |(class_type
const& rhs
) const
988 return (class_type(rhs
) |= rhs
);
991 template< typename_param_k Fld
992 , typename_param_k Buf
994 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
995 class_type
& bit_array
<Fld
, Buf
>::operator ^=(class_type
const& rhs
)
997 EXTL_ASSERT(size() == rhs
.size());
999 size_type n
= buffer().size();
1000 for (index_type i
= 0; i
< n
; ++i
)
1002 buffer()[i
] ^= rhs
.buffer()[i
];
1008 template< typename_param_k Fld
1009 , typename_param_k Buf
1011 inline typename_type_ret_k bit_array
<Fld
, Buf
>::
1012 class_type
const bit_array
<Fld
, Buf
>::operator ^(class_type
const& rhs
) const
1014 return (class_type(rhs
) ^= rhs
);
1017 /* /////////////////////////////////////////////////////////////////////////
1020 template< typename_param_k Fld
1021 , typename_param_k Buf
1023 EXTL_INLINE
void swap(bit_array
<Fld
, Buf
>& lhs
, bit_array
<Fld
, Buf
>& rhs
)
1028 /* ///////////////////////////////////////////////////////////////////////
1033 /* ///////////////////////////////////////////////////////////////////////
1036 #if !defined(EXTL_NO_STL) && \
1037 !defined(EXTL_NO_NAMESPACE)
1038 /* ::std namespace */
1039 EXTL_STD_BEGIN_NAMESPACE
1041 template< typename_param_k Fld
1042 , typename_param_k Buf
1044 EXTL_INLINE
void swap(EXTL_NS(bit_array
)<Fld
, Buf
>& lhs
, EXTL_NS(bit_array
)<Fld
, Buf
>& rhs
)
1048 /* ::std namespace */
1049 EXTL_STD_END_NAMESPACE
1052 /* //////////////////////////////////////////////////////////////////// */
1053 #endif /* EXTL_CONTAINER_BIT_ARRAY_H */
1054 /* //////////////////////////////////////////////////////////////////// */