m/b/circular: template based on data type

This commit is contained in:
Danny Robson 2017-12-30 13:39:12 +11:00
parent 59b21e67dd
commit dd69da09c3
2 changed files with 33 additions and 18 deletions

View File

@ -54,7 +54,8 @@ tmpname (std::string &str, size_t length)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
circular::circular (size_t bytes) template <typename ValueT>
circular<ValueT>::circular (size_t bytes)
{ {
bytes = max (bytes, sizeof (value_type)); bytes = max (bytes, sizeof (value_type));
bytes = round_up (bytes, pagesize ()); bytes = round_up (bytes, pagesize ());
@ -89,7 +90,9 @@ circular::circular (size_t bytes)
// pre-allocate a sufficiently large virtual memory block. it doesn't // pre-allocate a sufficiently large virtual memory block. it doesn't
// matter much what flags we use because we'll just be overwriting it // matter much what flags we use because we'll just be overwriting it
// shortly. // shortly.
m_begin = reinterpret_cast<char*> (mmap (nullptr, bytes * 2, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); m_begin = reinterpret_cast<ValueT*> (
mmap (nullptr, bytes * 2, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
);
if (MAP_FAILED == m_begin) if (MAP_FAILED == m_begin)
posix::error::throw_code (); posix::error::throw_code ();
@ -101,8 +104,8 @@ circular::circular (size_t bytes)
auto prot = PROT_READ | PROT_WRITE; auto prot = PROT_READ | PROT_WRITE;
auto flag = MAP_FIXED | MAP_SHARED; auto flag = MAP_FIXED | MAP_SHARED;
m_begin = reinterpret_cast<char*> (mmap (m_begin, bytes, prot, flag, fd, 0)); m_begin = reinterpret_cast<ValueT*> (mmap (m_begin, bytes, prot, flag, fd, 0));
m_end = reinterpret_cast<char*> (mmap (m_begin + bytes, bytes, prot, flag, fd, 0)); m_end = reinterpret_cast<ValueT*> (mmap (m_begin + bytes, bytes, prot, flag, fd, 0));
if (m_begin == MAP_FAILED || m_end == MAP_FAILED) if (m_begin == MAP_FAILED || m_end == MAP_FAILED)
posix::error::throw_code (); posix::error::throw_code ();
@ -113,7 +116,8 @@ circular::circular (size_t bytes)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
circular::~circular () template <typename ValueT>
circular<ValueT>::~circular ()
{ {
auto res = munmap (m_begin, 2 * (m_end - m_begin)); auto res = munmap (m_begin, 2 * (m_end - m_begin));
(void)res; (void)res;
@ -122,24 +126,32 @@ circular::~circular ()
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
char* template <typename ValueT>
circular::begin (void)& ValueT*
circular<ValueT>::begin (void)&
{ {
return m_begin; return m_begin;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
char* template <typename ValueT>
circular::end (void)& ValueT*
circular<ValueT>::end (void)&
{ {
return m_end; return m_end;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <typename ValueT>
size_t size_t
circular::size (void) const circular<ValueT>::size (void) const
{ {
return m_end - m_begin; return m_end - m_begin;
} }
///////////////////////////////////////////////////////////////////////////////
template class util::memory::buffer::circular<char>;
template class util::memory::buffer::circular<uint8_t>;

View File

@ -23,9 +23,12 @@ namespace util::memory::buffer {
// buffer size is advisory and will likely depend on page size. the user // buffer size is advisory and will likely depend on page size. the user
// must check the size after creation if this field is important for // must check the size after creation if this field is important for
// their usage. // their usage.
template <typename ValueT>
class circular { class circular {
public: public:
using value_type = char; using value_type = ValueT;
using iterator = value_type*;
using const_iterator = const value_type*;
explicit circular (size_t bytes); explicit circular (size_t bytes);
~circular (); ~circular ();
@ -35,19 +38,19 @@ namespace util::memory::buffer {
circular& operator= (const circular&) = delete; circular& operator= (const circular&) = delete;
circular& operator= (circular&&) = delete; circular& operator= (circular&&) = delete;
char& operator[] (size_t)&; value_type& operator[] (size_t)&;
const char& operator[] (size_t) const&; const value_type& operator[] (size_t) const&;
char* begin (void)&; iterator begin (void)&;
char* end (void)&; iterator end (void)&;
const char* begin (void) const&; const_iterator begin (void) const&;
const char* end (void) const&; const_iterator end (void) const&;
size_t size (void) const; size_t size (void) const;
private: private:
char *m_begin, *m_end; value_type *m_begin, *m_end;
}; };
} }