// 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 #include #include #include #include #if defined(__cpp_lib_atomic_is_always_lock_free) static_assert( std::atomic::is_always_lock_free, "atomic must be lock free"); #endif //------------------------------------------------------------------------------ template class Ring_Buffer_Ex; typedef Ring_Buffer_Ex Ring_Buffer; //------------------------------------------------------------------------------ template class Basic_Ring_Buffer { public: // read operations template bool get(T &x); template bool get(T *x, size_t n); template bool peek(T &x); template bool peek(T *x, size_t n); // write operations template bool put(const T &x); template bool put(const T *x, size_t n); }; //------------------------------------------------------------------------------ template class Ring_Buffer_Ex final : private Basic_Ring_Buffer> { private: typedef Basic_Ring_Buffer> 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, size_t>::type rp_{0}, wp_{0}; std::unique_ptr 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"