source: trunk/src/corelib/tools/qbitarray.cpp@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 19.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qbitarray.h"
43#include <qdatastream.h>
44#include <qdebug.h>
45#include <string.h>
46
47QT_BEGIN_NAMESPACE
48
49/*!
50 \class QBitArray
51 \brief The QBitArray class provides an array of bits.
52
53 \ingroup tools
54 \ingroup shared
55 \reentrant
56
57 A QBitArray is an array that gives access to individual bits and
58 provides operators (\link operator&() AND\endlink, \link
59 operator|() OR\endlink, \link operator^() XOR\endlink, and \link
60 operator~() NOT\endlink) that work on entire arrays of bits. It
61 uses \l{implicit sharing} (copy-on-write) to reduce memory usage
62 and to avoid the needless copying of data.
63
64 The following code constructs a QBitArray containing 200 bits
65 initialized to false (0):
66
67 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 0
68
69 To initialize the bits to true, either pass \c true as second
70 argument to the constructor, or call fill() later on.
71
72 QBitArray uses 0-based indexes, just like C++ arrays. To access
73 the bit at a particular index position, you can use operator[]().
74 On non-const bit arrays, operator[]() returns a reference to a
75 bit that can be used on the left side of an assignment. For
76 example:
77
78 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 1
79
80 For technical reasons, it is more efficient to use testBit() and
81 setBit() to access bits in the array than operator[](). For
82 example:
83
84 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 2
85
86 QBitArray supports \c{&} (\link operator&() AND\endlink), \c{|}
87 (\link operator|() OR\endlink), \c{^} (\link operator^()
88 XOR\endlink), \c{~} (\link operator~() NOT\endlink), as well as
89 \c{&=}, \c{|=}, and \c{^=}. These operators work in the same way
90 as the built-in C++ bitwise operators of the same name. For
91 example:
92
93 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 3
94
95 For historical reasons, QBitArray distinguishes between a null
96 bit array and an empty bit array. A \e null bit array is a bit
97 array that is initialized using QBitArray's default constructor.
98 An \e empty bit array is any bit array with size 0. A null bit
99 array is always empty, but an empty bit array isn't necessarily
100 null:
101
102 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 4
103
104 All functions except isNull() treat null bit arrays the same as
105 empty bit arrays; for example, QBitArray() compares equal to
106 QBitArray(0). We recommend that you always use isEmpty() and
107 avoid isNull().
108
109 \sa QByteArray, QVector
110*/
111
112/*! \fn QBitArray::QBitArray()
113
114 Constructs an empty bit array.
115
116 \sa isEmpty()
117*/
118
119/*!
120 Constructs a bit array containing \a size bits. The bits are
121 initialized with \a value, which defaults to false (0).
122*/
123QBitArray::QBitArray(int size, bool value)
124{
125 if (!size) {
126 d.resize(0);
127 return;
128 }
129 d.resize(1 + (size+7)/8);
130 uchar* c = reinterpret_cast<uchar*>(d.data());
131 memset(c, value ? 0xff : 0, d.size());
132 *c = d.size()*8 - size;
133 if (value && size && size % 8)
134 *(c+1+size/8) &= (1 << (size%8)) - 1;
135}
136
137/*! \fn int QBitArray::size() const
138
139 Returns the number of bits stored in the bit array.
140
141 \sa resize()
142*/
143
144/*! \fn int QBitArray::count() const
145
146 Same as size().
147*/
148
149/*!
150 If \a on is true, this function returns the number of
151 1-bits stored in the bit array; otherwise the number
152 of 0-bits is returned.
153*/
154int QBitArray::count(bool on) const
155{
156 int numBits = 0;
157 int len = size();
158#if 0
159 for (int i = 0; i < len; ++i)
160 numBits += testBit(i);
161#else
162 // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
163 const quint8 *bits = reinterpret_cast<const quint8 *>(d.data()) + 1;
164 while (len >= 32) {
165 quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16) | (quint32(bits[3]) << 24);
166 quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
167 c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
168 c += ((v >> 24) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
169 len -= 32;
170 bits += 4;
171 numBits += int(c);
172 }
173 while (len >= 24) {
174 quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16);
175 quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
176 c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
177 len -= 24;
178 bits += 3;
179 numBits += int(c);
180 }
181 while (len >= 0) {
182 if (bits[len / 8] & (1 << ((len - 1) & 7)))
183 ++numBits;
184 --len;
185 }
186#endif
187 return on ? numBits : size() - numBits;
188}
189
190/*!
191 Resizes the bit array to \a size bits.
192
193 If \a size is greater than the current size, the bit array is
194 extended to make it \a size bits with the extra bits added to the
195 end. The new bits are initialized to false (0).
196
197 If \a size is less than the current size, bits are removed from
198 the end.
199
200 \sa size()
201*/
202void QBitArray::resize(int size)
203{
204 if (!size) {
205 d.resize(0);
206 } else {
207 int s = d.size();
208 d.resize(1 + (size+7)/8);
209 uchar* c = reinterpret_cast<uchar*>(d.data());
210 if (size > (s << 3))
211 memset(c + s, 0, d.size() - s);
212 else if ( size % 8)
213 *(c+1+size/8) &= (1 << (size%8)) - 1;
214 *c = d.size()*8 - size;
215 }
216}
217
218/*! \fn bool QBitArray::isEmpty() const
219
220 Returns true if this bit array has size 0; otherwise returns
221 false.
222
223 \sa size()
224*/
225
226/*! \fn bool QBitArray::isNull() const
227
228 Returns true if this bit array is null; otherwise returns false.
229
230 Example:
231 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 5
232
233 Qt makes a distinction between null bit arrays and empty bit
234 arrays for historical reasons. For most applications, what
235 matters is whether or not a bit array contains any data,
236 and this can be determined using isEmpty().
237
238 \sa isEmpty()
239*/
240
241/*! \fn bool QBitArray::fill(bool value, int size = -1)
242
243 Sets every bit in the bit array to \a value, returning true if successful;
244 otherwise returns false. If \a size is different from -1 (the default),
245 the bit array is resized to \a size beforehand.
246
247 Example:
248 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 6
249
250 \sa resize()
251*/
252
253/*!
254 \overload
255
256 Sets bits at index positions \a begin up to and excluding \a end
257 to \a value.
258
259 \a begin and \a end must be a valid index position in the bit
260 array (i.e., 0 <= \a begin <= size() and 0 <= \a end <= size()).
261*/
262
263void QBitArray::fill(bool value, int begin, int end)
264{
265 while (begin < end && begin & 0x7)
266 setBit(begin++, value);
267 int len = end - begin;
268 if (len <= 0)
269 return;
270 int s = len & ~0x7;
271 uchar *c = reinterpret_cast<uchar*>(d.data());
272 memset(c + (begin >> 3) + 1, value ? 0xff : 0, s >> 3);
273 begin += s;
274 while (begin < end)
275 setBit(begin++, value);
276}
277
278/*! \fn bool QBitArray::isDetached() const
279
280 \internal
281*/
282
283/*! \fn void QBitArray::detach()
284
285 \internal
286*/
287
288/*! \fn void QBitArray::clear()
289
290 Clears the contents of the bit array and makes it empty.
291
292 \sa resize(), isEmpty()
293*/
294
295/*! \fn void QBitArray::truncate(int pos)
296
297 Truncates the bit array at index position \a pos.
298
299 If \a pos is beyond the end of the array, nothing happens.
300
301 \sa resize()
302*/
303
304/*! \fn bool QBitArray::toggleBit(int i)
305
306 Inverts the value of the bit at index position \a i, returning the
307 previous value of that bit as either true (if it was set) or false (if
308 it was unset).
309
310 If the previous value was 0, the new value will be 1. If the
311 previous value was 1, the new value will be 0.
312
313 \a i must be a valid index position in the bit array (i.e., 0 <=
314 \a i < size()).
315
316 \sa setBit(), clearBit()
317*/
318
319/*! \fn bool QBitArray::testBit(int i) const
320
321 Returns true if the bit at index position \a i is 1; otherwise
322 returns false.
323
324 \a i must be a valid index position in the bit array (i.e., 0 <=
325 \a i < size()).
326
327 \sa setBit(), clearBit()
328*/
329
330/*! \fn bool QBitArray::setBit(int i)
331
332 Sets the bit at index position \a i to 1.
333
334 \a i must be a valid index position in the bit array (i.e., 0 <=
335 \a i < size()).
336
337 \sa clearBit(), toggleBit()
338*/
339
340/*! \fn void QBitArray::setBit(int i, bool value)
341
342 \overload
343
344 Sets the bit at index position \a i to \a value.
345*/
346
347/*! \fn void QBitArray::clearBit(int i)
348
349 Sets the bit at index position \a i to 0.
350
351 \a i must be a valid index position in the bit array (i.e., 0 <=
352 \a i < size()).
353
354 \sa setBit(), toggleBit()
355*/
356
357/*! \fn bool QBitArray::at(int i) const
358
359 Returns the value of the bit at index position \a i.
360
361 \a i must be a valid index position in the bit array (i.e., 0 <=
362 \a i < size()).
363
364 \sa operator[]()
365*/
366
367/*! \fn QBitRef QBitArray::operator[](int i)
368
369 Returns the bit at index position \a i as a modifiable reference.
370
371 \a i must be a valid index position in the bit array (i.e., 0 <=
372 \a i < size()).
373
374 Example:
375 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 7
376
377 The return value is of type QBitRef, a helper class for QBitArray.
378 When you get an object of type QBitRef, you can assign to
379 it, and the assignment will apply to the bit in the QBitArray
380 from which you got the reference.
381
382 The functions testBit(), setBit(), and clearBit() are slightly
383 faster.
384
385 \sa at(), testBit(), setBit(), clearBit()
386*/
387
388/*! \fn bool QBitArray::operator[](int i) const
389
390 \overload
391*/
392
393/*! \fn bool QBitArray::operator[](uint i)
394
395 \overload
396*/
397
398/*! \fn bool QBitArray::operator[](uint i) const
399
400 \overload
401*/
402
403/*! \fn QBitArray::QBitArray(const QBitArray &other)
404
405 Constructs a copy of \a other.
406
407 This operation takes \l{constant time}, because QBitArray is
408 \l{implicitly shared}. This makes returning a QBitArray from a
409 function very fast. If a shared instance is modified, it will be
410 copied (copy-on-write), and that takes \l{linear time}.
411
412 \sa operator=()
413*/
414
415/*! \fn QBitArray &QBitArray::operator=(const QBitArray &other)
416
417 Assigns \a other to this bit array and returns a reference to
418 this bit array.
419*/
420
421/*! \fn bool QBitArray::operator==(const QBitArray &other) const
422
423 Returns true if \a other is equal to this bit array; otherwise
424 returns false.
425
426 \sa operator!=()
427*/
428
429/*! \fn bool QBitArray::operator!=(const QBitArray &other) const
430
431 Returns true if \a other is not equal to this bit array;
432 otherwise returns false.
433
434 \sa operator==()
435*/
436
437/*!
438 Performs the AND operation between all bits in this bit array and
439 \a other. Assigns the result to this bit array, and returns a
440 reference to it.
441
442 The result has the length of the longest of the two bit arrays,
443 with any missing bits (if one array is shorter than the other)
444 taken to be 0.
445
446 Example:
447 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 8
448
449 \sa operator&(), operator|=(), operator^=(), operator~()
450*/
451
452QBitArray &QBitArray::operator&=(const QBitArray &other)
453{
454 resize(qMax(size(), other.size()));
455 uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
456 const uchar *a2 = reinterpret_cast<const uchar*>(other.d.constData()) + 1;
457 int n = other.d.size() -1 ;
458 int p = d.size() - 1 - n;
459 while (n-- > 0)
460 *a1++ &= *a2++;
461 while (p-- > 0)
462 *a1++ = 0;
463 return *this;
464}
465
466/*!
467 Performs the OR operation between all bits in this bit array and
468 \a other. Assigns the result to this bit array, and returns a
469 reference to it.
470
471 The result has the length of the longest of the two bit arrays,
472 with any missing bits (if one array is shorter than the other)
473 taken to be 0.
474
475 Example:
476 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 9
477
478 \sa operator|(), operator&=(), operator^=(), operator~()
479*/
480
481QBitArray &QBitArray::operator|=(const QBitArray &other)
482{
483 resize(qMax(size(), other.size()));
484 uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
485 const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1;
486 int n = other.d.size() - 1;
487 while (n-- > 0)
488 *a1++ |= *a2++;
489 return *this;
490}
491
492/*!
493 Performs the XOR operation between all bits in this bit array and
494 \a other. Assigns the result to this bit array, and returns a
495 reference to it.
496
497 The result has the length of the longest of the two bit arrays,
498 with any missing bits (if one array is shorter than the other)
499 taken to be 0.
500
501 Example:
502 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 10
503
504 \sa operator^(), operator&=(), operator|=(), operator~()
505*/
506
507QBitArray &QBitArray::operator^=(const QBitArray &other)
508{
509 resize(qMax(size(), other.size()));
510 uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
511 const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1;
512 int n = other.d.size() - 1;
513 while (n-- > 0)
514 *a1++ ^= *a2++;
515 return *this;
516}
517
518/*!
519 Returns a bit array that contains the inverted bits of this bit
520 array.
521
522 Example:
523 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 11
524
525 \sa operator&(), operator|(), operator^()
526*/
527
528QBitArray QBitArray::operator~() const
529{
530 int sz = size();
531 QBitArray a(sz);
532 const uchar *a1 = reinterpret_cast<const uchar *>(d.constData()) + 1;
533 uchar *a2 = reinterpret_cast<uchar*>(a.d.data()) + 1;
534 int n = d.size() - 1;
535
536 while (n-- > 0)
537 *a2++ = ~*a1++;
538
539 if (sz && sz%8)
540 *(a2-1) &= (1 << (sz%8)) - 1;
541 return a;
542}
543
544/*!
545 \relates QBitArray
546
547 Returns a bit array that is the AND of the bit arrays \a a1 and \a
548 a2.
549
550 The result has the length of the longest of the two bit arrays,
551 with any missing bits (if one array is shorter than the other)
552 taken to be 0.
553
554 Example:
555 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 12
556
557 \sa QBitArray::operator&=(), operator|(), operator^()
558*/
559
560QBitArray operator&(const QBitArray &a1, const QBitArray &a2)
561{
562 QBitArray tmp = a1;
563 tmp &= a2;
564 return tmp;
565}
566
567/*!
568 \relates QBitArray
569
570 Returns a bit array that is the OR of the bit arrays \a a1 and \a
571 a2.
572
573 The result has the length of the longest of the two bit arrays,
574 with any missing bits (if one array is shorter than the other)
575 taken to be 0.
576
577 Example:
578 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 13
579
580 \sa QBitArray::operator|=(), operator&(), operator^()
581*/
582
583QBitArray operator|(const QBitArray &a1, const QBitArray &a2)
584{
585 QBitArray tmp = a1;
586 tmp |= a2;
587 return tmp;
588}
589
590/*!
591 \relates QBitArray
592
593 Returns a bit array that is the XOR of the bit arrays \a a1 and \a
594 a2.
595
596 The result has the length of the longest of the two bit arrays,
597 with any missing bits (if one array is shorter than the other)
598 taken to be 0.
599
600 Example:
601 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 14
602
603 \sa QBitArray::operator^=(), operator&(), operator|()
604*/
605
606QBitArray operator^(const QBitArray &a1, const QBitArray &a2)
607{
608 QBitArray tmp = a1;
609 tmp ^= a2;
610 return tmp;
611}
612
613/*!
614 \class QBitRef
615 \reentrant
616 \brief The QBitRef class is an internal class, used with QBitArray.
617
618 \internal
619
620 The QBitRef is required by the indexing [] operator on bit arrays.
621 It is not for use in any other context.
622*/
623
624/*! \fn QBitRef::QBitRef (QBitArray& a, int i)
625
626 Constructs a reference to element \a i in the QBitArray \a a.
627 This is what QBitArray::operator[] constructs its return value
628 with.
629*/
630
631/*! \fn QBitRef::operator bool() const
632
633 Returns the value referenced by the QBitRef.
634*/
635
636/*! \fn bool QBitRef::operator!() const
637
638 \internal
639*/
640
641/*! \fn QBitRef& QBitRef::operator= (const QBitRef& v)
642
643 Sets the value referenced by the QBitRef to that referenced by
644 QBitRef \a v.
645*/
646
647/*! \fn QBitRef& QBitRef::operator= (bool v)
648 \overload
649
650 Sets the value referenced by the QBitRef to \a v.
651*/
652
653
654/*****************************************************************************
655 QBitArray stream functions
656 *****************************************************************************/
657
658#ifndef QT_NO_DATASTREAM
659/*!
660 \relates QBitArray
661
662 Writes bit array \a ba to stream \a out.
663
664 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
665*/
666
667QDataStream &operator<<(QDataStream &out, const QBitArray &ba)
668{
669 quint32 len = ba.size();
670 out << len;
671 if (len > 0)
672 out.writeRawData(ba.d.constData() + 1, ba.d.size() - 1);
673 return out;
674}
675
676/*!
677 \relates QBitArray
678
679 Reads a bit array into \a ba from stream \a in.
680
681 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
682*/
683
684QDataStream &operator>>(QDataStream &in, QBitArray &ba)
685{
686 ba.clear();
687 quint32 len;
688 in >> len;
689 if (len == 0) {
690 ba.clear();
691 return in;
692 }
693
694 const quint32 Step = 8 * 1024 * 1024;
695 quint32 totalBytes = (len + 7) / 8;
696 quint32 allocated = 0;
697
698 while (allocated < totalBytes) {
699 int blockSize = qMin(Step, totalBytes - allocated);
700 ba.d.resize(allocated + blockSize + 1);
701 if (in.readRawData(ba.d.data() + 1 + allocated, blockSize) != blockSize) {
702 ba.clear();
703 in.setStatus(QDataStream::ReadPastEnd);
704 return in;
705 }
706 allocated += blockSize;
707 }
708
709 int paddingMask = ~((0x1 << (len & 0x7)) - 1);
710 if (paddingMask != ~0x0 && (ba.d.constData()[ba.d.size() - 1] & paddingMask)) {
711 ba.clear();
712 in.setStatus(QDataStream::ReadCorruptData);
713 return in;
714 }
715
716 *ba.d.data() = ba.d.size() * 8 - len;
717 return in;
718}
719#endif // QT_NO_DATASTREAM
720
721/*!
722 \fn DataPtr &QBitArray::data_ptr()
723 \internal
724*/
725
726/*!
727 \typedef QBitArray::DataPtr
728 \internal
729*/
730
731QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.