Use the util namespace for more classes

This commit is contained in:
Danny Robson 2011-10-07 21:58:16 +11:00
parent 6e2ba427f9
commit 641a15f0ec
6 changed files with 154 additions and 147 deletions

View File

@ -22,13 +22,15 @@
#include "debug.hpp" #include "debug.hpp"
class nocopy { namespace util {
public: class nocopy {
nocopy () { ; } public:
nocopy () { ; }
private: private:
nocopy (const nocopy &) = delete; nocopy (const nocopy &) = delete;
nocopy& operator =(const nocopy &) = delete; nocopy& operator =(const nocopy &) = delete;
}; };
}
#endif #endif

View File

@ -1,23 +0,0 @@
// Derived from boost::noncopyable
//
// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Contributed by Dave Abrahams
#ifndef __UTIL_NONCOPYABLE_HPP
#define __UTIL_NONCOPYABLE_HPP
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
};
#endif

View File

@ -22,4 +22,4 @@
// Explicitly instance a possibly useful specialisation so that we can more easily catch linker errors. // Explicitly instance a possibly useful specialisation so that we can more easily catch linker errors.
template class pool<std::string>; template class util::pool<std::string>;

126
pool.hpp
View File

@ -22,79 +22,79 @@
#include "nocopy.hpp" #include "nocopy.hpp"
namespace util {
template <typename T> template <typename T>
class pool : public nocopy { class pool : public nocopy {
protected: protected:
union node { union node {
char _data[sizeof (T)]; char _data[sizeof (T)];
node *_chain; node *_chain;
}; };
node *m_head; node *m_head;
node *m_next; node *m_next;
unsigned int m_capacity; unsigned int m_capacity;
public: public:
pool (unsigned int _capacity): pool (unsigned int _capacity):
m_capacity (_capacity) m_capacity (_capacity)
{ {
static_assert (sizeof (T) >= sizeof (uintptr_t), static_assert (sizeof (T) >= sizeof (uintptr_t),
"pool<T>'s chained block system requires that T be at least pointer sized"); "pool<T>'s chained block system requires that T be at least pointer sized");
m_head = (node *)operator new (sizeof (T) * m_capacity); m_head = (node *)operator new (sizeof (T) * m_capacity);
m_next = m_head; m_next = m_head;
for (unsigned int i = 0; i < m_capacity - 1; ++i) for (unsigned int i = 0; i < m_capacity - 1; ++i)
m_next[i]._chain = &m_next[i + 1]; m_next[i]._chain = &m_next[i + 1];
m_next[m_capacity - 1]._chain = NULL; m_next[m_capacity - 1]._chain = NULL;
}
~pool () {
check (m_next != NULL);
unsigned int doomed_count = 0;
for (node *cursor = m_next; cursor != NULL; cursor = cursor->_chain)
++doomed_count;
check_eq (doomed_count, m_capacity);
operator delete (m_head);
}
unsigned int capacity (void) const
{ return m_capacity; }
template <typename ...Args>
T* acquire (Args&... args) {
if (!m_next)
throw std::bad_alloc ();
node *newnext = m_next->_chain;
T *data = (T*)&m_next->_data;
try {
new (data) T (args...);
} catch (...) {
m_next->_chain = newnext;
throw;
} }
m_next = newnext;
return data; ~pool () {
} check (m_next != NULL);
unsigned int doomed_count = 0;
for (node *cursor = m_next; cursor != NULL; cursor = cursor->_chain)
++doomed_count;
check_eq (doomed_count, m_capacity);
operator delete (m_head);
}
unsigned int capacity (void) const
{ return m_capacity; }
void release (T *data) { template <typename ...Args>
data->~T(); T* acquire (Args&... args) {
node *newnode = (node *)data; if (!m_next)
throw std::bad_alloc ();
newnode->_chain = m_next; node *newnext = m_next->_chain;
m_next = newnode; T *data = (T*)&m_next->_data;
}
}; try {
new (data) T (args...);
} catch (...) {
m_next->_chain = newnext;
throw;
}
m_next = newnext;
return data;
}
void release (T *data) {
data->~T();
node *newnode = (node *)data;
newnode->_chain = m_next;
m_next = newnode;
}
};
}
#endif // __UTIL_POOL_HPP #endif // __UTIL_POOL_HPP

View File

@ -20,12 +20,14 @@
#include "version.hpp" #include "version.hpp"
#include <cstring>
#include <stdexcept> #include <stdexcept>
#include "debug.hpp" #include "debug.hpp"
using namespace std; using namespace std;
using namespace util;
version::version (unsigned int _major, version::version (unsigned int _major,
@ -45,6 +47,14 @@ version::version (const string& str):
} }
version::version (const char *str):
m_values (NUM_OFFSETS, 0),
m_release (RELEASE_PRODUCTION) {
m_values.clear ();
parse (str);
}
static void static void
check_release (version::release_t r) { check_release (version::release_t r) {
switch (r) { switch (r) {
@ -109,6 +119,20 @@ version::parse (const string& str) {
} }
void
version::parse (const char *str) {
unsigned int current;
size_t cs;
const char *p = str,
*pe = str + strlen (str),
*eof = pe;
%%write init;
%%write exec;
}
static string static string
release_string (const version::release_t r) { release_string (const version::release_t r) {
switch (r) { switch (r) {
@ -140,15 +164,17 @@ version::operator > (const version &rhs) const {
} }
ostream& namespace util {
operator <<(ostream& os, const version& rhs) { ostream&
auto i = rhs.m_values.begin(); operator <<(ostream& os, const util::version& rhs) {
os << *i; ++i; auto i = rhs.m_values.begin();
os << *i; ++i;
for (; i != rhs.m_values.end(); ++i) for (; i != rhs.m_values.end(); ++i)
os << '.' << *i; os << '.' << *i;
os << release_string (rhs.m_release); os << release_string (rhs.m_release);
return os; return os;
}
} }

View File

@ -25,62 +25,64 @@
#include <iostream> #include <iostream>
class version { namespace util {
public: class version {
enum release_t { public:
RELEASE_ALPHA, enum release_t {
RELEASE_BETA, RELEASE_ALPHA,
RELEASE_GAMMA, RELEASE_BETA,
RELEASE_PRODUCTION RELEASE_GAMMA,
}; RELEASE_PRODUCTION
};
version (unsigned int _major, version (unsigned int _major,
unsigned int _minor); unsigned int _minor);
version (const std::string& str); version (const std::string& str);
virtual ~version () { ; } version (const char *str);
virtual void sanity (void) const; virtual ~version () { ; }
protected: virtual void sanity (void) const;
enum {
OFFSET_MAJOR = 0,
OFFSET_MINOR = 1,
OFFSET_POINT = 2,
OFFSET_BUILD = 3,
NUM_OFFSETS protected:
}; enum {
OFFSET_MAJOR = 0,
OFFSET_MINOR = 1,
OFFSET_POINT = 2,
OFFSET_BUILD = 3,
std::vector <unsigned int> m_values; NUM_OFFSETS
release_t m_release; };
void parse (const std::string&); std::vector <unsigned int> m_values;
release_t m_release;
public: void parse (const std::string&);
void parse (const char*);
unsigned int major (void) const public:
{ return m_values[OFFSET_MAJOR]; }
unsigned int minor (void) const
{ return m_values[OFFSET_MINOR]; }
unsigned int point (void) const
{ return m_values[OFFSET_POINT]; }
unsigned int build (void) const
{ return m_values[OFFSET_BUILD]; }
bool operator < (const version& rhs) const; unsigned int major (void) const
bool operator > (const version& rhs) const; { return m_values[OFFSET_MAJOR]; }
bool operator >= (const version& rhs) const; unsigned int minor (void) const
bool operator <= (const version& rhs) const; { return m_values[OFFSET_MINOR]; }
bool operator == (const version& rhs) const unsigned int point (void) const
{ return m_values == rhs.m_values && { return m_values[OFFSET_POINT]; }
m_release == rhs.m_release; } unsigned int build (void) const
{ return m_values[OFFSET_BUILD]; }
friend std::ostream& bool operator < (const version& rhs) const;
operator <<(std::ostream& os, const version& rhs); bool operator > (const version& rhs) const;
}; bool operator >= (const version& rhs) const;
bool operator <= (const version& rhs) const;
bool operator == (const version& rhs) const
{ return m_values == rhs.m_values &&
m_release == rhs.m_release; }
friend std::ostream&
operator <<(std::ostream& os, const version& rhs);
};
}
std::ostream&
operator <<(std::ostream& os, const version& rhs);
#endif // __VERSION_HPP #endif // __VERSION_HPP