@@ -27,13 +27,11 @@ SOFTWARE.
27
27
28
28
#include < string>
29
29
#include < regex>
30
+ #include < utility>
30
31
#include < vector>
31
32
32
33
namespace semver
33
34
{
34
-
35
- using numeric_part = uint64_t ;
36
-
37
35
const std::string default_prerelease_part = " 0" ;
38
36
const char prerelease_delimiter = ' .' ;
39
37
const std::string numbers = " 0123456789" ;
@@ -46,12 +44,12 @@ namespace semver
46
44
" ?(?:\\ +([0-9a-zA-Z-]+(?:\\ .[0-9a-zA-Z-]+)*))?$" ;
47
45
48
46
struct semver_exception : public std ::runtime_error {
49
- semver_exception (const std::string& message) : std::runtime_error(message) { }
47
+ explicit semver_exception (const std::string& message) : std::runtime_error(message) { }
50
48
};
51
49
52
- inline numeric_part parse_numeric_part (const std::string& version_part)
50
+ inline uint64_t parse_numeric_part (const std::string& version_part)
53
51
{
54
- return static_cast <numeric_part >(std::stoull (version_part));
52
+ return static_cast <uint64_t >(std::stoull (version_part));
55
53
}
56
54
57
55
inline std::vector<std::string> split (const std::string& text, const char & delimiter) {
@@ -81,9 +79,9 @@ namespace semver
81
79
private:
82
80
bool m_numeric = false ;
83
81
std::string m_value;
84
- numeric_part m_numeric_value;
82
+ uint64_t m_numeric_value;
85
83
public:
86
- prerelease_part (const std::string& part) {
84
+ explicit prerelease_part (const std::string& part) {
87
85
if (part.empty ()) {
88
86
throw semver_exception (" Pre-release identity contains an empty part." );
89
87
}
@@ -103,11 +101,11 @@ namespace semver
103
101
m_value = part;
104
102
}
105
103
106
- bool numeric () const { return m_numeric; }
107
- std::string value () const { return m_value; }
108
- numeric_part numeric_value () const { return m_numeric_value; }
104
+ [[nodiscard]] bool numeric () const { return m_numeric; }
105
+ [[nodiscard]] std::string value () const { return m_value; }
106
+ [[nodiscard]] uint64_t numeric_value () const { return m_numeric_value; }
109
107
110
- int compare (const prerelease_part& other) const {
108
+ [[nodiscard]] int compare (const prerelease_part& other) const {
111
109
if (m_numeric && !other.m_numeric ) return -1 ;
112
110
if (!m_numeric && other.m_numeric ) return 1 ;
113
111
if (m_numeric && other.m_numeric ) {
@@ -122,7 +120,7 @@ namespace semver
122
120
std::vector<prerelease_part> m_parts;
123
121
std::string prerelease_str;
124
122
125
- prerelease_descriptor (const std::vector<prerelease_part>& parts)
123
+ explicit prerelease_descriptor (const std::vector<prerelease_part>& parts)
126
124
: m_parts(parts) {
127
125
if (parts.empty ()) prerelease_str = " " ;
128
126
for (const auto &part : parts) {
@@ -131,15 +129,15 @@ namespace semver
131
129
}
132
130
}
133
131
public:
134
- std::string str () const { return prerelease_str; }
135
- bool is_empty () const { return m_parts.empty (); }
132
+ [[nodiscard]] std::string str () const { return prerelease_str; }
133
+ [[nodiscard]] bool is_empty () const { return m_parts.empty (); }
136
134
137
- std::string identity () const {
135
+ [[nodiscard]] std::string identity () const {
138
136
if (is_empty ()) return " " ;
139
137
return m_parts.front ().value ();
140
138
}
141
139
142
- prerelease_descriptor increment () const {
140
+ [[nodiscard]] prerelease_descriptor increment () const {
143
141
std::vector<prerelease_part> new_parts = (m_parts);
144
142
size_t last_numeric_index = 0 ;
145
143
bool last_numeric_index_found = false ;
@@ -153,12 +151,12 @@ namespace semver
153
151
prerelease_part last = new_parts[last_numeric_index];
154
152
new_parts[last_numeric_index] = prerelease_part (std::to_string (last.numeric_value () + 1 ));
155
153
} else {
156
- new_parts.push_back ( prerelease_part ( default_prerelease_part) );
154
+ new_parts.emplace_back ( default_prerelease_part);
157
155
}
158
156
return prerelease_descriptor (new_parts);
159
157
}
160
158
161
- int compare (const prerelease_descriptor& other) const {
159
+ [[nodiscard]] int compare (const prerelease_descriptor& other) const {
162
160
auto this_size = m_parts.size ();
163
161
auto other_size = other.m_parts .size ();
164
162
@@ -191,7 +189,7 @@ namespace semver
191
189
std::vector<prerelease_part> prerelease_parts;
192
190
std::vector<std::string> parts = split (prerelease_part_str, prerelease_delimiter);
193
191
for (auto & part : parts) {
194
- prerelease_parts.push_back ( prerelease_part ( part) );
192
+ prerelease_parts.emplace_back ( part);
195
193
}
196
194
return prerelease_descriptor (prerelease_parts);
197
195
}
@@ -209,13 +207,13 @@ namespace semver
209
207
210
208
class version {
211
209
private:
212
- numeric_part m_major;
213
- numeric_part m_minor;
214
- numeric_part m_patch;
210
+ uint64_t m_major;
211
+ uint64_t m_minor;
212
+ uint64_t m_patch;
215
213
prerelease_descriptor m_prerelease;
216
214
std::string m_build_meta;
217
215
218
- int compare (const version& other) const {
216
+ [[nodiscard]] int compare (const version& other) const {
219
217
if (m_major > other.m_major ) return 1 ;
220
218
if (m_major < other.m_major ) return -1 ;
221
219
if (m_minor > other.m_minor ) return 1 ;
@@ -228,50 +226,50 @@ namespace semver
228
226
return 0 ;
229
227
}
230
228
public:
231
- version (numeric_part major = 0 ,
232
- numeric_part minor = 0 ,
233
- numeric_part patch = 0 ,
234
- std::string prerelease = " " ,
229
+ explicit version (uint64_t major = 0 ,
230
+ uint64_t minor = 0 ,
231
+ uint64_t patch = 0 ,
232
+ const std::string& prerelease = " " ,
235
233
std::string build_meta = " " )
236
234
: m_major{major},
237
235
m_minor{minor},
238
236
m_patch{patch},
239
237
m_prerelease{prerelease_descriptor::parse (prerelease)},
240
- m_build_meta{build_meta} { }
238
+ m_build_meta{std::move ( build_meta) } { }
241
239
242
- numeric_part major () const { return m_major; }
243
- numeric_part minor () const { return m_minor; }
244
- numeric_part patch () const { return m_patch; }
245
- std::string prerelease () const { return m_prerelease.str (); }
246
- std::string build_meta () const { return m_build_meta; }
240
+ [[nodiscard]] uint64_t major () const { return m_major; }
241
+ [[nodiscard]] uint64_t minor () const { return m_minor; }
242
+ [[nodiscard]] uint64_t patch () const { return m_patch; }
243
+ [[nodiscard]] std::string prerelease () const { return m_prerelease.str (); }
244
+ [[nodiscard]] std::string build_meta () const { return m_build_meta; }
247
245
248
- bool is_prerelease () const { return !m_prerelease.is_empty (); }
249
- bool is_stable () const { return m_major > 0 && m_prerelease.is_empty (); }
246
+ [[nodiscard]] bool is_prerelease () const { return !m_prerelease.is_empty (); }
247
+ [[nodiscard]] bool is_stable () const { return m_major > 0 && m_prerelease.is_empty (); }
250
248
251
- std::string str () const {
249
+ [[nodiscard]] std::string str () const {
252
250
std::string result = std::to_string (m_major) + " ." + std::to_string (m_minor) + " ." + std::to_string (m_patch);
253
251
if (!m_prerelease.is_empty ()) result += " -" + m_prerelease.str ();
254
252
if (!m_build_meta.empty ()) result += " +" + m_build_meta;
255
253
return result;
256
254
}
257
255
258
- version without_suffixes () const {
256
+ [[nodiscard]] version without_suffixes () const {
259
257
return version (m_major, m_minor, m_patch);
260
258
}
261
259
262
- version next_major (const std::string& prerelease = " " ) const {
260
+ [[nodiscard]] version next_major (const std::string& prerelease = " " ) const {
263
261
return version (m_major + 1 , 0 , 0 , prerelease);
264
262
}
265
263
266
- version next_minor (const std::string& prerelease = " " ) const {
264
+ [[nodiscard]] version next_minor (const std::string& prerelease = " " ) const {
267
265
return version (m_major, m_minor + 1 , 0 , prerelease);
268
266
}
269
267
270
- version next_patch (const std::string& prerelease = " " ) const {
268
+ [[nodiscard]] version next_patch (const std::string& prerelease = " " ) const {
271
269
return version (m_major, m_minor, (!is_prerelease () || !prerelease.empty () ? m_patch + 1 : m_patch), prerelease);
272
270
}
273
271
274
- version next_prerelease (const std::string& prerelease = " " ) const {
272
+ [[nodiscard]] version next_prerelease (const std::string& prerelease = " " ) const {
275
273
std::string pre = default_prerelease_part;
276
274
if (!prerelease.empty ()) {
277
275
pre = is_prerelease () && m_prerelease.identity () == prerelease ? m_prerelease.increment ().str () : prerelease;
@@ -281,7 +279,7 @@ namespace semver
281
279
return version (m_major, m_minor, is_prerelease () ? m_patch : m_patch + 1 , pre);
282
280
}
283
281
284
- version increment (inc by, const std::string& prerelease = " " ) const {
282
+ [[nodiscard]] version increment (inc by, const std::string& prerelease = " " ) const {
285
283
switch (by) {
286
284
case semver::major: return next_major (prerelease);
287
285
case semver::minor: return next_minor (prerelease);
@@ -318,11 +316,11 @@ namespace semver
318
316
static version parse (const std::string& version_str, bool strict = true ) {
319
317
std::regex regex (strict ? version_pattern : loose_version_pattern);
320
318
std::cmatch match;
321
- numeric_part major;
322
- numeric_part minor;
323
- numeric_part patch;
324
- std::string prerelease = " " ;
325
- std::string build_meta = " " ;
319
+ uint64_t major;
320
+ uint64_t minor;
321
+ uint64_t patch;
322
+ std::string prerelease;
323
+ std::string build_meta;
326
324
327
325
if (!std::regex_match (version_str.c_str (), match, regex)) {
328
326
throw semver_exception (" Invalid version: " + version_str);
0 commit comments