1 //===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Defines the clang::VersionTuple class, which represents a version in 12 /// the form major[.minor[.subminor]]. 13 /// 14 //===----------------------------------------------------------------------===// 15 #ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H 16 #define LLVM_CLANG_BASIC_VERSIONTUPLE_H 17 18 #include "clang/Basic/LLVM.h" 19 #include "llvm/ADT/Optional.h" 20 #include <string> 21 #include <tuple> 22 23 namespace clang { 24 25 /// \brief Represents a version number in the form major[.minor[.subminor[.build]]]. 26 class VersionTuple { 27 unsigned Major : 31; 28 29 unsigned UsesUnderscores : 1; 30 31 unsigned Minor : 31; 32 unsigned HasMinor : 1; 33 34 unsigned Subminor : 31; 35 unsigned HasSubminor : 1; 36 37 unsigned Build : 31; 38 unsigned HasBuild : 1; 39 40 public: VersionTuple()41 VersionTuple() 42 : Major(0), UsesUnderscores(false), Minor(0), HasMinor(false), 43 Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} 44 VersionTuple(unsigned Major)45 explicit VersionTuple(unsigned Major) 46 : Major(Major), UsesUnderscores(false), Minor(0), HasMinor(false), 47 Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} 48 49 explicit VersionTuple(unsigned Major, unsigned Minor, 50 bool UsesUnderscores = false) Major(Major)51 : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor), 52 HasMinor(true), Subminor(0), HasSubminor(false), Build(0), 53 HasBuild(false) {} 54 55 explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, 56 bool UsesUnderscores = false) Major(Major)57 : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor), 58 HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0), 59 HasBuild(false) {} 60 61 explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, 62 unsigned Build, bool UsesUnderscores = false) Major(Major)63 : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor), 64 HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build), 65 HasBuild(true) {} 66 67 /// \brief Determine whether this version information is empty 68 /// (e.g., all version components are zero). empty()69 bool empty() const { 70 return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0; 71 } 72 73 /// \brief Retrieve the major version number. getMajor()74 unsigned getMajor() const { return Major; } 75 76 /// \brief Retrieve the minor version number, if provided. getMinor()77 Optional<unsigned> getMinor() const { 78 if (!HasMinor) 79 return None; 80 return Minor; 81 } 82 83 /// \brief Retrieve the subminor version number, if provided. getSubminor()84 Optional<unsigned> getSubminor() const { 85 if (!HasSubminor) 86 return None; 87 return Subminor; 88 } 89 90 /// \brief Retrieve the build version number, if provided. getBuild()91 Optional<unsigned> getBuild() const { 92 if (!HasBuild) 93 return None; 94 return Build; 95 } 96 usesUnderscores()97 bool usesUnderscores() const { 98 return UsesUnderscores; 99 } 100 UseDotAsSeparator()101 void UseDotAsSeparator() { 102 UsesUnderscores = false; 103 } 104 105 /// \brief Determine if two version numbers are equivalent. If not 106 /// provided, minor and subminor version numbers are considered to be zero. 107 friend bool operator==(const VersionTuple& X, const VersionTuple &Y) { 108 return X.Major == Y.Major && X.Minor == Y.Minor && 109 X.Subminor == Y.Subminor && X.Build == Y.Build; 110 } 111 112 /// \brief Determine if two version numbers are not equivalent. 113 /// 114 /// If not provided, minor and subminor version numbers are considered to be 115 /// zero. 116 friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) { 117 return !(X == Y); 118 } 119 120 /// \brief Determine whether one version number precedes another. 121 /// 122 /// If not provided, minor and subminor version numbers are considered to be 123 /// zero. 124 friend bool operator<(const VersionTuple &X, const VersionTuple &Y) { 125 return std::tie(X.Major, X.Minor, X.Subminor, X.Build) < 126 std::tie(Y.Major, Y.Minor, Y.Subminor, Y.Build); 127 } 128 129 /// \brief Determine whether one version number follows another. 130 /// 131 /// If not provided, minor and subminor version numbers are considered to be 132 /// zero. 133 friend bool operator>(const VersionTuple &X, const VersionTuple &Y) { 134 return Y < X; 135 } 136 137 /// \brief Determine whether one version number precedes or is 138 /// equivalent to another. 139 /// 140 /// If not provided, minor and subminor version numbers are considered to be 141 /// zero. 142 friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) { 143 return !(Y < X); 144 } 145 146 /// \brief Determine whether one version number follows or is 147 /// equivalent to another. 148 /// 149 /// If not provided, minor and subminor version numbers are considered to be 150 /// zero. 151 friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) { 152 return !(X < Y); 153 } 154 155 /// \brief Retrieve a string representation of the version number. 156 std::string getAsString() const; 157 158 /// \brief Try to parse the given string as a version number. 159 /// \returns \c true if the string does not match the regular expression 160 /// [0-9]+(\.[0-9]+){0,3} 161 bool tryParse(StringRef string); 162 }; 163 164 /// \brief Print a version number. 165 raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V); 166 167 } // end namespace clang 168 #endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H 169