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