VersionTuple.h revision af50aab0c317462129d73ae8000c6394c718598d
10a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===//
20a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//
30a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//                     The LLVM Compiler Infrastructure
40a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//
50a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// This file is distributed under the University of Illinois Open Source
60a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor// License. See LICENSE.TXT for details.
70a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//
80a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//===----------------------------------------------------------------------===//
92f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett///
102f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \file
112f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// \brief Defines the clang::VersionTuple class, which represents a version in
122f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett/// the form major[.minor[.subminor]].
132f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622James Dennett///
140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor//===----------------------------------------------------------------------===//
150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H
160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#define LLVM_CLANG_BASIC_VERSIONTUPLE_H
170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
188cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner#include "clang/Basic/LLVM.h"
190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#include "llvm/ADT/Optional.h"
200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#include <string>
210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregornamespace clang {
230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor/// \brief Represents a version number in the form major[.minor[.subminor]].
250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorclass VersionTuple {
260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  unsigned Major;
270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  unsigned Minor : 31;
280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  unsigned Subminor : 31;
290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  unsigned HasMinor : 1;
300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  unsigned HasSubminor : 1;
310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorpublic:
330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  VersionTuple()
340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) { }
350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  explicit VersionTuple(unsigned Major)
370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false)
380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  { }
390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
400a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  explicit VersionTuple(unsigned Major, unsigned Minor)
410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    : Major(Major), Minor(Minor), Subminor(0), HasMinor(true),
420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      HasSubminor(false)
430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  { }
440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    : Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true),
470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      HasSubminor(true)
480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  { }
490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Determine whether this version information is empty
510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// (e.g., all version components are zero).
520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; }
530a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Retrieve the major version number.
550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  unsigned getMajor() const { return Major; }
560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Retrieve the minor version number, if provided.
580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  llvm::Optional<unsigned> getMinor() const {
590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (!HasMinor)
600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      return llvm::Optional<unsigned>();
610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return Minor;
620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Retrieve the subminor version number, if provided.
650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  llvm::Optional<unsigned> getSubminor() const {
660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (!HasSubminor)
670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      return llvm::Optional<unsigned>();
680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return Subminor;
690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Determine if two version numbers are equivalent. If not
720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// provided, minor and subminor version numbers are considered to be zero.
730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  friend bool operator==(const VersionTuple& X, const VersionTuple &Y) {
740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return X.Major == Y.Major && X.Minor == Y.Minor && X.Subminor == Y.Subminor;
750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
77af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Determine if two version numbers are not equivalent.
78af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
79af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// If not provided, minor and subminor version numbers are considered to be
800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// zero.
810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return !(X == Y);
830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
85af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Determine whether one version number precedes another.
86af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
87af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// If not provided, minor and subminor version numbers are considered to be
88af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// zero.
890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (X.Major != Y.Major)
910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      return X.Major < Y.Major;
920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    if (X.Minor != Y.Minor)
940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      return X.Minor < Y.Minor;
950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return X.Subminor < Y.Subminor;
970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
99af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Determine whether one version number follows another.
100af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
101af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// If not provided, minor and subminor version numbers are considered to be
102af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// zero.
1030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
1040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return Y < X;
1050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
1060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Determine whether one version number precedes or is
108af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// equivalent to another.
109af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
110af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// If not provided, minor and subminor version numbers are considered to be
111af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// zero.
1120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
1130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return !(Y < X);
1140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
1150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Determine whether one version number follows or is
117af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// equivalent to another.
118af50aab0c317462129d73ae8000c6394c718598dJames Dennett  ///
119af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// If not provided, minor and subminor version numbers are considered to be
120af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// zero.
1210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
1220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor    return !(X < Y);
1230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  }
1240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
125af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \brief Retrieve a string representation of the version number.
1260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  std::string getAsString() const;
127260611a32535c851237926bfcf78869b13c07d5bJohn McCall
128260611a32535c851237926bfcf78869b13c07d5bJohn McCall  /// \brief Try to parse the given string as a version number.
129af50aab0c317462129d73ae8000c6394c718598dJames Dennett  /// \returns \c true if the string does not match the regular expression
130260611a32535c851237926bfcf78869b13c07d5bJohn McCall  ///   [0-9]+(\.[0-9]+(\.[0-9]+))
131260611a32535c851237926bfcf78869b13c07d5bJohn McCall  bool tryParse(StringRef string);
1320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor};
1330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor/// \brief Print a version number.
1358cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattnerraw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V);
1360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
1370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} // end namespace clang
1380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H
139