Skip to content
LeviMC
English
AutoLightDark
LeviLamina
Loading...
Searching...
No Matches
SemVersionBase.h
1#pragma once
2
3#include "mc/_HeaderOutputPredefine.h"
4#include "mc/deps/core/sem_ver/SemVersionAnyVersionType.h"
5
6// auto generated inclusion list
7#include "mc/deps/core/string/StaticOptimizedString.h"
8
9// Some codes are from
10// https://github.com/EndstoneMC/endstone/blob/main/src/bedrock/core/sem_ver/sem_version.h
11
12template <typename T>
13class SemVersionBase {
14public:
15 uint16 mMajor;
16 uint16 mMinor;
17 uint16 mPatch;
18 bool mValidVersion;
19 bool mAnyVersion;
20 T mPreRelease;
21 T mBuildMeta;
22
23 SemVersionBase() : mMajor(0), mMinor(0), mPatch(0), mValidVersion(false), mAnyVersion(false) {}
24
25 explicit SemVersionBase(SemVersionAnyVersionType)
26 : mMajor(0),
27 mMinor(0),
28 mPatch(0),
29 mValidVersion(true),
30 mAnyVersion(true) {}
31
32 explicit SemVersionBase(uint16 major, uint16 minor, uint16 patch, T preRelease, T buildMeta)
33 : mMajor(major),
34 mMinor(minor),
35 mPatch(patch),
36 mValidVersion(true),
37 mAnyVersion(false),
38 mPreRelease(preRelease),
39 mBuildMeta(buildMeta) {}
40
41 MCAPI std::string asString() const;
42};
43
44template <typename StringTypeLhs, typename StringTypeRhs>
45bool operator==(SemVersionBase<StringTypeLhs> const& lhs, SemVersionBase<StringTypeRhs> const& rhs) {
46 if (lhs.mAnyVersion && rhs.mAnyVersion) {
47 return true;
48 }
49
50 if (lhs.mAnyVersion || rhs.mAnyVersion) {
51 return false;
52 }
53
54 if (lhs.mMajor != rhs.mMajor || lhs.mMinor != rhs.mMinor || lhs.mPatch != rhs.mPatch) {
55 return false;
56 }
57
58 if (lhs.mPreRelease.length() != rhs.mPreRelease.length()) {
59 return false;
60 }
61
62 if (std::memcmp(&lhs.mPreRelease, &rhs.mPreRelease, rhs.mPreRelease.length()) != 0) {
63 return false;
64 }
65 return true;
66}
67
68template <typename StringTypeLhs, typename StringTypeRhs>
69bool operator!=(SemVersionBase<StringTypeLhs> const& lhs, SemVersionBase<StringTypeRhs> const& rhs) {
70 return !(lhs == rhs);
71}
72
73template <typename StringTypeLhs, typename StringTypeRhs>
74bool operator<(SemVersionBase<StringTypeLhs> const& lhs, SemVersionBase<StringTypeRhs> const& rhs) {
75 if (lhs.mAnyVersion) {
76 return false;
77 }
78
79 if (rhs.mAnyVersion) {
80 return true;
81 }
82
83 if (lhs.mMajor != rhs.mMajor) {
84 return lhs.mMajor < rhs.mMajor;
85 }
86
87 if (lhs.mMinor != rhs.mMinor) {
88 return lhs.mMinor < rhs.mMinor;
89 }
90
91 if (lhs.mPatch != rhs.mPatch) {
92 return lhs.mPatch < rhs.mPatch;
93 }
94
95 if (lhs.mPreRelease.length() == 0 && rhs.mPreRelease.length() != 0) {
96 return false;
97 }
98
99 if (lhs.mPreRelease.length() != 0 && rhs.mPreRelease.length() == 0) {
100 return true;
101 }
102
103 auto versionSplit = [](std::string_view str, char const delim = '.') -> std::vector<std::string> {
104 std::vector<std::string> result;
105 size_t start = 0;
106 size_t end;
107 while ((end = str.find(delim, start)) != std::string_view::npos) {
108 if (end > start) {
109 result.emplace_back(str.substr(start, end - start));
110 }
111 start = end + 1;
112 }
113 if (start < str.size()) {
114 result.emplace_back(str.substr(start));
115 }
116 return result;
117 };
118
119 std::vector<std::string> lhsParts = versionSplit(lhs.mPreRelease);
120 std::vector<std::string> rhsParts = versionSplit(rhs.mPreRelease);
121
122 for (size_t i = 0; i < std::min(lhsParts.size(), rhsParts.size()); ++i) {
123 bool lhsNumeric = std::ranges::all_of(lhsParts[i], ::isdigit);
124 bool rhsNumeric = std::ranges::all_of(rhsParts[i], ::isdigit);
125
126 if (lhsNumeric && rhsNumeric) {
127 if (std::stoi(lhsParts[i]) != std::stoi(rhsParts[i])) {
128 return std::stoi(lhsParts[i]) < std::stoi(rhsParts[i]);
129 }
130 } else if (lhsNumeric) {
131 return true;
132 } else if (rhsNumeric) {
133 return false;
134 } else {
135 if (lhsParts[i] != rhsParts[i]) {
136 return lhsParts[i] < rhsParts[i];
137 }
138 }
139 }
140 return lhsParts.size() < rhsParts.size();
141}
142
143template <typename StringTypeLhs, typename StringTypeRhs>
144bool operator<=(SemVersionBase<StringTypeLhs> const& lhs, SemVersionBase<StringTypeRhs> const& rhs) {
145 return lhs == rhs || lhs < rhs;
146}
Definition SemVersionBase.h:13
Definition SemVersionAnyVersionType.h:5