Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/QtCore/qversionnumber.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright (C) 2020 The Qt Company Ltd.
0002 // Copyright (C) 2022 Intel Corporation.
0003 // Copyright (C) 2015 Keith Gardner <kreios4004@gmail.com>
0004 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0005 
0006 #ifndef QVERSIONNUMBER_H
0007 #define QVERSIONNUMBER_H
0008 
0009 #include <QtCore/qlist.h>
0010 #include <QtCore/qmetatype.h>
0011 #include <QtCore/qnamespace.h>
0012 #include <QtCore/qstring.h>
0013 #include <QtCore/qtypeinfo.h>
0014 #if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 2
0015 #include <QtCore/qtyperevision.h>
0016 #endif // lean headers level 2
0017 
0018 QT_BEGIN_NAMESPACE
0019 
0020 class QVersionNumber;
0021 Q_CORE_EXPORT size_t qHash(const QVersionNumber &key, size_t seed = 0);
0022 
0023 #ifndef QT_NO_DATASTREAM
0024 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QVersionNumber &version);
0025 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QVersionNumber &version);
0026 #endif
0027 
0028 class QVersionNumber
0029 {
0030     /*
0031      * QVersionNumber stores small values inline, without memory allocation.
0032      * We do that by setting the LSB in the pointer that would otherwise hold
0033      * the longer form of the segments.
0034      * The constants below help us deal with the permutations for 32- and 64-bit,
0035      * little- and big-endian architectures.
0036      */
0037     enum {
0038         // in little-endian, inline_segments[0] is shared with the pointer's LSB, while
0039         // in big-endian, it's inline_segments[7]
0040         InlineSegmentMarker = Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? 0 : sizeof(void *) - 1,
0041         InlineSegmentStartIdx = !InlineSegmentMarker, // 0 for BE, 1 for LE
0042         InlineSegmentCount = sizeof(void *) - 1
0043     };
0044     static_assert(InlineSegmentCount >= 3);   // at least major, minor, micro
0045 
0046     struct SegmentStorage
0047     {
0048         // Note: we alias the use of dummy and inline_segments in the use of the
0049         // union below. This is undefined behavior in C++98, but most compilers implement
0050         // the C++11 behavior. The one known exception is older versions of Sun Studio.
0051         union {
0052             quintptr dummy;
0053             qint8 inline_segments[sizeof(void *)];
0054             QList<int> *pointer_segments;
0055         };
0056 
0057         // set the InlineSegmentMarker and set length to zero
0058         SegmentStorage() noexcept : dummy(1) {}
0059 
0060         SegmentStorage(const QList<int> &seg)
0061         {
0062             if (dataFitsInline(seg.data(), seg.size()))
0063                 setInlineData(seg.data(), seg.size());
0064             else
0065                 setListData(seg);
0066         }
0067 
0068         Q_CORE_EXPORT void setListData(const QList<int> &seg);
0069 
0070         SegmentStorage(const SegmentStorage &other)
0071         {
0072             if (other.isUsingPointer())
0073                 setListData(*other.pointer_segments);
0074             else
0075                 dummy = other.dummy;
0076         }
0077 
0078         SegmentStorage &operator=(const SegmentStorage &other)
0079         {
0080             if (isUsingPointer() && other.isUsingPointer()) {
0081                 *pointer_segments = *other.pointer_segments;
0082             } else if (other.isUsingPointer()) {
0083                 setListData(*other.pointer_segments);
0084             } else {
0085                 if (isUsingPointer())
0086                     delete pointer_segments;
0087                 dummy = other.dummy;
0088             }
0089             return *this;
0090         }
0091 
0092         SegmentStorage(SegmentStorage &&other) noexcept
0093             : dummy(other.dummy)
0094         {
0095             other.dummy = 1;
0096         }
0097 
0098         QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(SegmentStorage)
0099 
0100         void swap(SegmentStorage &other) noexcept
0101         {
0102             std::swap(dummy, other.dummy);
0103         }
0104 
0105         explicit SegmentStorage(QList<int> &&seg)
0106         {
0107             if (dataFitsInline(std::as_const(seg).data(), seg.size()))
0108                 setInlineData(std::as_const(seg).data(), seg.size());
0109             else
0110                 setListData(std::move(seg));
0111         }
0112 
0113         Q_CORE_EXPORT void setListData(QList<int> &&seg);
0114 
0115         explicit SegmentStorage(std::initializer_list<int> args)
0116             : SegmentStorage(args.begin(), args.end()) {}
0117 
0118         explicit SegmentStorage(const int *first, const int *last)
0119         {
0120             if (dataFitsInline(first, last - first)) {
0121                 setInlineData(first, last - first);
0122             } else {
0123                 setListData(first, last);
0124             }
0125         }
0126 
0127         Q_CORE_EXPORT void setListData(const int *first, const int *last);
0128 
0129         ~SegmentStorage() { if (isUsingPointer()) delete pointer_segments; }
0130 
0131         bool isUsingPointer() const noexcept
0132         { return (inline_segments[InlineSegmentMarker] & 1) == 0; }
0133 
0134         qsizetype size() const noexcept
0135         { return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); }
0136 
0137         void setInlineSize(qsizetype len)
0138         {
0139             Q_ASSERT(len <= InlineSegmentCount);
0140             inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len);
0141         }
0142 
0143         Q_CORE_EXPORT void resize(qsizetype len);
0144 
0145         int at(qsizetype index) const
0146         {
0147             return isUsingPointer() ?
0148                         pointer_segments->at(index) :
0149                         inline_segments[InlineSegmentStartIdx + index];
0150         }
0151 
0152         void setSegments(int len, int maj, int min = 0, int mic = 0)
0153         {
0154             if (maj == qint8(maj) && min == qint8(min) && mic == qint8(mic)) {
0155                 int data[] = { maj, min, mic };
0156                 setInlineData(data, len);
0157             } else {
0158                 setVector(len, maj, min, mic);
0159             }
0160         }
0161 
0162     private:
0163         static bool dataFitsInline(const int *data, qsizetype len)
0164         {
0165             if (len > InlineSegmentCount)
0166                 return false;
0167             for (qsizetype i = 0; i < len; ++i)
0168                 if (data[i] != qint8(data[i]))
0169                     return false;
0170             return true;
0171         }
0172         void setInlineData(const int *data, qsizetype len)
0173         {
0174             Q_ASSERT(len <= InlineSegmentCount);
0175             dummy = 1 + len * 2;
0176 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
0177             for (qsizetype i = 0; i < len; ++i)
0178                 dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1));
0179 #elif Q_BYTE_ORDER == Q_BIG_ENDIAN
0180             for (qsizetype i = 0; i < len; ++i)
0181                 dummy |= quintptr(data[i] & 0xFF) << (8 * (sizeof(void *) - i - 1));
0182 #else
0183             // the code above is equivalent to:
0184             setInlineSize(len);
0185             for (qsizetype i = 0; i < len; ++i)
0186                 inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF;
0187 #endif
0188         }
0189 
0190         Q_CORE_EXPORT void setVector(int len, int maj, int min, int mic);
0191     } m_segments;
0192 
0193 public:
0194     inline QVersionNumber() noexcept
0195         : m_segments()
0196     {}
0197     inline explicit QVersionNumber(const QList<int> &seg) : m_segments(seg) { }
0198 
0199     // compiler-generated copy/move ctor/assignment operators and the destructor are ok
0200 
0201     explicit QVersionNumber(QList<int> &&seg) : m_segments(std::move(seg)) { }
0202 
0203     inline QVersionNumber(std::initializer_list<int> args)
0204         : m_segments(args)
0205     {}
0206 
0207     template <qsizetype N>
0208     explicit QVersionNumber(const QVarLengthArray<int, N> &sec)
0209         : m_segments(sec.begin(), sec.end())
0210     {}
0211 
0212     inline explicit QVersionNumber(int maj)
0213     { m_segments.setSegments(1, maj); }
0214 
0215     inline explicit QVersionNumber(int maj, int min)
0216     { m_segments.setSegments(2, maj, min); }
0217 
0218     inline explicit QVersionNumber(int maj, int min, int mic)
0219     { m_segments.setSegments(3, maj, min, mic); }
0220 
0221     [[nodiscard]] inline bool isNull() const noexcept
0222     { return segmentCount() == 0; }
0223 
0224     [[nodiscard]] inline bool isNormalized() const noexcept
0225     { return isNull() || segmentAt(segmentCount() - 1) != 0; }
0226 
0227     [[nodiscard]] inline int majorVersion() const noexcept
0228     { return segmentAt(0); }
0229 
0230     [[nodiscard]] inline int minorVersion() const noexcept
0231     { return segmentAt(1); }
0232 
0233     [[nodiscard]] inline int microVersion() const noexcept
0234     { return segmentAt(2); }
0235 
0236     [[nodiscard]] Q_CORE_EXPORT QVersionNumber normalized() const;
0237 
0238     [[nodiscard]] Q_CORE_EXPORT QList<int> segments() const;
0239 
0240     [[nodiscard]] inline int segmentAt(qsizetype index) const noexcept
0241     { return (m_segments.size() > index) ? m_segments.at(index) : 0; }
0242 
0243     [[nodiscard]] inline qsizetype segmentCount() const noexcept
0244     { return m_segments.size(); }
0245 
0246     [[nodiscard]] Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept;
0247 
0248     [[nodiscard]] Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept;
0249 
0250     [[nodiscard]] Q_CORE_EXPORT static QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2);
0251 
0252     [[nodiscard]] Q_CORE_EXPORT QString toString() const;
0253     [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex = nullptr);
0254 
0255 #if QT_DEPRECATED_SINCE(6, 4) && QT_POINTER_SIZE != 4
0256     Q_WEAK_OVERLOAD
0257     QT_DEPRECATED_VERSION_X_6_4("Use the 'qsizetype *suffixIndex' overload.")
0258     [[nodiscard]] static QVersionNumber fromString(QAnyStringView string, int *suffixIndex)
0259     {
0260         QT_WARNING_PUSH
0261         // fromString() writes to *n unconditionally, but GCC can't know that
0262         QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
0263         qsizetype n;
0264         auto r = fromString(string, &n);
0265         if (suffixIndex) {
0266             Q_ASSERT(int(n) == n);
0267             *suffixIndex = int(n);
0268         }
0269         return r;
0270         QT_WARNING_POP
0271     }
0272 #endif
0273 
0274 
0275 #if QT_CORE_REMOVED_SINCE(6, 4)
0276     [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex);
0277     [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(QLatin1StringView string, int *suffixIndex);
0278     [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex);
0279 #endif
0280 
0281     [[nodiscard]] friend bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
0282     { return compare(lhs, rhs) > 0; }
0283 
0284     [[nodiscard]] friend bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
0285     { return compare(lhs, rhs) >= 0; }
0286 
0287     [[nodiscard]] friend bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
0288     { return compare(lhs, rhs) < 0; }
0289 
0290     [[nodiscard]] friend bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
0291     { return compare(lhs, rhs) <= 0; }
0292 
0293     [[nodiscard]] friend bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
0294     { return compare(lhs, rhs) == 0; }
0295 
0296     [[nodiscard]] friend bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
0297     { return compare(lhs, rhs) != 0; }
0298 
0299 private:
0300 #ifndef QT_NO_DATASTREAM
0301     friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
0302 #endif
0303     friend Q_CORE_EXPORT size_t qHash(const QVersionNumber &key, size_t seed);
0304 };
0305 
0306 Q_DECLARE_TYPEINFO(QVersionNumber, Q_RELOCATABLE_TYPE);
0307 
0308 #ifndef QT_NO_DEBUG_STREAM
0309 Q_CORE_EXPORT QDebug operator<<(QDebug, const QVersionNumber &version);
0310 #endif
0311 
0312 QT_END_NAMESPACE
0313 
0314 QT_DECL_METATYPE_EXTERN(QVersionNumber, Q_CORE_EXPORT)
0315 
0316 #endif // QVERSIONNUMBER_H