File indexing completed on 2026-05-10 08:44:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_SUPPORT_VERSIONTUPLE_H
0015 #define LLVM_SUPPORT_VERSIONTUPLE_H
0016
0017 #include "llvm/ADT/DenseMapInfo.h"
0018 #include "llvm/ADT/Hashing.h"
0019 #include <optional>
0020 #include <string>
0021 #include <tuple>
0022
0023 namespace llvm {
0024 template <typename HasherT, llvm::endianness Endianness> class HashBuilder;
0025 class raw_ostream;
0026 class StringRef;
0027
0028
0029 class VersionTuple {
0030 unsigned Major : 32;
0031
0032 unsigned Minor : 31;
0033 unsigned HasMinor : 1;
0034
0035 unsigned Subminor : 31;
0036 unsigned HasSubminor : 1;
0037
0038 unsigned Build : 31;
0039 unsigned HasBuild : 1;
0040
0041 public:
0042 constexpr VersionTuple()
0043 : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false),
0044 Build(0), HasBuild(false) {}
0045
0046 explicit constexpr VersionTuple(unsigned Major)
0047 : Major(Major), Minor(0), HasMinor(false), Subminor(0),
0048 HasSubminor(false), Build(0), HasBuild(false) {}
0049
0050 explicit constexpr VersionTuple(unsigned Major, unsigned Minor)
0051 : Major(Major), Minor(Minor), HasMinor(true), Subminor(0),
0052 HasSubminor(false), Build(0), HasBuild(false) {}
0053
0054 explicit constexpr VersionTuple(unsigned Major, unsigned Minor,
0055 unsigned Subminor)
0056 : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
0057 HasSubminor(true), Build(0), HasBuild(false) {}
0058
0059 explicit constexpr VersionTuple(unsigned Major, unsigned Minor,
0060 unsigned Subminor, unsigned Build)
0061 : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
0062 HasSubminor(true), Build(Build), HasBuild(true) {}
0063
0064
0065
0066 bool empty() const {
0067 return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0;
0068 }
0069
0070
0071 unsigned getMajor() const { return Major; }
0072
0073
0074 std::optional<unsigned> getMinor() const {
0075 if (!HasMinor)
0076 return std::nullopt;
0077 return Minor;
0078 }
0079
0080
0081 std::optional<unsigned> getSubminor() const {
0082 if (!HasSubminor)
0083 return std::nullopt;
0084 return Subminor;
0085 }
0086
0087
0088 std::optional<unsigned> getBuild() const {
0089 if (!HasBuild)
0090 return std::nullopt;
0091 return Build;
0092 }
0093
0094
0095 VersionTuple withoutBuild() const {
0096 if (HasBuild)
0097 return VersionTuple(Major, Minor, Subminor);
0098 return *this;
0099 }
0100
0101
0102
0103 VersionTuple withMajorReplaced(unsigned NewMajor) const {
0104 return VersionTuple(NewMajor, Minor, Subminor, Build);
0105 }
0106
0107
0108 VersionTuple normalize() const {
0109 VersionTuple Result = *this;
0110 if (Result.Build == 0) {
0111 Result.HasBuild = false;
0112 if (Result.Subminor == 0) {
0113 Result.HasSubminor = false;
0114 if (Result.Minor == 0)
0115 Result.HasMinor = false;
0116 }
0117 }
0118 return Result;
0119 }
0120
0121
0122
0123 friend bool operator==(const VersionTuple &X, const VersionTuple &Y) {
0124 return X.Major == Y.Major && X.Minor == Y.Minor &&
0125 X.Subminor == Y.Subminor && X.Build == Y.Build;
0126 }
0127
0128
0129
0130
0131
0132 friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
0133 return !(X == Y);
0134 }
0135
0136
0137
0138
0139
0140 friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
0141 return std::tie(X.Major, X.Minor, X.Subminor, X.Build) <
0142 std::tie(Y.Major, Y.Minor, Y.Subminor, Y.Build);
0143 }
0144
0145
0146
0147
0148
0149 friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
0150 return Y < X;
0151 }
0152
0153
0154
0155
0156
0157
0158 friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
0159 return !(Y < X);
0160 }
0161
0162
0163
0164
0165
0166
0167 friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
0168 return !(X < Y);
0169 }
0170
0171 friend hash_code hash_value(const VersionTuple &VT) {
0172 return hash_combine(VT.Major, VT.Minor, VT.Subminor, VT.Build);
0173 }
0174
0175 template <typename HasherT, llvm::endianness Endianness>
0176 friend void addHash(HashBuilder<HasherT, Endianness> &HBuilder,
0177 const VersionTuple &VT) {
0178 HBuilder.add(VT.Major, VT.Minor, VT.Subminor, VT.Build);
0179 }
0180
0181
0182 std::string getAsString() const;
0183
0184
0185
0186
0187 bool tryParse(StringRef string);
0188 };
0189
0190
0191 raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V);
0192
0193
0194 template <> struct DenseMapInfo<VersionTuple> {
0195 static inline VersionTuple getEmptyKey() { return VersionTuple(0x7FFFFFFF); }
0196 static inline VersionTuple getTombstoneKey() {
0197 return VersionTuple(0x7FFFFFFE);
0198 }
0199 static unsigned getHashValue(const VersionTuple &Value) {
0200 unsigned Result = Value.getMajor();
0201 if (auto Minor = Value.getMinor())
0202 Result = detail::combineHashValue(Result, *Minor);
0203 if (auto Subminor = Value.getSubminor())
0204 Result = detail::combineHashValue(Result, *Subminor);
0205 if (auto Build = Value.getBuild())
0206 Result = detail::combineHashValue(Result, *Build);
0207
0208 return Result;
0209 }
0210
0211 static bool isEqual(const VersionTuple &LHS, const VersionTuple &RHS) {
0212 return LHS == RHS;
0213 }
0214 };
0215
0216 }
0217 #endif