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