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