Mantid
Loading...
Searching...
No Matches
SemanticVersion.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
9#include <algorithm>
10#include <cctype>
11#include <charconv>
12#include <cstddef>
13#include <format>
14#include <stdexcept>
15
16namespace Mantid {
17
18namespace DataObjects {
19
20namespace {
21
22// trimming spaces
23std::string trim(std::string s) {
24 auto not_space = [](unsigned char c) { return !std::isspace(c); };
25
26 s.erase(s.begin(), std::find_if(s.begin(), s.end(), not_space));
27 s.erase(std::find_if(s.rbegin(), s.rend(), not_space).base(), s.end());
28
29 return s;
30}
31
32} // namespace
33
34std::regex
35 SemanticVersion::version_regex(R"(^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$)");
36
45SemanticVersion::SemanticVersion(const std::string &version) : m_version(version) { parse_version(version); }
46
55SemanticVersion::SemanticVersion(std::uint32_t major, std::uint32_t minor, std::uint32_t patch,
56 const std::string &prerelease, const std::string &build)
57 : m_major(major), m_minor(minor), m_patch(patch), m_prerelease(trim(prerelease)), m_build(trim(build)) {
58 // cppcheck-suppress useInitializationList
59 m_version = std::format("{}.{}.{}", major, minor, patch);
60 if (!m_prerelease.empty())
61 m_version = std::format("{}-{}", m_version, m_prerelease);
62
63 if (!m_build.empty())
64 m_version = std::format("{}+{}", m_version, m_build);
65}
66
72 return (m_major == other.m_major) && (m_minor == other.m_minor) && (m_patch == other.m_patch) &&
73 (m_prerelease == other.m_prerelease);
74}
75
82std::strong_ordering SemanticVersion::operator<=>(const SemanticVersion &other) const {
83 if (auto cmp = m_major <=> other.m_major; cmp != 0)
84 return cmp;
85
86 if (auto cmp = m_minor <=> other.m_minor; cmp != 0)
87 return cmp;
88
89 if (auto cmp = m_patch <=> other.m_patch; cmp != 0)
90 return cmp;
91
92 // According SemVer the build is not used to differentiate two versions so the comparison is stopped at the prerelease
93 return m_prerelease <=> other.m_prerelease;
94}
95
102std::strong_ordering SemanticVersion::operator<=>(const std::string &otherVersionStr) const {
103 return *this <=> SemanticVersion(otherVersionStr);
104}
105
106const std::string &SemanticVersion::getBuild() const { return m_build; }
107
108std::uint32_t SemanticVersion::getMajor() const { return m_major; }
109
110std::uint32_t SemanticVersion::getMinor() const { return m_minor; }
111
112std::uint32_t SemanticVersion::getPatch() const { return m_patch; }
113
114const std::string &SemanticVersion::getPrerelease() const { return m_prerelease; }
115
116const std::string &SemanticVersion::getVersion() const { return m_version; }
117
122void SemanticVersion::parse_version(const std::string &version) {
123
124 std::smatch m;
125 if (!std::regex_match(version, m, version_regex))
126 throw std::runtime_error(std::format("Invalid version: {}", version));
127
128 std::uint32_t value = 0;
129
130 std::string matchStr = m[1].str();
131 {
132 auto [ptr, ec] = std::from_chars(matchStr.data(), matchStr.data() + matchStr.size(), value);
133 if (ec != std::errc())
134 throw std::runtime_error(std::format("Invalid major revision number: {}", matchStr));
135 }
136 m_major = value;
137
138 if (m[2].matched) {
139 matchStr = m[2].str();
140 {
141 auto [ptr, ec] = std::from_chars(matchStr.data(), matchStr.data() + matchStr.size(), value);
142 if (ec != std::errc())
143 throw std::runtime_error(std::format("Invalid minor revision number: {}", m[2].str()));
144 }
145 m_minor = value;
146 }
147
148 if (m[3].matched) {
149 matchStr = m[3].str();
150 {
151 auto [ptr, ec] = std::from_chars(matchStr.data(), matchStr.data() + matchStr.size(), value);
152 if (ec != std::errc())
153 throw std::runtime_error(std::format("Invalid minor revision number: {}", m[3].str()));
154 }
155 m_patch = value;
156 }
157
158 // No need to trim the match, covered by the regex
159 if (m[4].matched)
160 m_prerelease = m[4].str();
161
162 // No need to trim the match, covered by the regex
163 if (m[5].matched)
164 m_build = m[5].str();
165}
166
167} // end namespace DataObjects
168
169} // end namespace Mantid
double value
The value of the point.
Definition FitMW.cpp:51
Implementation of a SemVer parser.
void parse_version(const std::string &)
Check and split the version string into major, minor, patch, etc.
const std::string & getVersion() const
const std::string & getBuild() const
const std::string & getPrerelease() const
bool operator==(const SemanticVersion &other) const
Check if two versions are equivalent.
std::strong_ordering operator<=>(const SemanticVersion &other) const
Comparison operator.
Helper class which provides the Collimation Length for SANS instruments.