1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QBITARRAY_H
5#define QBITARRAY_H
6
7#include <QtCore/qbytearray.h>
8
9QT_BEGIN_NAMESPACE
10
11class QBitRef;
12class Q_CORE_EXPORT QBitArray
13{
14#ifndef QT_NO_DATASTREAM
15 friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
16 friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
17#endif
18 friend Q_CORE_EXPORT size_t qHash(const QBitArray &key, size_t seed) noexcept;
19 QByteArray d;
20
21public:
22 inline QBitArray() noexcept {}
23 explicit QBitArray(qsizetype size, bool val = false);
24 QBitArray(const QBitArray &other) noexcept : d(other.d) {}
25 inline QBitArray &operator=(const QBitArray &other) noexcept { d = other.d; return *this; }
26 inline QBitArray(QBitArray &&other) noexcept : d(std::move(other.d)) {}
27 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QBitArray)
28
29 void swap(QBitArray &other) noexcept { d.swap(other&: other.d); }
30
31 inline qsizetype size() const { return (d.size() << 3) - *d.constData(); }
32 inline qsizetype count() const { return (d.size() << 3) - *d.constData(); }
33 qsizetype count(bool on) const;
34
35 inline bool isEmpty() const { return d.isEmpty(); }
36 inline bool isNull() const { return d.isNull(); }
37
38 void resize(qsizetype size);
39
40 inline void detach() { d.detach(); }
41 inline bool isDetached() const { return d.isDetached(); }
42 inline void clear() { d.clear(); }
43
44 bool testBit(qsizetype i) const;
45 void setBit(qsizetype i);
46 void setBit(qsizetype i, bool val);
47 void clearBit(qsizetype i);
48 bool toggleBit(qsizetype i);
49
50 bool at(qsizetype i) const;
51 QBitRef operator[](qsizetype i);
52 bool operator[](qsizetype i) const;
53
54 QBitArray &operator&=(const QBitArray &);
55 QBitArray &operator|=(const QBitArray &);
56 QBitArray &operator^=(const QBitArray &);
57 QBitArray operator~() const;
58
59 inline bool operator==(const QBitArray &other) const { return d == other.d; }
60 inline bool operator!=(const QBitArray &other) const { return d != other.d; }
61
62 inline bool fill(bool val, qsizetype size = -1);
63 void fill(bool val, qsizetype first, qsizetype last);
64
65 inline void truncate(qsizetype pos) { if (pos < size()) resize(size: pos); }
66
67 const char *bits() const { return isEmpty() ? nullptr : d.constData() + 1; }
68 static QBitArray fromBits(const char *data, qsizetype len);
69
70 quint32 toUInt32(QSysInfo::Endian endianness, bool *ok = nullptr) const noexcept;
71
72public:
73 typedef QByteArray::DataPointer DataPtr;
74 inline DataPtr &data_ptr() { return d.data_ptr(); }
75};
76
77inline bool QBitArray::fill(bool aval, qsizetype asize)
78{ *this = QBitArray((asize < 0 ? this->size() : asize), aval); return true; }
79
80Q_CORE_EXPORT QBitArray operator&(const QBitArray &, const QBitArray &);
81Q_CORE_EXPORT QBitArray operator|(const QBitArray &, const QBitArray &);
82Q_CORE_EXPORT QBitArray operator^(const QBitArray &, const QBitArray &);
83
84inline bool QBitArray::testBit(qsizetype i) const
85{ Q_ASSERT(size_t(i) < size_t(size()));
86 return (*(reinterpret_cast<const uchar*>(d.constData())+1+(i>>3)) & (1 << (i & 7))) != 0; }
87
88inline void QBitArray::setBit(qsizetype i)
89{ Q_ASSERT(size_t(i) < size_t(size()));
90 *(reinterpret_cast<uchar*>(d.data())+1+(i>>3)) |= uchar(1 << (i & 7)); }
91
92inline void QBitArray::clearBit(qsizetype i)
93{ Q_ASSERT(size_t(i) < size_t(size()));
94 *(reinterpret_cast<uchar*>(d.data())+1+(i>>3)) &= ~uchar(1 << (i & 7)); }
95
96inline void QBitArray::setBit(qsizetype i, bool val)
97{ if (val) setBit(i); else clearBit(i); }
98
99inline bool QBitArray::toggleBit(qsizetype i)
100{ Q_ASSERT(size_t(i) < size_t(size()));
101 uchar b = uchar(1<<(i&7)); uchar* p = reinterpret_cast<uchar*>(d.data())+1+(i>>3);
102 uchar c = uchar(*p&b); *p^=b; return c!=0; }
103
104inline bool QBitArray::operator[](qsizetype i) const { return testBit(i); }
105inline bool QBitArray::at(qsizetype i) const { return testBit(i); }
106
107class Q_CORE_EXPORT QBitRef
108{
109private:
110 QBitArray &a;
111 qsizetype i;
112 inline QBitRef(QBitArray &array, qsizetype idx) : a(array), i(idx) { }
113 friend class QBitArray;
114
115public:
116 inline operator bool() const { return a.testBit(i); }
117 inline bool operator!() const { return !a.testBit(i); }
118 QBitRef &operator=(const QBitRef &val) { a.setBit(i, val); return *this; }
119 QBitRef &operator=(bool val) { a.setBit(i, val); return *this; }
120};
121
122inline QBitRef QBitArray::operator[](qsizetype i)
123{ Q_ASSERT(i >= 0); return QBitRef(*this, i); }
124
125#ifndef QT_NO_DATASTREAM
126Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
127Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
128#endif
129
130#ifndef QT_NO_DEBUG_STREAM
131Q_CORE_EXPORT QDebug operator<<(QDebug, const QBitArray &);
132#endif
133
134Q_DECLARE_SHARED(QBitArray)
135
136QT_END_NAMESPACE
137
138#endif // QBITARRAY_H
139

source code of qtbase/src/corelib/tools/qbitarray.h