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 |
|
---|
47 | QT_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 | */
|
---|
123 | QBitArray::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 | */
|
---|
154 | int 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 | */
|
---|
202 | void 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 |
|
---|
261 | void 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 |
|
---|
450 | QBitArray &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 |
|
---|
479 | QBitArray &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 |
|
---|
505 | QBitArray &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 |
|
---|
526 | QBitArray 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 |
|
---|
558 | QBitArray 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 |
|
---|
581 | QBitArray 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 |
|
---|
604 | QBitArray 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
|
---|
664 | QDataStream &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 |
|
---|
681 | QDataStream &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 |
|
---|
728 | QT_END_NAMESPACE
|
---|