mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-09 16:14:12 +00:00
Add base::Version class.
This commit is contained in:
parent
7e6d25db88
commit
68fde07334
@ -12,4 +12,5 @@ add_library(base-lib
|
||||
serialization.cpp
|
||||
split_string.cpp
|
||||
string.cpp
|
||||
thread.cpp)
|
||||
thread.cpp
|
||||
version.cpp)
|
||||
|
@ -6,19 +6,52 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#include "base/convert_to.h"
|
||||
#include "base/version.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
template<> int base::convert_to(const base::string& from)
|
||||
namespace base {
|
||||
|
||||
template<> int convert_to(const string& from)
|
||||
{
|
||||
return std::strtol(from.c_str(), NULL, 10);
|
||||
}
|
||||
|
||||
template<> base::string base::convert_to(const int& from)
|
||||
template<> string convert_to(const int& from)
|
||||
{
|
||||
char buf[32];
|
||||
std::sprintf(buf, "%d", from);
|
||||
return buf;
|
||||
}
|
||||
|
||||
template<> Version convert_to(const string& from)
|
||||
{
|
||||
Version result;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (j != string::npos) {
|
||||
j = from.find('.', i);
|
||||
string digitString = from.substr(i, j - i);
|
||||
int digit = convert_to<int>(digitString);
|
||||
result.addDigit(digit);
|
||||
i = j+1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<> string convert_to(const Version& from)
|
||||
{
|
||||
string result;
|
||||
result.reserve(3*from.size());
|
||||
|
||||
for (size_t i=0; i<from.size(); ++i) {
|
||||
result += convert_to<string>(from[i]);
|
||||
if (i < from.size()-1)
|
||||
result += ".";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace base {
|
||||
|
||||
class Version;
|
||||
|
||||
// Undefined convertion
|
||||
template<typename To, typename From>
|
||||
To convert_to(const From& from) {
|
||||
@ -20,6 +22,9 @@ namespace base {
|
||||
template<> int convert_to(const base::string& from);
|
||||
template<> base::string convert_to(const int& from);
|
||||
|
||||
template<> Version convert_to(const base::string& from);
|
||||
template<> base::string convert_to(const Version& from);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
67
src/base/version.cpp
Normal file
67
src/base/version.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
// ASE base library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "base/version.h"
|
||||
|
||||
using namespace base;
|
||||
|
||||
Version::Version()
|
||||
{
|
||||
}
|
||||
|
||||
Version::Version(int major, int minor, int rev, int compilation)
|
||||
{
|
||||
if (major >= 0 || minor >= 0 || rev >= 0 || compilation >= 0)
|
||||
addDigit(major);
|
||||
|
||||
if (minor >= 0 || rev >= 0 || compilation >= 0)
|
||||
addDigit(minor);
|
||||
|
||||
if (rev >= 0 || compilation >= 0)
|
||||
addDigit(rev);
|
||||
|
||||
if (compilation >= 0)
|
||||
addDigit(compilation);
|
||||
}
|
||||
|
||||
bool Version::operator==(const Version& other) const
|
||||
{
|
||||
Digits::const_iterator
|
||||
it1 = m_digits.begin(), end1 = m_digits.end(),
|
||||
it2 = other.m_digits.begin(), end2 = other.m_digits.end();
|
||||
|
||||
while (it1 != end1 || it2 != end2) {
|
||||
int digit1 = (it1 != end1 ? *it1++: 0);
|
||||
int digit2 = (it2 != end2 ? *it2++: 0);
|
||||
|
||||
if (digit1 != digit2)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Version::operator<(const Version& other) const
|
||||
{
|
||||
Digits::const_iterator
|
||||
it1 = m_digits.begin(), end1 = m_digits.end(),
|
||||
it2 = other.m_digits.begin(), end2 = other.m_digits.end();
|
||||
|
||||
while (it1 != end1 || it2 != end2) {
|
||||
int digit1 = (it1 != end1 ? *it1++: 0);
|
||||
int digit2 = (it2 != end2 ? *it2++: 0);
|
||||
|
||||
if (digit1 < digit2)
|
||||
return true;
|
||||
else if (digit1 > digit2)
|
||||
return false;
|
||||
// else continue...
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
82
src/base/version.h
Normal file
82
src/base/version.h
Normal file
@ -0,0 +1,82 @@
|
||||
// ASE base library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#ifndef BASE_VERSION_H_INCLUDED
|
||||
#define BASE_VERSION_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace base {
|
||||
|
||||
class Version
|
||||
{
|
||||
public:
|
||||
Version();
|
||||
explicit Version(int major, int minor = -1, int revision = -1, int build = -1);
|
||||
|
||||
int major() const { return (*this)[0]; }
|
||||
int minor() const { return (*this)[1]; }
|
||||
int revision() const { return (*this)[2]; }
|
||||
int build() const { return (*this)[3]; }
|
||||
|
||||
Version& major(int digit) { (*this)[0] = digit; return *this; }
|
||||
Version& minor(int digit) { (*this)[1] = digit; return *this; }
|
||||
Version& revision(int digit) { (*this)[2] = digit; return *this; }
|
||||
Version& build(int digit) { (*this)[3] = digit; return *this; }
|
||||
|
||||
size_t size() const {
|
||||
return m_digits.size();
|
||||
}
|
||||
|
||||
// operator[] that can be used to set version digits.
|
||||
int& operator[](size_t index) {
|
||||
if (index >= m_digits.size())
|
||||
m_digits.resize(index+1);
|
||||
return m_digits[index];
|
||||
}
|
||||
|
||||
// operator[] that can be used to get version digits.
|
||||
int operator[](size_t index) const {
|
||||
if (index < m_digits.size())
|
||||
return m_digits[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Adds a new digit.
|
||||
void addDigit(int digit) {
|
||||
m_digits.push_back(digit);
|
||||
}
|
||||
|
||||
// Comparison
|
||||
bool operator==(const Version& other) const;
|
||||
bool operator<(const Version& other) const;
|
||||
|
||||
bool operator!=(const Version& other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool operator>(const Version& other) const {
|
||||
return !operator<(other) && !operator==(other);
|
||||
}
|
||||
|
||||
bool operator>=(const Version& other) const {
|
||||
return !operator<(other);
|
||||
}
|
||||
|
||||
bool operator<=(const Version& other) const {
|
||||
return operator<(other) || operator==(other);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<int> Digits;
|
||||
Digits m_digits;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
153
src/base/version_unittest.cpp
Normal file
153
src/base/version_unittest.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
// ASE base library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "base/version.h"
|
||||
#include "base/convert_to.h"
|
||||
|
||||
using namespace base;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Version& ver)
|
||||
{
|
||||
return os << convert_to<string>(ver);
|
||||
}
|
||||
|
||||
TEST(Version, Ctor)
|
||||
{
|
||||
Version v0;
|
||||
EXPECT_EQ(0, v0[0]);
|
||||
EXPECT_EQ(0, v0[1]);
|
||||
EXPECT_EQ(0, v0[2]);
|
||||
EXPECT_EQ(0, v0[3]);
|
||||
EXPECT_EQ(0, v0[4]);
|
||||
|
||||
Version v1(1);
|
||||
EXPECT_EQ(1, v1[0]);
|
||||
EXPECT_EQ(0, v1[1]);
|
||||
|
||||
Version v2(1, 2);
|
||||
EXPECT_EQ(1, v2[0]);
|
||||
EXPECT_EQ(2, v2[1]);
|
||||
EXPECT_EQ(0, v2[2]);
|
||||
|
||||
Version v3(1, 2, 3);
|
||||
EXPECT_EQ(1, v3[0]);
|
||||
EXPECT_EQ(2, v3[1]);
|
||||
EXPECT_EQ(3, v3[2]);
|
||||
EXPECT_EQ(0, v3[3]);
|
||||
|
||||
Version v4(1, 2, 3, 4);
|
||||
EXPECT_EQ(1, v4[0]);
|
||||
EXPECT_EQ(2, v4[1]);
|
||||
EXPECT_EQ(3, v4[2]);
|
||||
EXPECT_EQ(4, v4[3]);
|
||||
EXPECT_EQ(0, v4[4]);
|
||||
}
|
||||
|
||||
TEST(Version, StringToVersion)
|
||||
{
|
||||
EXPECT_EQ(Version(), convert_to<Version>(string("")));
|
||||
EXPECT_EQ(Version(1), convert_to<Version>(string("1")));
|
||||
EXPECT_EQ(Version(1, 2), convert_to<Version>(string("1.2")));
|
||||
EXPECT_EQ(Version(1, 2, 3), convert_to<Version>(string("1.2.3")));
|
||||
EXPECT_EQ(Version(1, 2, 3, 4), convert_to<Version>(string("1.2.3.4")));
|
||||
}
|
||||
|
||||
TEST(Version, VersionToString)
|
||||
{
|
||||
EXPECT_EQ("", convert_to<string>(Version()));
|
||||
EXPECT_EQ("0", convert_to<string>(Version(0)));
|
||||
EXPECT_EQ("1", convert_to<string>(Version(1)));
|
||||
EXPECT_EQ("1.0", convert_to<string>(Version(1, 0)));
|
||||
EXPECT_EQ("0.0", convert_to<string>(Version(0, 0)));
|
||||
EXPECT_EQ("1.0.2", convert_to<string>(Version(1, 0, 2)));
|
||||
}
|
||||
|
||||
TEST(Version, Equal)
|
||||
{
|
||||
EXPECT_EQ(Version(), Version());
|
||||
EXPECT_EQ(Version(0), Version());
|
||||
EXPECT_EQ(Version(1), Version(1));
|
||||
EXPECT_EQ(Version(1), Version(1, 0));
|
||||
EXPECT_EQ(Version(1, 0), Version(1));
|
||||
EXPECT_EQ(Version(1, 2), Version(1, 2));
|
||||
EXPECT_EQ(Version(1, 2, 3), Version(1, 2, 3));
|
||||
EXPECT_EQ(Version(1, 0, 0), Version(1));
|
||||
}
|
||||
|
||||
TEST(Version, NotEqual)
|
||||
{
|
||||
EXPECT_FALSE(Version() != Version());
|
||||
EXPECT_TRUE(Version(1) != Version(1, 2));
|
||||
EXPECT_TRUE(Version() != Version(0, 1));
|
||||
EXPECT_TRUE(Version(1, 0) != Version(1, 0, 1));
|
||||
EXPECT_TRUE(Version(1, 2) != Version(1, 3));
|
||||
EXPECT_TRUE(Version(1, 2, 3) != Version(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
TEST(Version, LessThan)
|
||||
{
|
||||
EXPECT_FALSE(Version() < Version(0));
|
||||
EXPECT_TRUE(Version(0) < Version(1));
|
||||
EXPECT_TRUE(Version(1, 2) < Version(1, 3));
|
||||
EXPECT_TRUE(Version(1, 2, 3) < Version(1, 2, 4));
|
||||
EXPECT_TRUE(Version(1, 2, 0, 4) < Version(1, 2, 3));
|
||||
EXPECT_FALSE(Version(1, 3) < Version(1, 2));
|
||||
}
|
||||
|
||||
TEST(Version, AllComparisons)
|
||||
{
|
||||
EXPECT_TRUE(Version(1, 2, 3) == Version(1, 2, 3));
|
||||
EXPECT_FALSE(Version(1, 2, 3) < Version(1, 2, 3));
|
||||
EXPECT_FALSE(Version(1, 2, 3) > Version(1, 2, 3));
|
||||
EXPECT_FALSE(Version(1, 2, 3) != Version(1, 2, 3));
|
||||
EXPECT_TRUE(Version(1, 2, 3) <= Version(1, 2, 3));
|
||||
EXPECT_TRUE(Version(1, 2, 3) >= Version(1, 2, 3));
|
||||
|
||||
EXPECT_FALSE(Version(1, 2, 3) == Version(2));
|
||||
EXPECT_TRUE(Version(1, 2, 3) < Version(2));
|
||||
EXPECT_FALSE(Version(1, 2, 3) > Version(2));
|
||||
EXPECT_TRUE(Version(1, 2, 3) != Version(2));
|
||||
EXPECT_TRUE(Version(1, 2, 3) <= Version(2));
|
||||
EXPECT_FALSE(Version(1, 2, 3) >= Version(2));
|
||||
}
|
||||
|
||||
TEST(Version, SimpleGetters)
|
||||
{
|
||||
Version v0;
|
||||
EXPECT_EQ(0, v0.major());
|
||||
EXPECT_EQ(0, v0.minor());
|
||||
EXPECT_EQ(0, v0.revision());
|
||||
EXPECT_EQ(0, v0.build());
|
||||
|
||||
Version v2(1, 2);
|
||||
EXPECT_EQ(1, v2.major());
|
||||
EXPECT_EQ(2, v2.minor());
|
||||
EXPECT_EQ(0, v2.revision());
|
||||
|
||||
Version v4(1, 2, 3, 4);
|
||||
EXPECT_EQ(1, v4.major());
|
||||
EXPECT_EQ(2, v4.minor());
|
||||
EXPECT_EQ(3, v4.revision());
|
||||
EXPECT_EQ(4, v4.build());
|
||||
}
|
||||
|
||||
TEST(Version, SimpleSetters)
|
||||
{
|
||||
EXPECT_EQ(Version(1), Version().major(1));
|
||||
EXPECT_EQ(Version(1, 2), Version().major(1).minor(2));
|
||||
EXPECT_EQ(Version(1, 2), Version().minor(2).major(1));
|
||||
EXPECT_EQ(Version(1, 2, 3, 4), Version().major(1).minor(2).revision(3).build(4));
|
||||
EXPECT_EQ(Version(1, 2, 3, 4), Version().build(4).revision(3).minor(2).major(1));
|
||||
EXPECT_EQ(Version(0, 0, 0, 4), Version().build(4));
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user