1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QBITARRAY_H
41 #define QBITARRAY_H
42 
43 #include <QtCore/qbytearray.h>
44 
45 QT_BEGIN_NAMESPACE
46 
47 
48 class QBitRef;
49 class Q_CORE_EXPORT QBitArray
50 {
51     friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
52     friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
53     friend Q_CORE_EXPORT uint qHash(const QBitArray &key, uint seed) noexcept;
54     QByteArray d;
55 
56 public:
QBitArray()57     inline QBitArray() noexcept {}
58     explicit QBitArray(int size, bool val = false);
QBitArray(const QBitArray & other)59     QBitArray(const QBitArray &other) : d(other.d) {}
60     inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
QBitArray(QBitArray && other)61     inline QBitArray(QBitArray &&other) noexcept : d(std::move(other.d)) {}
62     inline QBitArray &operator=(QBitArray &&other) noexcept
63     { qSwap(d, other.d); return *this; }
64 
swap(QBitArray & other)65     inline void swap(QBitArray &other) noexcept { qSwap(d, other.d); }
66 
size()67     inline int size() const { return (d.size() << 3) - *d.constData(); }
count()68     inline int count() const { return (d.size() << 3) - *d.constData(); }
69     int count(bool on) const;
70 
isEmpty()71     inline bool isEmpty() const { return d.isEmpty(); }
isNull()72     inline bool isNull() const { return d.isNull(); }
73 
74     void resize(int size);
75 
detach()76     inline void detach() { d.detach(); }
isDetached()77     inline bool isDetached() const { return d.isDetached(); }
clear()78     inline void clear() { d.clear(); }
79 
80     bool testBit(int i) const;
81     void setBit(int i);
82     void setBit(int i, bool val);
83     void clearBit(int i);
84     bool toggleBit(int i);
85 
86     bool at(int i) const;
87     QBitRef operator[](int i);
88     bool operator[](int i) const;
89     QBitRef operator[](uint i);
90     bool operator[](uint i) const;
91 
92     QBitArray& operator&=(const QBitArray &);
93     QBitArray& operator|=(const QBitArray &);
94     QBitArray& operator^=(const QBitArray &);
95     QBitArray  operator~() const;
96 
97     inline bool operator==(const QBitArray& other) const { return d == other.d; }
98     inline bool operator!=(const QBitArray& other) const { return d != other.d; }
99 
100     inline bool fill(bool val, int size = -1);
101     void fill(bool val, int first, int last);
102 
truncate(int pos)103     inline void truncate(int pos) { if (pos < size()) resize(pos); }
104 
bits()105     const char *bits() const { return isEmpty() ? nullptr : d.constData() + 1; }
106     static QBitArray fromBits(const char *data, qsizetype len);
107 
108 public:
109     typedef QByteArray::DataPtr DataPtr;
data_ptr()110     inline DataPtr &data_ptr() { return d.data_ptr(); }
111 };
112 
fill(bool aval,int asize)113 inline bool QBitArray::fill(bool aval, int asize)
114 { *this = QBitArray((asize < 0 ? this->size() : asize), aval); return true; }
115 
116 Q_CORE_EXPORT QBitArray operator&(const QBitArray &, const QBitArray &);
117 Q_CORE_EXPORT QBitArray operator|(const QBitArray &, const QBitArray &);
118 Q_CORE_EXPORT QBitArray operator^(const QBitArray &, const QBitArray &);
119 
testBit(int i)120 inline bool QBitArray::testBit(int i) const
121 { Q_ASSERT(uint(i) < uint(size()));
122  return (*(reinterpret_cast<const uchar*>(d.constData())+1+(i>>3)) & (1 << (i & 7))) != 0; }
123 
setBit(int i)124 inline void QBitArray::setBit(int i)
125 { Q_ASSERT(uint(i) < uint(size()));
126  *(reinterpret_cast<uchar*>(d.data())+1+(i>>3)) |= uchar(1 << (i & 7)); }
127 
clearBit(int i)128 inline void QBitArray::clearBit(int i)
129 { Q_ASSERT(uint(i) < uint(size()));
130  *(reinterpret_cast<uchar*>(d.data())+1+(i>>3)) &= ~uchar(1 << (i & 7)); }
131 
setBit(int i,bool val)132 inline void QBitArray::setBit(int i, bool val)
133 { if (val) setBit(i); else clearBit(i); }
134 
toggleBit(int i)135 inline bool QBitArray::toggleBit(int i)
136 { Q_ASSERT(uint(i) < uint(size()));
137  uchar b = uchar(1<<(i&7)); uchar* p = reinterpret_cast<uchar*>(d.data())+1+(i>>3);
138  uchar c = uchar(*p&b); *p^=b; return c!=0; }
139 
140 inline bool QBitArray::operator[](int i) const { return testBit(i); }
141 inline bool QBitArray::operator[](uint i) const { return testBit(i); }
at(int i)142 inline bool QBitArray::at(int i) const { return testBit(i); }
143 
144 class Q_CORE_EXPORT QBitRef
145 {
146 private:
147     QBitArray& a;
148     int i;
QBitRef(QBitArray & array,int idx)149     inline QBitRef(QBitArray& array, int idx) : a(array), i(idx) {}
150     friend class QBitArray;
151 public:
152     QBitRef(const QBitRef &) = default;
153     inline operator bool() const { return a.testBit(i); }
154     inline bool operator!() const { return !a.testBit(i); }
155     QBitRef& operator=(const QBitRef& val) { a.setBit(i, val); return *this; }
156     QBitRef& operator=(bool val) { a.setBit(i, val); return *this; }
157 };
158 
159 inline QBitRef QBitArray::operator[](int i)
160 { Q_ASSERT(i >= 0); return QBitRef(*this, i); }
161 inline QBitRef QBitArray::operator[](uint i)
162 { return QBitRef(*this, i); }
163 
164 
165 #ifndef QT_NO_DATASTREAM
166 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
167 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
168 #endif
169 
170 #ifndef QT_NO_DEBUG_STREAM
171 Q_CORE_EXPORT QDebug operator<<(QDebug, const QBitArray &);
172 #endif
173 
174 Q_DECLARE_SHARED(QBitArray)
175 
176 QT_END_NAMESPACE
177 
178 #endif // QBITARRAY_H
179