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 = round_up (bytes, pagesize ());
@ -89,7 +90,9 @@ circular::circular (size_t bytes)
// pre-allocate a sufficiently large virtual memory block. it doesn't
// matter much what flags we use because we'll just be overwriting it
// 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)
posix::error::throw_code ();
@ -101,8 +104,8 @@ circular::circular (size_t bytes)
auto prot = PROT_READ | PROT_WRITE;
auto flag = MAP_FIXED | MAP_SHARED;
m_begin = reinterpret_cast<char*> (mmap (m_begin, bytes, prot, flag, fd, 0));
m_end = reinterpret_cast<char*> (mmap (m_begin + bytes, bytes, prot, flag, fd, 0));
m_begin = reinterpret_cast<ValueT*> (mmap (m_begin, 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)
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));
(void)res;
@ -122,24 +126,32 @@ circular::~circular ()
///////////////////////////////////////////////////////////////////////////////
char*
circular::begin (void)&
template <typename ValueT>
ValueT*
circular<ValueT>::begin (void)&
{
return m_begin;
}
//-----------------------------------------------------------------------------
char*
circular::end (void)&
template <typename ValueT>
ValueT*
circular<ValueT>::end (void)&
{
return m_end;
}
///////////////////////////////////////////////////////////////////////////////
template <typename ValueT>
size_t
circular::size (void) const
circular<ValueT>::size (void) const
{
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
// must check the size after creation if this field is important for
// their usage.
template <typename ValueT>
class circular {
public:
using value_type = char;
using value_type = ValueT;
using iterator = value_type*;
using const_iterator = const value_type*;
explicit circular (size_t bytes);
~circular ();
@ -35,19 +38,19 @@ namespace util::memory::buffer {
circular& operator= (const circular&) = delete;
circular& operator= (circular&&) = delete;
char& operator[] (size_t)&;
const char& operator[] (size_t) const&;
value_type& operator[] (size_t)&;
const value_type& operator[] (size_t) const&;
char* begin (void)&;
char* end (void)&;
iterator begin (void)&;
iterator end (void)&;
const char* begin (void) const&;
const char* end (void) const&;
const_iterator begin (void) const&;
const_iterator end (void) const&;
size_t size (void) const;
private:
char *m_begin, *m_end;
value_type *m_begin, *m_end;
};
}