13 #ifndef __STOUT_VERSION_HPP__ 14 #define __STOUT_VERSION_HPP__ 66 std::vector<std::string> buildLabel;
68 std::vector<std::string> buildParts =
strings::split(input,
"+", 2);
69 CHECK(buildParts.size() == 1 || buildParts.size() == 2);
71 if (buildParts.size() == 2) {
72 const std::string& buildString = buildParts.back();
76 return Error(
"Invalid build label: " + parsed.
error());
79 buildLabel = parsed.
get();
82 std::string remainder = buildParts.front();
86 std::vector<std::string> prereleaseLabel;
88 std::vector<std::string> prereleaseParts =
90 CHECK(prereleaseParts.size() == 1 || prereleaseParts.size() == 2);
92 if (prereleaseParts.size() == 2) {
93 const std::string& prereleaseString = prereleaseParts.back();
97 return Error(
"Invalid prerelease label: " + parsed.
error());
100 prereleaseLabel = parsed.
get();
103 remainder = prereleaseParts.front();
105 constexpr
size_t maxNumericComponents = 3;
106 std::vector<std::string> numericComponents =
strings::split(remainder,
".");
108 if (numericComponents.size() > maxNumericComponents) {
109 return Error(
"Version has " +
stringify(numericComponents.size()) +
110 " components; maximum " +
stringify(maxNumericComponents) +
111 " components allowed");
114 uint32_t versionNumbers[maxNumericComponents] = {0};
116 for (
size_t i = 0; i < numericComponents.size(); i++) {
117 Try<uint32_t> result = parseNumericIdentifier(numericComponents[i]);
119 return Error(
"Invalid version component '" + numericComponents[i] +
"'" 120 ": " + result.
error());
123 versionNumbers[i] = result.
get();
126 return Version(versionNumbers[0],
136 uint32_t _minorVersion,
137 uint32_t _patchVersion,
138 const std::vector<std::string>& _prerelease = {},
139 const std::vector<std::string>& _build = {})
149 foreach (
const std::string& identifier,
prerelease) {
153 foreach (
const std::string& identifier,
build) {
170 return !(*
this == other);
222 size_t minPrereleaseSize =
std::min(
225 for (
size_t i = 0; i < minPrereleaseSize; i++) {
230 parseNumericIdentifier(other.
prerelease.at(i));
232 if (identifier.
isSome() && otherIdentifier.isSome()) {
234 if (identifier.
get() != otherIdentifier.get()) {
235 return identifier.
get() < otherIdentifier.get();
237 }
else if (identifier.
isSome()) {
241 }
else if (otherIdentifier.isSome()) {
261 return other < *
this;
266 return *
this < other || *
this == other;
271 return *
this > other || *
this == other;
275 std::ostream& stream,
282 const std::vector<std::string>
build;
289 static Option<Error> validateIdentifier(
const std::string& identifier)
291 if (identifier.empty()) {
292 return Error(
"Empty identifier");
295 auto alphaNumericOrHyphen = [](
unsigned char c) ->
bool {
296 return std::isalnum(c) || c ==
'-';
299 auto firstInvalid = std::find_if_not(
300 identifier.begin(), identifier.end(), alphaNumericOrHyphen);
302 if (firstInvalid != identifier.end()) {
303 return Error(
"Identifier contains illegal character: " 316 return Error(
"Empty label");
319 std::vector<std::string> identifiers =
strings::split(label,
".");
321 foreach (
const std::string& identifier, identifiers) {
337 static Try<uint32_t> parseNumericIdentifier(
const std::string& identifier) {
339 return Error(
"Contains leading hyphen");
342 return numify<uint32_t>(identifier);
348 std::ostream& stream,
359 if (!version.
build.empty()) {
366 #endif // __STOUT_VERSION_HPP__ const std::vector< std::string > prerelease
Definition: version.hpp:281
Definition: errorbase.hpp:36
T & get()&
Definition: try.hpp:80
bool operator>(const Version &other) const
Definition: version.hpp:259
const uint32_t majorVersion
Definition: version.hpp:278
std::stringstream & join(std::stringstream &stream, const std::string &separator, T &&...args)
Definition: strings.hpp:307
const uint32_t patchVersion
Definition: version.hpp:280
Version(uint32_t _majorVersion, uint32_t _minorVersion, uint32_t _patchVersion, const std::vector< std::string > &_prerelease={}, const std::vector< std::string > &_build={})
Definition: version.hpp:135
#define CHECK_NONE(expression)
Definition: check.hpp:54
JSON::Object version()
Definition: version.hpp:32
bool operator>=(const Version &other) const
Definition: version.hpp:269
static Try< Version > parse(const std::string &input)
Definition: version.hpp:58
bool isSome() const
Definition: option.hpp:116
bool operator<(const Version &other) const
Definition: version.hpp:198
Option< T > min(const Option< T > &left, const Option< T > &right)
Definition: option.hpp:185
bool isSome() const
Definition: try.hpp:77
const T & get() const &
Definition: option.hpp:119
bool operator<=(const Version &other) const
Definition: version.hpp:264
static Try error(const E &e)
Definition: try.hpp:43
friend std::ostream & operator<<(std::ostream &stream, const Version &version)
Definition: version.hpp:347
bool isError() const
Definition: try.hpp:78
const uint32_t minorVersion
Definition: version.hpp:279
std::string error(const std::string &msg, uint32_t code)
bool operator==(const Version &other) const
Definition: version.hpp:158
Definition: version.hpp:41
std::vector< std::string > split(const std::string &s, const std::string &delims, const Option< size_t > &maxTokens=None())
Definition: strings.hpp:184
bool operator!=(const Version &other) const
Definition: version.hpp:168
std::string stringify(int flags)
bool startsWith(const std::string &s, const std::string &prefix)
Definition: strings.hpp:381
const std::vector< std::string > build
Definition: version.hpp:282