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

Last change on this file since 421 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 19.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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 *c = d.size()*8 - size;
213 }
214}
215
216/*! \fn bool QBitArray::isEmpty() const
217
218 Returns true if this bit array has size 0; otherwise returns
219 false.
220
221 \sa size()
222*/
223
224/*! \fn bool QBitArray::isNull() const
225
226 Returns true if this bit array is null; otherwise returns false.
227
228 Example:
229 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 5
230
231 Qt makes a distinction between null bit arrays and empty bit
232 arrays for historical reasons. For most applications, what
233 matters is whether or not a bit array contains any data,
234 and this can be determined using isEmpty().
235
236 \sa isEmpty()
237*/
238
239/*! \fn bool QBitArray::fill(bool value, int size = -1)
240
241 Sets every bit in the bit array to \a value, returning true if successful;
242 otherwise returns false. If \a size is different from -1 (the default),
243 the bit array is resized to \a size beforehand.
244
245 Example:
246 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 6
247
248 \sa resize()
249*/
250
251/*!
252 \overload
253
254 Sets bits at index positions \a begin up to and excluding \a end
255 to \a value.
256
257 \a begin and \a end must be a valid index position in the bit
258 array (i.e., 0 <= \a begin <= size() and 0 <= \a end <= size()).
259*/
260
261void QBitArray::fill(bool value, int begin, int end)
262{
263 while (begin < end && begin & 0x7)
264 setBit(begin++, value);
265 int len = end - begin;
266 if (len <= 0)
267 return;
268 int s = len & ~0x7;
269 uchar *c = reinterpret_cast<uchar*>(d.data());
270 memset(c + (begin >> 3) + 1, value ? 0xff : 0, s >> 3);
271 begin += s;
272 while (begin < end)
273 setBit(begin++, value);
274}
275
276/*! \fn bool QBitArray::isDetached() const
277
278 \internal
279*/
280
281/*! \fn void QBitArray::detach()
282
283 \internal
284*/
285
286/*! \fn void QBitArray::clear()
287
288 Clears the contents of the bit array and makes it empty.
289
290 \sa resize(), isEmpty()
291*/
292
293/*! \fn void QBitArray::truncate(int pos)
294
295 Truncates the bit array at index position \a pos.
296
297 If \a pos is beyond the end of the array, nothing happens.
298
299 \sa resize()
300*/
301
302/*! \fn bool QBitArray::toggleBit(int i)
303
304 Inverts the value of the bit at index position \a i, returning the
305 previous value of that bit as either true (if it was set) or false (if
306 it was unset).
307
308 If the previous value was 0, the new value will be 1. If the
309 previous value was 1, the new value will be 0.
310
311 \a i must be a valid index position in the bit array (i.e., 0 <=
312 \a i < size()).
313
314 \sa setBit(), clearBit()
315*/
316
317/*! \fn bool QBitArray::testBit(int i) const
318
319 Returns true if the bit at index position \a i is 1; otherwise
320 returns false.
321
322 \a i must be a valid index position in the bit array (i.e., 0 <=
323 \a i < size()).
324
325 \sa setBit(), clearBit()
326*/
327
328/*! \fn bool QBitArray::setBit(int i)
329
330 Sets the bit at index position \a i to 1.
331
332 \a i must be a valid index position in the bit array (i.e., 0 <=
333 \a i < size()).
334
335 \sa clearBit(), toggleBit()
336*/
337
338/*! \fn void QBitArray::setBit(int i, bool value)
339
340 \overload
341
342 Sets the bit at index position \a i to \a value.
343*/
344
345/*! \fn void QBitArray::clearBit(int i)
346
347 Sets the bit at index position \a i to 0.
348
349 \a i must be a valid index position in the bit array (i.e., 0 <=
350 \a i < size()).
351
352 \sa setBit(), toggleBit()
353*/
354
355/*! \fn bool QBitArray::at(int i) const
356
357 Returns the value of the bit at index position \a i.
358
359 \a i must be a valid index position in the bit array (i.e., 0 <=
360 \a i < size()).
361
362 \sa operator[]()
363*/
364
365/*! \fn QBitRef QBitArray::operator[](int i)
366
367 Returns the bit at index position \a i as a modifiable reference.
368
369 \a i must be a valid index position in the bit array (i.e., 0 <=
370 \a i < size()).
371
372 Example:
373 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 7
374
375 The return value is of type QBitRef, a helper class for QBitArray.
376 When you get an object of type QBitRef, you can assign to
377 it, and the assignment will apply to the bit in the QBitArray
378 from which you got the reference.
379
380 The functions testBit(), setBit(), and clearBit() are slightly
381 faster.
382
383 \sa at(), testBit(), setBit(), clearBit()
384*/
385
386/*! \fn bool QBitArray::operator[](int i) const
387
388 \overload
389*/
390
391/*! \fn bool QBitArray::operator[](uint i)
392
393 \overload
394*/
395
396/*! \fn bool QBitArray::operator[](uint i) const
397
398 \overload
399*/
400
401/*! \fn QBitArray::QBitArray(const QBitArray &other)
402
403 Constructs a copy of \a other.
404
405 This operation takes \l{constant time}, because QBitArray is
406 \l{implicitly shared}. This makes returning a QBitArray from a
407 function very fast. If a shared instance is modified, it will be
408 copied (copy-on-write), and that takes \l{linear time}.
409
410 \sa operator=()
411*/
412
413/*! \fn QBitArray &QBitArray::operator=(const QBitArray &other)
414
415 Assigns \a other to this bit array and returns a reference to
416 this bit array.
417*/
418
419/*! \fn bool QBitArray::operator==(const QBitArray &other) const
420
421 Returns true if \a other is equal to this bit array; otherwise
422 returns false.
423
424 \sa operator!=()
425*/
426
427/*! \fn bool QBitArray::operator!=(const QBitArray &other) const
428
429 Returns true if \a other is not equal to this bit array;
430 otherwise returns false.
431
432 \sa operator==()
433*/
434
435/*!
436 Performs the AND operation between all bits in this bit array and
437 \a other. Assigns the result to this bit array, and returns a
438 reference to it.
439
440 The result has the length of the longest of the two bit arrays,
441 with any missing bits (if one array is shorter than the other)
442 taken to be 0.
443
444 Example:
445 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 8
446
447 \sa operator&(), operator|=(), operator^=(), operator~()
448*/
449
450QBitArray &QBitArray::operator&=(const QBitArray &other)
451{
452 resize(qMax(size(), other.size()));
453 uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
454 const uchar *a2 = reinterpret_cast<const uchar*>(other.d.constData()) + 1;
455 int n = other.d.size() -1 ;
456 int p = d.size() - 1 - n;
457 while (n-- > 0)
458 *a1++ &= *a2++;
459 while (p-- > 0)
460 *a1++ = 0;
461 return *this;
462}
463
464/*!
465 Performs the OR operation between all bits in this bit array and
466 \a other. Assigns the result to this bit array, and returns a
467 reference to it.
468
469 The result has the length of the longest of the two bit arrays,
470 with any missing bits (if one array is shorter than the other)
471 taken to be 0.
472
473 Example:
474 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 9
475
476 \sa operator|(), operator&=(), operator^=(), operator~()
477*/
478
479QBitArray &QBitArray::operator|=(const QBitArray &other)
480{
481 resize(qMax(size(), other.size()));
482 uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
483 const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1;
484 int n = other.d.size() - 1;
485 while (n-- > 0)
486 *a1++ |= *a2++;
487 return *this;
488}
489
490/*!
491 Performs the XOR operation between all bits in this bit array and
492 \a other. Assigns the result to this bit array, and returns a
493 reference to it.
494
495 The result has the length of the longest of the two bit arrays,
496 with any missing bits (if one array is shorter than the other)
497 taken to be 0.
498
499 Example:
500 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 10
501
502 \sa operator^(), operator&=(), operator|=(), operator~()
503*/
504
505QBitArray &QBitArray::operator^=(const QBitArray &other)
506{
507 resize(qMax(size(), other.size()));
508 uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
509 const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1;
510 int n = other.d.size() - 1;
511 while (n-- > 0)
512 *a1++ ^= *a2++;
513 return *this;
514}
515
516/*!
517 Returns a bit array that contains the inverted bits of this bit
518 array.
519
520 Example:
521 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 11
522
523 \sa operator&(), operator|(), operator^()
524*/
525
526QBitArray QBitArray::operator~() const
527{
528 int sz = size();
529 QBitArray a(sz);
530 const uchar *a1 = reinterpret_cast<const uchar *>(d.constData()) + 1;
531 uchar *a2 = reinterpret_cast<uchar*>(a.d.data()) + 1;
532 int n = d.size() - 1;
533
534 while (n-- > 0)
535 *a2++ = ~*a1++;
536
537 if (sz && sz%8)
538 *(a2-1) &= (1 << (sz%8)) - 1;
539 return a;
540}
541
542/*!
543 \relates QBitArray
544
545 Returns a bit array that is the AND of the bit arrays \a a1 and \a
546 a2.
547
548 The result has the length of the longest of the two bit arrays,
549 with any missing bits (if one array is shorter than the other)
550 taken to be 0.
551
552 Example:
553 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 12
554
555 \sa QBitArray::operator&=(), operator|(), operator^()
556*/
557
558QBitArray operator&(const QBitArray &a1, const QBitArray &a2)
559{
560 QBitArray tmp = a1;
561 tmp &= a2;
562 return tmp;
563}
564
565/*!
566 \relates QBitArray
567
568 Returns a bit array that is the OR of the bit arrays \a a1 and \a
569 a2.
570
571 The result has the length of the longest of the two bit arrays,
572 with any missing bits (if one array is shorter than the other)
573 taken to be 0.
574
575 Example:
576 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 13
577
578 \sa QBitArray::operator|=(), operator&(), operator^()
579*/
580
581QBitArray operator|(const QBitArray &a1, const QBitArray &a2)
582{
583 QBitArray tmp = a1;
584 tmp |= a2;
585 return tmp;
586}
587
588/*!
589 \relates QBitArray
590
591 Returns a bit array that is the XOR of the bit arrays \a a1 and \a
592 a2.
593
594 The result has the length of the longest of the two bit arrays,
595 with any missing bits (if one array is shorter than the other)
596 taken to be 0.
597
598 Example:
599 \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 14
600
601 \sa QBitArray::operator^=(), operator&(), operator|()
602*/
603
604QBitArray operator^(const QBitArray &a1, const QBitArray &a2)
605{
606 QBitArray tmp = a1;
607 tmp ^= a2;
608 return tmp;
609}
610
611/*!
612 \class QBitRef
613 \reentrant
614 \brief The QBitRef class is an internal class, used with QBitArray.
615
616 \internal
617
618 The QBitRef is required by the indexing [] operator on bit arrays.
619 It is not for use in any other context.
620*/
621
622/*! \fn QBitRef::QBitRef (QBitArray& a, int i)
623
624 Constructs a reference to element \a i in the QBitArray \a a.
625 This is what QBitArray::operator[] constructs its return value
626 with.
627*/
628
629/*! \fn QBitRef::operator bool() const
630
631 Returns the value referenced by the QBitRef.
632*/
633
634/*! \fn bool QBitRef::operator!() const
635
636 \internal
637*/
638
639/*! \fn QBitRef& QBitRef::operator= (const QBitRef& v)
640
641 Sets the value referenced by the QBitRef to that referenced by
642 QBitRef \a v.
643*/
644
645/*! \fn QBitRef& QBitRef::operator= (bool v)
646 \overload
647
648 Sets the value referenced by the QBitRef to \a v.
649*/
650
651
652/*****************************************************************************
653 QBitArray stream functions
654 *****************************************************************************/
655
656/*!
657 \relates QBitArray
658
659 Writes bit array \a ba to stream \a out.
660
661 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
662*/
663#ifndef QT_NO_DATASTREAM
664QDataStream &operator<<(QDataStream &out, const QBitArray &ba)
665{
666 quint32 len = ba.size();
667 out << len;
668 if (len > 0)
669 out.writeRawData(ba.d.constData() + 1, ba.d.size() - 1);
670 return out;
671}
672
673/*!
674 \relates QBitArray
675
676 Reads a bit array into \a ba from stream \a in.
677
678 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
679*/
680
681QDataStream &operator>>(QDataStream &in, QBitArray &ba)
682{
683 ba.clear();
684 quint32 len;
685 in >> len;
686 if (len == 0) {
687 ba.clear();
688 return in;
689 }
690
691 const quint32 Step = 8 * 1024 * 1024;
692 quint32 totalBytes = (len + 7) / 8;
693 quint32 allocated = 0;
694
695 while (allocated < totalBytes) {
696 int blockSize = qMin(Step, totalBytes - allocated);
697 ba.d.resize(allocated + blockSize + 1);
698 if (in.readRawData(ba.d.data() + 1 + allocated, blockSize) != blockSize) {
699 ba.clear();
700 in.setStatus(QDataStream::ReadPastEnd);
701 return in;
702 }
703 allocated += blockSize;
704 }
705
706 int paddingMask = ~((0x1 << (len & 0x7)) - 1);
707 if (paddingMask != ~0x0 && (ba.d.constData()[ba.d.size() - 1] & paddingMask)) {
708 ba.clear();
709 in.setStatus(QDataStream::ReadCorruptData);
710 return in;
711 }
712
713 *ba.d.data() = ba.d.size() * 8 - len;
714 return in;
715}
716#endif
717
718/*!
719 \fn DataPtr &QBitArray::data_ptr()
720 \internal
721*/
722
723/*!
724 \typedef QBitArray::DataPtr
725 \internal
726*/
727
728QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.