A basic semantic versioning library

Dependents:   BLE_Display

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?

UserRevisionLine numberNew 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 };