Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:09:37

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