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 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | class QBitRef; |
12 | class Q_CORE_EXPORT QBitArray |
13 | { |
14 | Q_CORE_EXPORT friend QBitArray operator&(const QBitArray &a1, const QBitArray &a2); |
15 | friend QBitArray operator&(QBitArray &&a1, const QBitArray &a2) |
16 | { return a1 &= a2; } |
17 | friend QBitArray operator&(const QBitArray &a1, QBitArray &&a2) |
18 | { return a2 &= a1; } |
19 | friend QBitArray operator&(QBitArray &&a1, QBitArray &&a2) |
20 | { return a1 &= a2; } |
21 | |
22 | Q_CORE_EXPORT friend QBitArray operator|(const QBitArray &a1, const QBitArray &a2); |
23 | friend QBitArray operator|(QBitArray &&a1, const QBitArray &a2) |
24 | { return a1 |= a2; } |
25 | friend QBitArray operator|(const QBitArray &a1, QBitArray &&a2) |
26 | { return a2 |= a1; } |
27 | friend QBitArray operator|(QBitArray &&a1, QBitArray &&a2) |
28 | { return a1 |= a2; } |
29 | |
30 | Q_CORE_EXPORT friend QBitArray operator^(const QBitArray &a1, const QBitArray &a2); |
31 | friend QBitArray operator^(QBitArray &&a1, const QBitArray &a2) |
32 | { return a1 ^= a2; } |
33 | friend QBitArray operator^(const QBitArray &a1, QBitArray &&a2) |
34 | { return a2 ^= a1; } |
35 | friend QBitArray operator^(QBitArray &&a1, QBitArray &&a2) |
36 | { return a1 ^= a2; } |
37 | |
38 | #ifndef QT_NO_DATASTREAM |
39 | friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &); |
40 | friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &); |
41 | #endif |
42 | friend Q_CORE_EXPORT size_t qHash(const QBitArray &key, size_t seed) noexcept; |
43 | friend QBitArray operator~(QBitArray a) |
44 | { return std::move(a).inverted_inplace(); } |
45 | QByteArray d; |
46 | |
47 | QBitArray(QByteArrayData &&dd) : d(std::move(dd)) {} |
48 | |
49 | template <typename BitArray> static auto bitLocation(BitArray &ba, qsizetype i) |
50 | { |
51 | Q_ASSERT(size_t(i) < size_t(ba.size())); |
52 | struct R { |
53 | decltype(ba.d[1]) byte; |
54 | uchar bitMask; |
55 | }; |
56 | qsizetype byteIdx = i >> 3; |
57 | qsizetype bitIdx = i & 7; |
58 | return R{ ba.d[1 + byteIdx], uchar(1U << bitIdx) }; |
59 | } |
60 | |
61 | QBitArray inverted_inplace() &&; |
62 | |
63 | public: |
64 | inline QBitArray() noexcept {} |
65 | explicit QBitArray(qsizetype size, bool val = false); |
66 | // Rule Of Zero applies |
67 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) |
68 | QBitArray(const QBitArray &other) noexcept : d(other.d) {} |
69 | inline QBitArray &operator=(const QBitArray &other) noexcept { d = other.d; return *this; } |
70 | inline QBitArray(QBitArray &&other) noexcept : d(std::move(other.d)) {} |
71 | QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QBitArray) |
72 | #endif // Qt 6 |
73 | |
74 | void swap(QBitArray &other) noexcept { d.swap(other&: other.d); } |
75 | |
76 | qsizetype size() const { return qsizetype((size_t(d.size()) << 3) - *d.constData()); } |
77 | qsizetype count() const { return size(); } |
78 | qsizetype count(bool on) const; |
79 | |
80 | inline bool isEmpty() const { return d.isEmpty(); } |
81 | inline bool isNull() const { return d.isNull(); } |
82 | |
83 | void resize(qsizetype size); |
84 | |
85 | inline void detach() { d.detach(); } |
86 | inline bool isDetached() const { return d.isDetached(); } |
87 | inline void clear() { d.clear(); } |
88 | |
89 | bool testBit(qsizetype i) const |
90 | { auto r = bitLocation(ba: *this, i); return r.byte & r.bitMask; } |
91 | void setBit(qsizetype i) |
92 | { auto r = bitLocation(ba&: *this, i); r.byte |= r.bitMask; } |
93 | void setBit(qsizetype i, bool val) |
94 | { if (val) setBit(i); else clearBit(i); } |
95 | void clearBit(qsizetype i) |
96 | { auto r = bitLocation(ba&: *this, i); r.byte &= ~r.bitMask; } |
97 | bool toggleBit(qsizetype i) |
98 | { |
99 | auto r = bitLocation(ba&: *this, i); |
100 | bool cl = r.byte & r.bitMask; |
101 | r.byte ^= r.bitMask; |
102 | return cl; |
103 | } |
104 | |
105 | bool at(qsizetype i) const { return testBit(i); } |
106 | inline QBitRef operator[](qsizetype i); |
107 | bool operator[](qsizetype i) const { return testBit(i); } |
108 | |
109 | QBitArray &operator&=(QBitArray &&); |
110 | QBitArray &operator|=(QBitArray &&); |
111 | QBitArray &operator^=(QBitArray &&); |
112 | QBitArray &operator&=(const QBitArray &); |
113 | QBitArray &operator|=(const QBitArray &); |
114 | QBitArray &operator^=(const QBitArray &); |
115 | #if QT_CORE_REMOVED_SINCE(6, 7) |
116 | QBitArray operator~() const; |
117 | #endif |
118 | |
119 | #if QT_CORE_REMOVED_SINCE(6, 8) |
120 | inline bool operator==(const QBitArray &other) const { return comparesEqual(d, other.d); } |
121 | inline bool operator!=(const QBitArray &other) const { return !operator==(other); } |
122 | #endif |
123 | |
124 | bool fill(bool aval, qsizetype asize = -1) |
125 | { *this = QBitArray((asize < 0 ? this->size() : asize), aval); return true; } |
126 | void fill(bool val, qsizetype first, qsizetype last); |
127 | |
128 | inline void truncate(qsizetype pos) { if (pos < size()) resize(size: pos); } |
129 | |
130 | const char *bits() const { return isEmpty() ? nullptr : d.constData() + 1; } |
131 | static QBitArray fromBits(const char *data, qsizetype len); |
132 | |
133 | quint32 toUInt32(QSysInfo::Endian endianness, bool *ok = nullptr) const noexcept; |
134 | |
135 | public: |
136 | typedef QByteArray::DataPointer DataPtr; |
137 | inline DataPtr &data_ptr() { return d.data_ptr(); } |
138 | inline const DataPtr &data_ptr() const { return d.data_ptr(); } |
139 | |
140 | private: |
141 | friend bool comparesEqual(const QBitArray &lhs, const QBitArray &rhs) noexcept |
142 | { |
143 | return lhs.d == rhs.d; |
144 | } |
145 | Q_DECLARE_EQUALITY_COMPARABLE(QBitArray) |
146 | }; |
147 | |
148 | class QT6_ONLY(Q_CORE_EXPORT) QBitRef |
149 | { |
150 | private: |
151 | QBitArray &a; |
152 | qsizetype i; |
153 | inline QBitRef(QBitArray &array, qsizetype idx) : a(array), i(idx) { } |
154 | friend class QBitArray; |
155 | |
156 | public: |
157 | inline operator bool() const { return a.testBit(i); } |
158 | inline bool operator!() const { return !a.testBit(i); } |
159 | QBitRef &operator=(const QBitRef &val) { a.setBit(i, val); return *this; } |
160 | QBitRef &operator=(bool val) { a.setBit(i, val); return *this; } |
161 | }; |
162 | |
163 | QBitRef QBitArray::operator[](qsizetype i) |
164 | { Q_ASSERT(i >= 0); return QBitRef(*this, i); } |
165 | |
166 | #ifndef QT_NO_DATASTREAM |
167 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &); |
168 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &); |
169 | #endif |
170 | |
171 | #ifndef QT_NO_DEBUG_STREAM |
172 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QBitArray &); |
173 | #endif |
174 | |
175 | Q_DECLARE_SHARED(QBitArray) |
176 | |
177 | QT_END_NAMESPACE |
178 | |
179 | #endif // QBITARRAY_H |
180 |
Definitions
- QBitArray
- operator&
- operator&
- operator&
- operator|
- operator|
- operator|
- operator^
- operator^
- operator^
- operator~
- QBitArray
- bitLocation
- QBitArray
- QBitArray
- operator=
- QBitArray
- swap
- size
- count
- isEmpty
- isNull
- detach
- isDetached
- clear
- testBit
- setBit
- setBit
- clearBit
- toggleBit
- at
- operator[]
- fill
- truncate
- bits
- data_ptr
- data_ptr
- comparesEqual
- QBitRef
- QBitRef
- operator bool
- operator!
- operator=
- operator=
Learn Advanced QML with KDAB
Find out more