A basic semantic versioning library
SemVer.h@0:91466b3b925e, 2015-03-30 (annotated)
- Committer:
- rosterloh84
- Date:
- Mon Mar 30 13:22:22 2015 +0000
- Revision:
- 0:91466b3b925e
Major, Minor and Patch implemented
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rosterloh84 | 0:91466b3b925e | 1 | /** |
rosterloh84 | 0:91466b3b925e | 2 | * @file |
rosterloh84 | 0:91466b3b925e | 3 | * @date 30 March 2015 |
rosterloh84 | 0:91466b3b925e | 4 | * @author Richard Osterloh <richardo@buddi.co.uk> |
rosterloh84 | 0:91466b3b925e | 5 | */ |
rosterloh84 | 0:91466b3b925e | 6 | #pragma once |
rosterloh84 | 0:91466b3b925e | 7 | |
rosterloh84 | 0:91466b3b925e | 8 | #include <sstream> |
rosterloh84 | 0:91466b3b925e | 9 | #include <string> |
rosterloh84 | 0:91466b3b925e | 10 | |
rosterloh84 | 0:91466b3b925e | 11 | /** |
rosterloh84 | 0:91466b3b925e | 12 | * @class SemVer |
rosterloh84 | 0:91466b3b925e | 13 | * @brief A basic implementation of semantic versioning |
rosterloh84 | 0:91466b3b925e | 14 | */ |
rosterloh84 | 0:91466b3b925e | 15 | class SemVer { |
rosterloh84 | 0:91466b3b925e | 16 | public: |
rosterloh84 | 0:91466b3b925e | 17 | |
rosterloh84 | 0:91466b3b925e | 18 | /** |
rosterloh84 | 0:91466b3b925e | 19 | * SemVer constructor |
rosterloh84 | 0:91466b3b925e | 20 | * @param version string to parse as a version |
rosterloh84 | 0:91466b3b925e | 21 | */ |
rosterloh84 | 0:91466b3b925e | 22 | SemVer(const std::string& version) |
rosterloh84 | 0:91466b3b925e | 23 | { |
rosterloh84 | 0:91466b3b925e | 24 | m_version = version; |
rosterloh84 | 0:91466b3b925e | 25 | m_major = 0; |
rosterloh84 | 0:91466b3b925e | 26 | m_minor = 0; |
rosterloh84 | 0:91466b3b925e | 27 | m_patch = 0; |
rosterloh84 | 0:91466b3b925e | 28 | |
rosterloh84 | 0:91466b3b925e | 29 | if (version.empty()) |
rosterloh84 | 0:91466b3b925e | 30 | { |
rosterloh84 | 0:91466b3b925e | 31 | m_is_valid = false; |
rosterloh84 | 0:91466b3b925e | 32 | } |
rosterloh84 | 0:91466b3b925e | 33 | else |
rosterloh84 | 0:91466b3b925e | 34 | { |
rosterloh84 | 0:91466b3b925e | 35 | m_is_valid = true; |
rosterloh84 | 0:91466b3b925e | 36 | parse(); |
rosterloh84 | 0:91466b3b925e | 37 | } |
rosterloh84 | 0:91466b3b925e | 38 | } |
rosterloh84 | 0:91466b3b925e | 39 | |
rosterloh84 | 0:91466b3b925e | 40 | ~SemVer() {} |
rosterloh84 | 0:91466b3b925e | 41 | |
rosterloh84 | 0:91466b3b925e | 42 | /** |
rosterloh84 | 0:91466b3b925e | 43 | * Get full version |
rosterloh84 | 0:91466b3b925e | 44 | */ |
rosterloh84 | 0:91466b3b925e | 45 | const std::string& getVersion() const |
rosterloh84 | 0:91466b3b925e | 46 | { |
rosterloh84 | 0:91466b3b925e | 47 | return m_version; |
rosterloh84 | 0:91466b3b925e | 48 | } |
rosterloh84 | 0:91466b3b925e | 49 | |
rosterloh84 | 0:91466b3b925e | 50 | /** |
rosterloh84 | 0:91466b3b925e | 51 | * Get the major of the version |
rosterloh84 | 0:91466b3b925e | 52 | */ |
rosterloh84 | 0:91466b3b925e | 53 | const int& getMajor() const |
rosterloh84 | 0:91466b3b925e | 54 | { |
rosterloh84 | 0:91466b3b925e | 55 | return m_major; |
rosterloh84 | 0:91466b3b925e | 56 | } |
rosterloh84 | 0:91466b3b925e | 57 | |
rosterloh84 | 0:91466b3b925e | 58 | /** |
rosterloh84 | 0:91466b3b925e | 59 | * Get the minor of the version |
rosterloh84 | 0:91466b3b925e | 60 | */ |
rosterloh84 | 0:91466b3b925e | 61 | const int& getMinor() const |
rosterloh84 | 0:91466b3b925e | 62 | { |
rosterloh84 | 0:91466b3b925e | 63 | return m_minor; |
rosterloh84 | 0:91466b3b925e | 64 | } |
rosterloh84 | 0:91466b3b925e | 65 | |
rosterloh84 | 0:91466b3b925e | 66 | /** |
rosterloh84 | 0:91466b3b925e | 67 | * Get the patch of the version |
rosterloh84 | 0:91466b3b925e | 68 | */ |
rosterloh84 | 0:91466b3b925e | 69 | const int& getPatch() const |
rosterloh84 | 0:91466b3b925e | 70 | { |
rosterloh84 | 0:91466b3b925e | 71 | return m_patch; |
rosterloh84 | 0:91466b3b925e | 72 | } |
rosterloh84 | 0:91466b3b925e | 73 | |
rosterloh84 | 0:91466b3b925e | 74 | /** |
rosterloh84 | 0:91466b3b925e | 75 | * Check if the version is valid |
rosterloh84 | 0:91466b3b925e | 76 | */ |
rosterloh84 | 0:91466b3b925e | 77 | const bool& isValid() const |
rosterloh84 | 0:91466b3b925e | 78 | { |
rosterloh84 | 0:91466b3b925e | 79 | return m_is_valid; |
rosterloh84 | 0:91466b3b925e | 80 | } |
rosterloh84 | 0:91466b3b925e | 81 | |
rosterloh84 | 0:91466b3b925e | 82 | int compare(SemVer& rgt) |
rosterloh84 | 0:91466b3b925e | 83 | { |
rosterloh84 | 0:91466b3b925e | 84 | if ((*this) == rgt) |
rosterloh84 | 0:91466b3b925e | 85 | { |
rosterloh84 | 0:91466b3b925e | 86 | return 0; |
rosterloh84 | 0:91466b3b925e | 87 | } |
rosterloh84 | 0:91466b3b925e | 88 | |
rosterloh84 | 0:91466b3b925e | 89 | if ((*this) > rgt) |
rosterloh84 | 0:91466b3b925e | 90 | { |
rosterloh84 | 0:91466b3b925e | 91 | return 1; |
rosterloh84 | 0:91466b3b925e | 92 | } |
rosterloh84 | 0:91466b3b925e | 93 | |
rosterloh84 | 0:91466b3b925e | 94 | return -1; |
rosterloh84 | 0:91466b3b925e | 95 | } |
rosterloh84 | 0:91466b3b925e | 96 | |
rosterloh84 | 0:91466b3b925e | 97 | SemVer& operator= (SemVer& rgt) |
rosterloh84 | 0:91466b3b925e | 98 | { |
rosterloh84 | 0:91466b3b925e | 99 | if ((*this) != rgt) |
rosterloh84 | 0:91466b3b925e | 100 | { |
rosterloh84 | 0:91466b3b925e | 101 | this->m_version = rgt.getVersion(); |
rosterloh84 | 0:91466b3b925e | 102 | this->m_major = rgt.getMajor(); |
rosterloh84 | 0:91466b3b925e | 103 | this->m_minor = rgt.getMinor(); |
rosterloh84 | 0:91466b3b925e | 104 | this->m_patch = rgt.getPatch(); |
rosterloh84 | 0:91466b3b925e | 105 | this->m_is_valid = rgt.isValid(); |
rosterloh84 | 0:91466b3b925e | 106 | } |
rosterloh84 | 0:91466b3b925e | 107 | |
rosterloh84 | 0:91466b3b925e | 108 | return *this; |
rosterloh84 | 0:91466b3b925e | 109 | } |
rosterloh84 | 0:91466b3b925e | 110 | |
rosterloh84 | 0:91466b3b925e | 111 | friend bool operator== (SemVer &lft, SemVer &rgt) |
rosterloh84 | 0:91466b3b925e | 112 | { |
rosterloh84 | 0:91466b3b925e | 113 | return lft.getVersion().compare(rgt.getVersion()) == 0; |
rosterloh84 | 0:91466b3b925e | 114 | } |
rosterloh84 | 0:91466b3b925e | 115 | |
rosterloh84 | 0:91466b3b925e | 116 | friend bool operator!= (SemVer &lft, SemVer &rgt) |
rosterloh84 | 0:91466b3b925e | 117 | { |
rosterloh84 | 0:91466b3b925e | 118 | return !(lft == rgt); |
rosterloh84 | 0:91466b3b925e | 119 | } |
rosterloh84 | 0:91466b3b925e | 120 | |
rosterloh84 | 0:91466b3b925e | 121 | friend bool operator> (SemVer &lft, SemVer &rgt) |
rosterloh84 | 0:91466b3b925e | 122 | { |
rosterloh84 | 0:91466b3b925e | 123 | // Major |
rosterloh84 | 0:91466b3b925e | 124 | if (lft.getMajor() < 0 && rgt.getMajor() >= 0) |
rosterloh84 | 0:91466b3b925e | 125 | { |
rosterloh84 | 0:91466b3b925e | 126 | return false; |
rosterloh84 | 0:91466b3b925e | 127 | } |
rosterloh84 | 0:91466b3b925e | 128 | |
rosterloh84 | 0:91466b3b925e | 129 | if (lft.getMajor() >= 0 && rgt.getMajor() < 0) |
rosterloh84 | 0:91466b3b925e | 130 | { |
rosterloh84 | 0:91466b3b925e | 131 | return true; |
rosterloh84 | 0:91466b3b925e | 132 | } |
rosterloh84 | 0:91466b3b925e | 133 | |
rosterloh84 | 0:91466b3b925e | 134 | if (lft.getMajor() > rgt.getMajor()) |
rosterloh84 | 0:91466b3b925e | 135 | { |
rosterloh84 | 0:91466b3b925e | 136 | return true; |
rosterloh84 | 0:91466b3b925e | 137 | } |
rosterloh84 | 0:91466b3b925e | 138 | |
rosterloh84 | 0:91466b3b925e | 139 | if (lft.getMajor() < rgt.getMajor()) |
rosterloh84 | 0:91466b3b925e | 140 | { |
rosterloh84 | 0:91466b3b925e | 141 | return false; |
rosterloh84 | 0:91466b3b925e | 142 | } |
rosterloh84 | 0:91466b3b925e | 143 | |
rosterloh84 | 0:91466b3b925e | 144 | // Minor |
rosterloh84 | 0:91466b3b925e | 145 | if (lft.getMinor() < 0 && rgt.getMinor() >= 0) |
rosterloh84 | 0:91466b3b925e | 146 | { |
rosterloh84 | 0:91466b3b925e | 147 | return false; |
rosterloh84 | 0:91466b3b925e | 148 | } |
rosterloh84 | 0:91466b3b925e | 149 | |
rosterloh84 | 0:91466b3b925e | 150 | if (lft.getMinor() >= 0 && rgt.getMinor() < 0) |
rosterloh84 | 0:91466b3b925e | 151 | { |
rosterloh84 | 0:91466b3b925e | 152 | return true; |
rosterloh84 | 0:91466b3b925e | 153 | } |
rosterloh84 | 0:91466b3b925e | 154 | |
rosterloh84 | 0:91466b3b925e | 155 | if (lft.getMinor() > rgt.getMinor()) |
rosterloh84 | 0:91466b3b925e | 156 | { |
rosterloh84 | 0:91466b3b925e | 157 | return true; |
rosterloh84 | 0:91466b3b925e | 158 | } |
rosterloh84 | 0:91466b3b925e | 159 | |
rosterloh84 | 0:91466b3b925e | 160 | if (lft.getMinor() < rgt.getMinor()) |
rosterloh84 | 0:91466b3b925e | 161 | { |
rosterloh84 | 0:91466b3b925e | 162 | return false; |
rosterloh84 | 0:91466b3b925e | 163 | } |
rosterloh84 | 0:91466b3b925e | 164 | |
rosterloh84 | 0:91466b3b925e | 165 | // Patch |
rosterloh84 | 0:91466b3b925e | 166 | if (lft.getPatch() < 0 && rgt.getPatch() >= 0) |
rosterloh84 | 0:91466b3b925e | 167 | { |
rosterloh84 | 0:91466b3b925e | 168 | return false; |
rosterloh84 | 0:91466b3b925e | 169 | } |
rosterloh84 | 0:91466b3b925e | 170 | |
rosterloh84 | 0:91466b3b925e | 171 | if (lft.getPatch() >= 0 && rgt.getPatch() < 0) |
rosterloh84 | 0:91466b3b925e | 172 | { |
rosterloh84 | 0:91466b3b925e | 173 | return true; |
rosterloh84 | 0:91466b3b925e | 174 | } |
rosterloh84 | 0:91466b3b925e | 175 | |
rosterloh84 | 0:91466b3b925e | 176 | if (lft.getPatch() > rgt.getPatch()) |
rosterloh84 | 0:91466b3b925e | 177 | { |
rosterloh84 | 0:91466b3b925e | 178 | return true; |
rosterloh84 | 0:91466b3b925e | 179 | } |
rosterloh84 | 0:91466b3b925e | 180 | |
rosterloh84 | 0:91466b3b925e | 181 | if (lft.getPatch() < rgt.getPatch()) |
rosterloh84 | 0:91466b3b925e | 182 | { |
rosterloh84 | 0:91466b3b925e | 183 | return false; |
rosterloh84 | 0:91466b3b925e | 184 | } |
rosterloh84 | 0:91466b3b925e | 185 | |
rosterloh84 | 0:91466b3b925e | 186 | return false; |
rosterloh84 | 0:91466b3b925e | 187 | } |
rosterloh84 | 0:91466b3b925e | 188 | |
rosterloh84 | 0:91466b3b925e | 189 | friend bool operator>= (SemVer &lft, SemVer &rgt) |
rosterloh84 | 0:91466b3b925e | 190 | { |
rosterloh84 | 0:91466b3b925e | 191 | return (lft > rgt) || (lft == rgt); |
rosterloh84 | 0:91466b3b925e | 192 | } |
rosterloh84 | 0:91466b3b925e | 193 | |
rosterloh84 | 0:91466b3b925e | 194 | friend bool operator< (SemVer &lft, SemVer &rgt) |
rosterloh84 | 0:91466b3b925e | 195 | { |
rosterloh84 | 0:91466b3b925e | 196 | return (rgt > lft); |
rosterloh84 | 0:91466b3b925e | 197 | } |
rosterloh84 | 0:91466b3b925e | 198 | |
rosterloh84 | 0:91466b3b925e | 199 | friend bool operator<= (SemVer &lft, SemVer &rgt) |
rosterloh84 | 0:91466b3b925e | 200 | { |
rosterloh84 | 0:91466b3b925e | 201 | return (lft < rgt) || (lft == rgt); |
rosterloh84 | 0:91466b3b925e | 202 | } |
rosterloh84 | 0:91466b3b925e | 203 | |
rosterloh84 | 0:91466b3b925e | 204 | friend std::ostream& operator<< (std::ostream& out, const SemVer& value) |
rosterloh84 | 0:91466b3b925e | 205 | { |
rosterloh84 | 0:91466b3b925e | 206 | out << value.getVersion(); |
rosterloh84 | 0:91466b3b925e | 207 | |
rosterloh84 | 0:91466b3b925e | 208 | return out; |
rosterloh84 | 0:91466b3b925e | 209 | } |
rosterloh84 | 0:91466b3b925e | 210 | |
rosterloh84 | 0:91466b3b925e | 211 | private: |
rosterloh84 | 0:91466b3b925e | 212 | std::string m_version; |
rosterloh84 | 0:91466b3b925e | 213 | int m_major; |
rosterloh84 | 0:91466b3b925e | 214 | int m_minor; |
rosterloh84 | 0:91466b3b925e | 215 | int m_patch; |
rosterloh84 | 0:91466b3b925e | 216 | bool m_is_valid; |
rosterloh84 | 0:91466b3b925e | 217 | |
rosterloh84 | 0:91466b3b925e | 218 | enum m_type { |
rosterloh84 | 0:91466b3b925e | 219 | TYPE_MAJOR, |
rosterloh84 | 0:91466b3b925e | 220 | TYPE_MINOR, |
rosterloh84 | 0:91466b3b925e | 221 | TYPE_PATCH, |
rosterloh84 | 0:91466b3b925e | 222 | }; |
rosterloh84 | 0:91466b3b925e | 223 | |
rosterloh84 | 0:91466b3b925e | 224 | void parse() |
rosterloh84 | 0:91466b3b925e | 225 | { |
rosterloh84 | 0:91466b3b925e | 226 | int type = TYPE_MAJOR; |
rosterloh84 | 0:91466b3b925e | 227 | |
rosterloh84 | 0:91466b3b925e | 228 | std::string major, minor, patch; |
rosterloh84 | 0:91466b3b925e | 229 | |
rosterloh84 | 0:91466b3b925e | 230 | for (std::size_t i = 0; i < m_version.length(); i++) |
rosterloh84 | 0:91466b3b925e | 231 | { |
rosterloh84 | 0:91466b3b925e | 232 | char chr = m_version[i]; |
rosterloh84 | 0:91466b3b925e | 233 | int chr_dec = chr; |
rosterloh84 | 0:91466b3b925e | 234 | |
rosterloh84 | 0:91466b3b925e | 235 | switch (type) |
rosterloh84 | 0:91466b3b925e | 236 | { |
rosterloh84 | 0:91466b3b925e | 237 | case TYPE_MAJOR: |
rosterloh84 | 0:91466b3b925e | 238 | if (chr == '.') |
rosterloh84 | 0:91466b3b925e | 239 | { |
rosterloh84 | 0:91466b3b925e | 240 | type = TYPE_MINOR; |
rosterloh84 | 0:91466b3b925e | 241 | continue; |
rosterloh84 | 0:91466b3b925e | 242 | } |
rosterloh84 | 0:91466b3b925e | 243 | |
rosterloh84 | 0:91466b3b925e | 244 | if (chr_dec < 48 || chr_dec > 57) |
rosterloh84 | 0:91466b3b925e | 245 | { |
rosterloh84 | 0:91466b3b925e | 246 | m_is_valid = false; |
rosterloh84 | 0:91466b3b925e | 247 | } |
rosterloh84 | 0:91466b3b925e | 248 | |
rosterloh84 | 0:91466b3b925e | 249 | major += chr; |
rosterloh84 | 0:91466b3b925e | 250 | break; |
rosterloh84 | 0:91466b3b925e | 251 | |
rosterloh84 | 0:91466b3b925e | 252 | case TYPE_MINOR: |
rosterloh84 | 0:91466b3b925e | 253 | if (chr == '.') |
rosterloh84 | 0:91466b3b925e | 254 | { |
rosterloh84 | 0:91466b3b925e | 255 | type = TYPE_PATCH; |
rosterloh84 | 0:91466b3b925e | 256 | continue; |
rosterloh84 | 0:91466b3b925e | 257 | } |
rosterloh84 | 0:91466b3b925e | 258 | |
rosterloh84 | 0:91466b3b925e | 259 | if (chr_dec < 48 || chr_dec > 57) |
rosterloh84 | 0:91466b3b925e | 260 | { |
rosterloh84 | 0:91466b3b925e | 261 | m_is_valid = false; |
rosterloh84 | 0:91466b3b925e | 262 | } |
rosterloh84 | 0:91466b3b925e | 263 | |
rosterloh84 | 0:91466b3b925e | 264 | minor += chr; |
rosterloh84 | 0:91466b3b925e | 265 | break; |
rosterloh84 | 0:91466b3b925e | 266 | |
rosterloh84 | 0:91466b3b925e | 267 | case TYPE_PATCH: |
rosterloh84 | 0:91466b3b925e | 268 | if (chr_dec < 48 || chr_dec > 57) |
rosterloh84 | 0:91466b3b925e | 269 | { |
rosterloh84 | 0:91466b3b925e | 270 | m_is_valid = false; |
rosterloh84 | 0:91466b3b925e | 271 | } |
rosterloh84 | 0:91466b3b925e | 272 | |
rosterloh84 | 0:91466b3b925e | 273 | patch += chr; |
rosterloh84 | 0:91466b3b925e | 274 | break; |
rosterloh84 | 0:91466b3b925e | 275 | |
rosterloh84 | 0:91466b3b925e | 276 | } |
rosterloh84 | 0:91466b3b925e | 277 | |
rosterloh84 | 0:91466b3b925e | 278 | if (m_is_valid) |
rosterloh84 | 0:91466b3b925e | 279 | { |
rosterloh84 | 0:91466b3b925e | 280 | std::istringstream(major) >> m_major; |
rosterloh84 | 0:91466b3b925e | 281 | std::istringstream(minor) >> m_minor; |
rosterloh84 | 0:91466b3b925e | 282 | std::istringstream(patch) >> m_patch; |
rosterloh84 | 0:91466b3b925e | 283 | |
rosterloh84 | 0:91466b3b925e | 284 | if (m_major == 0 && m_minor == 0 && m_patch == 0) |
rosterloh84 | 0:91466b3b925e | 285 | { |
rosterloh84 | 0:91466b3b925e | 286 | m_is_valid = false; |
rosterloh84 | 0:91466b3b925e | 287 | } |
rosterloh84 | 0:91466b3b925e | 288 | } |
rosterloh84 | 0:91466b3b925e | 289 | } |
rosterloh84 | 0:91466b3b925e | 290 | } |
rosterloh84 | 0:91466b3b925e | 291 | |
rosterloh84 | 0:91466b3b925e | 292 | }; |