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