1221339Sdim//===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===//
2221339Sdim//
3221339Sdim//                     The LLVM Compiler Infrastructure
4221339Sdim//
5221339Sdim// This file is distributed under the University of Illinois Open Source
6221339Sdim// License. See LICENSE.TXT for details.
7221339Sdim//
8221339Sdim//===----------------------------------------------------------------------===//
9239462Sdim///
10239462Sdim/// \file
11239462Sdim/// \brief Defines the clang::VersionTuple class, which represents a version in
12239462Sdim/// the form major[.minor[.subminor]].
13239462Sdim///
14221339Sdim//===----------------------------------------------------------------------===//
15221339Sdim#ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H
16221339Sdim#define LLVM_CLANG_BASIC_VERSIONTUPLE_H
17221339Sdim
18226633Sdim#include "clang/Basic/LLVM.h"
19221339Sdim#include "llvm/ADT/Optional.h"
20221339Sdim#include <string>
21221339Sdim
22221339Sdimnamespace clang {
23221339Sdim
24221339Sdim/// \brief Represents a version number in the form major[.minor[.subminor]].
25221339Sdimclass VersionTuple {
26221339Sdim  unsigned Major;
27221339Sdim  unsigned Minor : 31;
28221339Sdim  unsigned Subminor : 31;
29221339Sdim  unsigned HasMinor : 1;
30221339Sdim  unsigned HasSubminor : 1;
31221339Sdim
32221339Sdimpublic:
33221339Sdim  VersionTuple()
34221339Sdim    : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) { }
35221339Sdim
36221339Sdim  explicit VersionTuple(unsigned Major)
37221339Sdim    : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false)
38221339Sdim  { }
39221339Sdim
40221339Sdim  explicit VersionTuple(unsigned Major, unsigned Minor)
41221339Sdim    : Major(Major), Minor(Minor), Subminor(0), HasMinor(true),
42221339Sdim      HasSubminor(false)
43221339Sdim  { }
44221339Sdim
45221339Sdim  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
46221339Sdim    : Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true),
47221339Sdim      HasSubminor(true)
48221339Sdim  { }
49221339Sdim
50221339Sdim  /// \brief Determine whether this version information is empty
51221339Sdim  /// (e.g., all version components are zero).
52221339Sdim  bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; }
53221339Sdim
54221339Sdim  /// \brief Retrieve the major version number.
55221339Sdim  unsigned getMajor() const { return Major; }
56221339Sdim
57221339Sdim  /// \brief Retrieve the minor version number, if provided.
58249423Sdim  Optional<unsigned> getMinor() const {
59221339Sdim    if (!HasMinor)
60249423Sdim      return None;
61221339Sdim    return Minor;
62221339Sdim  }
63221339Sdim
64221339Sdim  /// \brief Retrieve the subminor version number, if provided.
65249423Sdim  Optional<unsigned> getSubminor() const {
66221339Sdim    if (!HasSubminor)
67249423Sdim      return None;
68221339Sdim    return Subminor;
69221339Sdim  }
70221339Sdim
71221339Sdim  /// \brief Determine if two version numbers are equivalent. If not
72221339Sdim  /// provided, minor and subminor version numbers are considered to be zero.
73221339Sdim  friend bool operator==(const VersionTuple& X, const VersionTuple &Y) {
74221339Sdim    return X.Major == Y.Major && X.Minor == Y.Minor && X.Subminor == Y.Subminor;
75221339Sdim  }
76221339Sdim
77239462Sdim  /// \brief Determine if two version numbers are not equivalent.
78239462Sdim  ///
79239462Sdim  /// If not provided, minor and subminor version numbers are considered to be
80221339Sdim  /// zero.
81221339Sdim  friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
82221339Sdim    return !(X == Y);
83221339Sdim  }
84221339Sdim
85239462Sdim  /// \brief Determine whether one version number precedes another.
86239462Sdim  ///
87239462Sdim  /// If not provided, minor and subminor version numbers are considered to be
88239462Sdim  /// zero.
89221339Sdim  friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
90221339Sdim    if (X.Major != Y.Major)
91221339Sdim      return X.Major < Y.Major;
92221339Sdim
93221339Sdim    if (X.Minor != Y.Minor)
94221339Sdim      return X.Minor < Y.Minor;
95221339Sdim
96221339Sdim    return X.Subminor < Y.Subminor;
97221339Sdim  }
98221339Sdim
99239462Sdim  /// \brief Determine whether one version number follows another.
100239462Sdim  ///
101239462Sdim  /// If not provided, minor and subminor version numbers are considered to be
102239462Sdim  /// zero.
103221339Sdim  friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
104221339Sdim    return Y < X;
105221339Sdim  }
106221339Sdim
107221339Sdim  /// \brief Determine whether one version number precedes or is
108239462Sdim  /// equivalent to another.
109239462Sdim  ///
110239462Sdim  /// If not provided, minor and subminor version numbers are considered to be
111239462Sdim  /// zero.
112221339Sdim  friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
113221339Sdim    return !(Y < X);
114221339Sdim  }
115221339Sdim
116221339Sdim  /// \brief Determine whether one version number follows or is
117239462Sdim  /// equivalent to another.
118239462Sdim  ///
119239462Sdim  /// If not provided, minor and subminor version numbers are considered to be
120239462Sdim  /// zero.
121221339Sdim  friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
122221339Sdim    return !(X < Y);
123221339Sdim  }
124221339Sdim
125239462Sdim  /// \brief Retrieve a string representation of the version number.
126221339Sdim  std::string getAsString() const;
127239462Sdim
128239462Sdim  /// \brief Try to parse the given string as a version number.
129239462Sdim  /// \returns \c true if the string does not match the regular expression
130239462Sdim  ///   [0-9]+(\.[0-9]+(\.[0-9]+))
131239462Sdim  bool tryParse(StringRef string);
132221339Sdim};
133221339Sdim
134221339Sdim/// \brief Print a version number.
135226633Sdimraw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V);
136221339Sdim
137221339Sdim} // end namespace clang
138221339Sdim#endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H
139