69 lines
2.2 KiB
C++
69 lines
2.2 KiB
C++
// Copyright Jean Pierre Cimalando 2018.
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
#pragma once
|
|
#include <memory>
|
|
#include <atomic>
|
|
#include <type_traits>
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
|
|
#if defined(__cpp_lib_atomic_is_always_lock_free)
|
|
static_assert(
|
|
std::atomic<size_t>::is_always_lock_free, "atomic<size_t> must be lock free");
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------------
|
|
template <bool> class Ring_Buffer_Ex;
|
|
typedef Ring_Buffer_Ex<true> Ring_Buffer;
|
|
|
|
//------------------------------------------------------------------------------
|
|
template <class RB>
|
|
class Basic_Ring_Buffer {
|
|
public:
|
|
// read operations
|
|
template <class T> bool get(T &x);
|
|
template <class T> bool get(T *x, size_t n);
|
|
template <class T> bool peek(T &x);
|
|
template <class T> bool peek(T *x, size_t n);
|
|
// write operations
|
|
template <class T> bool put(const T &x);
|
|
template <class T> bool put(const T *x, size_t n);
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
template <bool Atomic>
|
|
class Ring_Buffer_Ex final :
|
|
private Basic_Ring_Buffer<Ring_Buffer_Ex<Atomic>> {
|
|
private:
|
|
typedef Basic_Ring_Buffer<Ring_Buffer_Ex<Atomic>> Base;
|
|
public:
|
|
// initialization and cleanup
|
|
explicit Ring_Buffer_Ex(size_t capacity);
|
|
~Ring_Buffer_Ex();
|
|
// attributes
|
|
size_t capacity() const;
|
|
// read operations
|
|
size_t size_used() const;
|
|
bool discard(size_t len);
|
|
using Base::get;
|
|
using Base::peek;
|
|
// write operations
|
|
size_t size_free() const;
|
|
using Base::put;
|
|
|
|
private:
|
|
size_t cap_{0};
|
|
typename std::conditional<Atomic, std::atomic<size_t>, size_t>::type rp_{0}, wp_{0};
|
|
std::unique_ptr<uint8_t[]> rbdata_ {};
|
|
friend Base;
|
|
bool getbytes_(void *data, size_t len);
|
|
bool peekbytes_(void *data, size_t len) const;
|
|
bool getbytes_ex_(void *data, size_t len, bool advp);
|
|
bool putbytes_(const void *data, size_t len);
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
#include "ring_buffer.tcc"
|