Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-08 09:23:54

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 // Qt-Security score:critical reason:data-parser
0006 
0007 #ifndef QTYPEREVISION_H
0008 #define QTYPEREVISION_H
0009 
0010 #include <QtCore/qassert.h>
0011 #include <QtCore/qcompare.h>
0012 #include <QtCore/qcontainertools_impl.h>
0013 #include <QtCore/qmetatype.h>
0014 #include <QtCore/qtypeinfo.h>
0015 
0016 #include <limits>
0017 
0018 QT_BEGIN_NAMESPACE
0019 
0020 class QDataStream;
0021 class QDebug;
0022 
0023 class QTypeRevision;
0024 Q_CORE_EXPORT size_t qHash(const QTypeRevision &key, size_t seed = 0);
0025 
0026 #ifndef QT_NO_DATASTREAM
0027 Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QTypeRevision &revision);
0028 Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QTypeRevision &revision);
0029 #endif
0030 
0031 class QTypeRevision
0032 {
0033 public:
0034     template<typename Integer>
0035     using if_valid_segment_type = typename std::enable_if<
0036             std::is_integral<Integer>::value, bool>::type;
0037 
0038     template<typename Integer>
0039     using if_valid_value_type = typename std::enable_if<
0040             std::is_integral<Integer>::value
0041             && (sizeof(Integer) > sizeof(quint16)
0042                 || (sizeof(Integer) == sizeof(quint16)
0043                     && !std::is_signed<Integer>::value)), bool>::type;
0044 
0045     template<typename Integer, if_valid_segment_type<Integer> = true>
0046     static constexpr bool isValidSegment(Integer segment)
0047     {
0048         // using extra parentheses around max to avoid expanding it if it is a macro
0049         // and adding zero to cause it to be promoted
0050         constexpr auto Max = (std::numeric_limits<Integer>::max)() + 0;
0051         constexpr bool HasSufficientRange = Max >= SegmentUnknown;
0052         return segment >= Integer(0)
0053                 && (!HasSufficientRange || segment < Integer(SegmentUnknown));
0054     }
0055 
0056     template<typename Major, typename Minor,
0057              if_valid_segment_type<Major> = true,
0058              if_valid_segment_type<Minor> = true>
0059     static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
0060     {
0061         return Q_ASSERT(isValidSegment(majorVersion)),
0062                Q_ASSERT(isValidSegment(minorVersion)),
0063                QTypeRevision(quint8(majorVersion), quint8(minorVersion));
0064     }
0065 
0066     template<typename Major, if_valid_segment_type<Major> = true>
0067     static constexpr QTypeRevision fromMajorVersion(Major majorVersion)
0068     {
0069         return Q_ASSERT(isValidSegment(majorVersion)),
0070                QTypeRevision(quint8(majorVersion), SegmentUnknown);
0071     }
0072 
0073     template<typename Minor, if_valid_segment_type<Minor> = true>
0074     static constexpr QTypeRevision fromMinorVersion(Minor minorVersion)
0075     {
0076         return Q_ASSERT(isValidSegment(minorVersion)),
0077                QTypeRevision(SegmentUnknown, quint8(minorVersion));
0078     }
0079 
0080     template<typename Integer, if_valid_value_type<Integer> = true>
0081     static constexpr QTypeRevision fromEncodedVersion(Integer value)
0082     {
0083         return Q_ASSERT((value & ~Integer(0xffff)) == Integer(0)),
0084                QTypeRevision((value & Integer(0xff00)) >> 8, value & Integer(0xff));
0085     }
0086 
0087     static constexpr QTypeRevision zero() { return QTypeRevision(0, 0); }
0088 
0089     constexpr QTypeRevision() = default;
0090 
0091     constexpr bool hasMajorVersion() const { return m_majorVersion != SegmentUnknown; }
0092     constexpr quint8 majorVersion() const { return m_majorVersion; }
0093 
0094     constexpr bool hasMinorVersion() const { return m_minorVersion != SegmentUnknown; }
0095     constexpr quint8 minorVersion() const { return m_minorVersion; }
0096 
0097     constexpr bool isValid() const { return hasMajorVersion() || hasMinorVersion(); }
0098 
0099     template<typename Integer, if_valid_value_type<Integer> = true>
0100     constexpr Integer toEncodedVersion() const
0101     {
0102         return Integer(m_majorVersion << 8) | Integer(m_minorVersion);
0103     }
0104 
0105 private:
0106     friend constexpr bool
0107     comparesEqual(const QTypeRevision &lhs, const QTypeRevision &rhs) noexcept
0108     { return lhs.toEncodedVersion<quint16>() == rhs.toEncodedVersion<quint16>(); }
0109     friend constexpr Qt::strong_ordering
0110     compareThreeWay(const QTypeRevision &lhs, const QTypeRevision &rhs) noexcept
0111     {
0112         // For both major and minor the following rule applies:
0113         // non-0 ver > unspecified ver > 0 ver
0114         auto cmpUnspecified = [](quint8 leftVer, quint8 rightVer) {
0115             Q_ASSERT(leftVer != rightVer
0116                      && (leftVer == QTypeRevision::SegmentUnknown
0117                          || rightVer == QTypeRevision::SegmentUnknown));
0118             if (leftVer != QTypeRevision::SegmentUnknown)
0119                 return leftVer > 0 ? Qt::strong_ordering::greater : Qt::strong_ordering::less;
0120             return rightVer > 0 ? Qt::strong_ordering::less : Qt::strong_ordering::greater;
0121         };
0122 
0123         if (lhs.hasMajorVersion() != rhs.hasMajorVersion()) {
0124             return cmpUnspecified(lhs.majorVersion(), rhs.majorVersion());
0125         } else {
0126             const auto majorRes = Qt::compareThreeWay(lhs.majorVersion(), rhs.majorVersion());
0127             if (is_eq(majorRes)) {
0128                 if (lhs.hasMinorVersion() != rhs.hasMinorVersion())
0129                     return cmpUnspecified(lhs.minorVersion(), rhs.minorVersion());
0130                 return Qt::compareThreeWay(lhs.minorVersion(), rhs.minorVersion());
0131             }
0132             return majorRes;
0133         }
0134     }
0135     Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QTypeRevision)
0136 
0137     enum { SegmentUnknown = 0xff };
0138 
0139 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
0140     constexpr QTypeRevision(quint8 major, quint8 minor)
0141         : m_minorVersion(minor), m_majorVersion(major) {}
0142 
0143     quint8 m_minorVersion = SegmentUnknown;
0144     quint8 m_majorVersion = SegmentUnknown;
0145 #else
0146     constexpr QTypeRevision(quint8 major, quint8 minor)
0147         : m_majorVersion(major), m_minorVersion(minor) {}
0148 
0149     quint8 m_majorVersion = SegmentUnknown;
0150     quint8 m_minorVersion = SegmentUnknown;
0151 #endif
0152 };
0153 
0154 static_assert(sizeof(QTypeRevision) == 2);
0155 Q_DECLARE_TYPEINFO(QTypeRevision, Q_RELOCATABLE_TYPE);
0156 
0157 #ifndef QT_NO_DEBUG_STREAM
0158 Q_CORE_EXPORT QDebug operator<<(QDebug, const QTypeRevision &revision);
0159 #endif
0160 
0161 QT_END_NAMESPACE
0162 
0163 QT_DECL_METATYPE_EXTERN(QTypeRevision, Q_CORE_EXPORT)
0164 
0165 #endif // QTYPEREVISION_H
0166 
0167 #if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 2
0168 // make QVersionNumber available from <QTypeRevision>
0169 #include <QtCore/qversionnumber.h>
0170 #endif