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