Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Semver.hpp « Utils « slic3r « src « xs - github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 736f9b891aedf1dc46af914bff630fa6b801d491 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef slic3r_Semver_hpp_
#define slic3r_Semver_hpp_

#include <string>
#include <cstring>
#include <ostream>
#include <stdexcept>
#include <boost/optional.hpp>
#include <boost/format.hpp>

#include "semver/semver.h"

namespace Slic3r {


class Semver
{
public:
	struct Major { const int i;  Major(int i) : i(i) {} };
	struct Minor { const int i;  Minor(int i) : i(i) {} };
	struct Patch { const int i;  Patch(int i) : i(i) {} };

	Semver() : ver(semver_zero()) {}

	Semver(int major, int minor, int patch,
		boost::optional<const std::string&> metadata = boost::none,
		boost::optional<const std::string&> prerelease = boost::none)
		: ver(semver_zero())
	{
		ver.major = major;
		ver.minor = minor;
		ver.patch = patch;
		set_metadata(metadata);
		set_prerelease(prerelease);
	}

	Semver(const std::string &str) : ver(semver_zero())
	{
		auto parsed = parse(str);
		if (! parsed) {
			throw std::runtime_error(std::string("Could not parse version string: ") + str);
		}
		ver = parsed->ver;
		parsed->ver = semver_zero();
	}

	static boost::optional<Semver> parse(const std::string &str)
	{
		semver_t ver = semver_zero();
		if (::semver_parse(str.c_str(), &ver) == 0) {
			return Semver(ver);
		} else {
			return boost::none;
		}
	}

	static const Semver zero() { return Semver(semver_zero()); }

	static const Semver inf()
	{
		static semver_t ver = { std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), nullptr, nullptr };
		return Semver(ver);
	}

	static const Semver invalid()
	{
		static semver_t ver = { -1, 0, 0, nullptr, nullptr };
		return Semver(ver);
	}

	Semver(Semver &&other) : ver(other.ver) { other.ver = semver_zero(); }
	Semver(const Semver &other) : ver(::semver_copy(&other.ver)) {}

	Semver &operator=(Semver &&other)
	{
		::semver_free(&ver);
		ver = other.ver;
		other.ver = semver_zero();
		return *this;
	}

	Semver &operator=(const Semver &other)
	{
		::semver_free(&ver);
		ver = ::semver_copy(&other.ver);
		return *this;
	}

	~Semver() { ::semver_free(&ver); }

	// const accessors
	int 		maj()        const { return ver.major; }
	int 		min()        const { return ver.minor; }
	int 		patch() 	 const { return ver.patch; }
	const char*	prerelease() const { return ver.prerelease; }
	const char*	metadata() 	 const { return ver.metadata; }
	
	// Setters
	void set_maj(int maj) { ver.major = maj; }
	void set_min(int min) { ver.minor = min; }
	void set_patch(int patch) { ver.patch = patch; }
	void set_metadata(boost::optional<const std::string&> meta) { ver.metadata = meta ? strdup(*meta) : nullptr; }
	void set_prerelease(boost::optional<const std::string&> pre) { ver.prerelease = pre ? strdup(*pre) : nullptr; }

	// Comparison
	bool operator<(const Semver &b)  const { return ::semver_compare(ver, b.ver) == -1; }
	bool operator<=(const Semver &b) const { return ::semver_compare(ver, b.ver) <= 0; }
	bool operator==(const Semver &b) const { return ::semver_compare(ver, b.ver) == 0; }
	bool operator!=(const Semver &b) const { return ::semver_compare(ver, b.ver) != 0; }
	bool operator>=(const Semver &b) const { return ::semver_compare(ver, b.ver) >= 0; }
	bool operator>(const Semver &b)  const { return ::semver_compare(ver, b.ver) == 1; }
	// We're using '&' instead of the '~' operator here as '~' is unary-only:
	// Satisfies patch if Major and minor are equal.
	bool operator&(const Semver &b) const { return ::semver_satisfies_patch(ver, b.ver); }
	bool operator^(const Semver &b) const { return ::semver_satisfies_caret(ver, b.ver); }
	bool in_range(const Semver &low, const Semver &high) const { return low <= *this && *this <= high; }

	// Conversion
	std::string to_string() const {
		auto res = (boost::format("%1%.%2%.%3%") % ver.major % ver.minor % ver.patch).str();
		if (ver.prerelease != nullptr) { res += '-'; res += ver.prerelease; }
		if (ver.metadata != nullptr)   { res += '+'; res += ver.metadata; }
		return res;
	}

	// Arithmetics
	Semver& operator+=(const Major &b) { ver.major += b.i; return *this; }
	Semver& operator+=(const Minor &b) { ver.minor += b.i; return *this; }
	Semver& operator+=(const Patch &b) { ver.patch += b.i; return *this; }
	Semver& operator-=(const Major &b) { ver.major -= b.i; return *this; }
	Semver& operator-=(const Minor &b) { ver.minor -= b.i; return *this; }
	Semver& operator-=(const Patch &b) { ver.patch -= b.i; return *this; }
	Semver operator+(const Major &b) const { Semver res(*this); return res += b; }
	Semver operator+(const Minor &b) const { Semver res(*this); return res += b; }
	Semver operator+(const Patch &b) const { Semver res(*this); return res += b; }
	Semver operator-(const Major &b) const { Semver res(*this); return res -= b; }
	Semver operator-(const Minor &b) const { Semver res(*this); return res -= b; }
	Semver operator-(const Patch &b) const { Semver res(*this); return res -= b; }

private:
	semver_t ver;

	Semver(semver_t ver) : ver(ver) {}

	static semver_t semver_zero() { return { 0, 0, 0, nullptr, nullptr }; }
	static char * strdup(const std::string &str) { return ::semver_strdup(const_cast<char*>(str.c_str())); }
};


}
#endif