version: style, naming, accessors

This commit is contained in:
Danny Robson 2016-01-19 18:31:35 +11:00
parent 08ac4b0e9d
commit 031ef3dca7
2 changed files with 144 additions and 92 deletions

View File

@ -26,46 +26,51 @@
#include "debug.hpp" #include "debug.hpp"
using namespace util; using util::version;
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
version::version (): version::version ():
size (0) size (0),
release (PRODUCTION)
{ ; } { ; }
//-----------------------------------------------------------------------------
version::version (unsigned int _major, version::version (unsigned int _major,
unsigned int _minor): unsigned int _minor):
size (2), size (0),
release (RELEASE_PRODUCTION) components { _major, _minor },
release (PRODUCTION)
{ {
values[OFFSET_MAJOR] = _major; components[MAJOR] = _major;
values[OFFSET_MINOR] = _minor; components[MINOR] = _minor;
}
version::version (const std::string& str):
size (0)
{
*this = version::parse (str);
}
version::version (const char *str):
size (0)
{
*this = version::parse (str);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
version::version (const std::string& str):
version (str.c_str ())
{ ; }
//-----------------------------------------------------------------------------
version::version (const char *str):
version ()
{
*this = version::parse (str);
}
///////////////////////////////////////////////////////////////////////////////
static void static void
sanity (version::release_t r) { sanity (version::release_t r)
{
switch (r) { switch (r) {
case version::RELEASE_ALPHA: case version::ALPHA:
case version::RELEASE_BETA: case version::BETA:
case version::RELEASE_GAMMA: case version::GAMMA:
case version::RELEASE_PRODUCTION: case version::PRODUCTION:
return; return;
} }
@ -73,6 +78,7 @@ sanity (version::release_t r) {
} }
//-----------------------------------------------------------------------------
void void
version::sanity (void) const { version::sanity (void) const {
::sanity (release); ::sanity (release);
@ -80,7 +86,29 @@ version::sanity (void) const {
} }
//----------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////
unsigned version::major (void) const { return components[MAJOR]; }
unsigned version::minor (void) const { return components[MINOR]; }
unsigned version::point (void) const { return components[POINT]; }
unsigned version::build (void) const { return components[BUILD]; }
///////////////////////////////////////////////////////////////////////////////
const unsigned*
version::begin (void) const
{
return components.begin ();
}
const unsigned*
version::end (void) const
{
return components.begin () + size;
}
///////////////////////////////////////////////////////////////////////////////
%%{ %%{
machine version; machine version;
@ -90,7 +118,7 @@ version::sanity (void) const {
{ accum *= 10; { accum *= 10;
accum += (uintptr_t)(fc - (unsigned char)'0'); } accum += (uintptr_t)(fc - (unsigned char)'0'); }
action finish action finish
{ v.values[v.size++] = accum ; } { v.components[v.size++] = accum ; }
number = (digit+) number = (digit+)
>clear >clear
@ -99,9 +127,9 @@ version::sanity (void) const {
dots = (number '.')* number; dots = (number '.')* number;
type = ('beta'i | 'b'i) %{ v.release = RELEASE_BETA; } type = ('beta'i | 'b'i) %{ v.release = BETA; }
| ('alpha'i | 'a'i) %{ v.release = RELEASE_ALPHA; } | ('alpha'i | 'a'i) %{ v.release = ALPHA; }
| ('gamma'i | 'g'i) %{ v.release = RELEASE_GAMMA; }; | ('gamma'i | 'g'i) %{ v.release = GAMMA; };
version := (dots type?) >clear version := (dots type?) >clear
$!{ throw std::invalid_argument (str); }; $!{ throw std::invalid_argument (str); };
@ -129,37 +157,24 @@ util::version::parse (const std::string& str) {
} }
//-----------------------------------------------------------------------------
util::version util::version
util::version::parse (const char *str) { util::version::parse (const char *str) {
return parse (std::string (str)); return parse (std::string (str));
} }
//----------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////
static std::string
release_to_string (version::release_t r) {
sanity (r);
static const char* RELEASE_STRINGS[] = {
"a", // RELEASE_ALPHA
"b", // RELEASE_BETA
"g", // RELEASE_GAMMA
"" // RELEASE_PRODUCTION
};
return RELEASE_STRINGS[r];
}
bool bool
version::operator> (const version &rhs) const { version::operator> (const version &rhs) const
unsigned int count = min (values.size (), rhs.values.size ()); {
unsigned int count = min (size, rhs.size);
for (unsigned int i = 0; i < count; ++i) for (unsigned int i = 0; i < count; ++i)
if (values[i] < rhs.values[i]) if (components[i] < rhs.components[i])
return false; return false;
if (values.size () < rhs.values.size()) if (size < rhs.size)
return false; return false;
if (release <= rhs.release) if (release <= rhs.release)
@ -169,35 +184,58 @@ version::operator> (const version &rhs) const {
} }
//-----------------------------------------------------------------------------
bool bool
version::operator== (const version &rhs) const { version::operator== (const version &rhs) const {
return values == rhs.values && return components == rhs.components &&
size == rhs.size && size == rhs.size &&
release == rhs.release; release == rhs.release;
} }
///////////////////////////////////////////////////////////////////////////////
namespace util {
std::ostream&
operator<< (std::ostream& os, const util::version::release_t r)
{
switch (r) {
case version::ALPHA: return os << 'a';
case version::BETA: return os << 'b';
case version::GAMMA: return os << 'g';
case version::PRODUCTION: return os;
default:
unreachable ();
}
}
}
//-----------------------------------------------------------------------------
std::ostream& std::ostream&
operator <<(std::ostream& os, const util::version& rhs) { util::operator<< (std::ostream& os, const util::version& rhs)
{
size_t elements = rhs.size; size_t elements = rhs.size;
CHECK_GT (elements, 0u); CHECK_GT (elements, 0u);
do {
os << rhs.major (); os << rhs.major ();
if (!--elements) if (!--elements)
goto done; break;
os << "." << rhs.minor (); os << "." << rhs.minor ();
if (!--elements) if (!--elements)
goto done; break;
os << "." << rhs.point (); os << "." << rhs.point ();
if (!--elements) if (!--elements)
goto done; break;
os << "." << rhs.build (); os << "." << rhs.build ();
CHECK_EQ (elements - 1, 0u); CHECK_EQ (elements - 1, 0u);
} while (0);
os << rhs.release;
done:
os << release_to_string (rhs.release);
return os; return os;
} }

View File

@ -20,15 +20,25 @@
#include <array> #include <array>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <limits>
namespace util { namespace util {
struct version { struct version {
// underlying component value type
using value_t = unsigned;
static_assert (std::numeric_limits<value_t>::max () >= 2100'00'00,
"value_t must be sufficient to store a reasonable future year in YYYYMMDD format");
/// type of release.
///
/// * must be sorted from earliest to latest
/// * specific values aren't currently guaranteed.
enum release_t { enum release_t {
RELEASE_ALPHA, ALPHA,
RELEASE_BETA, BETA,
RELEASE_GAMMA, GAMMA,
RELEASE_PRODUCTION PRODUCTION
}; };
version (); version ();
@ -38,36 +48,40 @@ namespace util {
void sanity (void) const; void sanity (void) const;
enum { // named component indices
OFFSET_MAJOR = 0, //
OFFSET_MINOR = 1, // * must start from zero and be monotonically increasing
OFFSET_POINT = 2, enum offset_t {
OFFSET_BUILD = 3, MAJOR = 0,
MINOR = 1,
NUM_OFFSETS POINT = 2,
BUILD = 3
}; };
unsigned major (void) const { return values[OFFSET_MAJOR]; } unsigned major (void) const;
unsigned minor (void) const { return values[OFFSET_MINOR]; } unsigned minor (void) const;
unsigned point (void) const { return values[OFFSET_POINT]; } unsigned point (void) const;
unsigned build (void) const { return values[OFFSET_BUILD]; } unsigned build (void) const;
const unsigned* begin (void) const;
const unsigned* end (void) const;
std::array<unsigned int, NUM_OFFSETS> values;
size_t size; size_t size;
std::array<unsigned,4u> components;
release_t release; release_t release;
static version parse (const std::string&); static version parse (const std::string&);
static version parse (const char*); static version parse (const char*);
bool operator < (const version& rhs) const; bool operator< (const version& rhs) const;
bool operator > (const version& rhs) const; bool operator> (const version& rhs) const;
bool operator >= (const version& rhs) const; bool operator>= (const version& rhs) const;
bool operator <= (const version& rhs) const; bool operator<= (const version& rhs) const;
bool operator == (const version& rhs) const; bool operator== (const version& rhs) const;
}; };
}
std::ostream& operator<< (std::ostream& os, const util::version& rhs); std::ostream& operator<< (std::ostream& os, const util::version& rhs);
}
#endif // __VERSION_HPP #endif // __VERSION_HPP