36 #ifndef CHARRINGBUFFER_H 37 #define CHARRINGBUFFER_H 39 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) 40 #error "Only <final/final.h> can be included directly." 49 #include <final/util/fstring.h> 55 template <std::
size_t>
62 template <
typename T, std::
size_t Capacity>
70 template<std::
size_t N = Capacity>
73 #if __cplusplus > 1 && __cplusplus >= 201703L 75 static constexpr
bool is_pow2 = (N & (N - 1)) == 0;
77 static constexpr
auto next (std::size_t current) noexcept -> std::size_t
79 if constexpr ( is_pow2 )
80 return (current + 1) & (N - 1);
82 return (current + 1) % N;
85 static constexpr
auto add ( std::size_t current
86 , std::size_t offset ) noexcept -> std::size_t
88 if constexpr ( is_pow2 )
89 return (current + offset) & (N - 1);
91 return (current + offset) % N;
96 static constexpr
auto next (std::size_t current) noexcept -> std::size_t
98 return (current + 1) % N;
101 static constexpr
auto add ( std::size_t current
102 , std::size_t offset ) noexcept -> std::size_t
104 return (current + offset) % N;
114 template <
typename Type, std::
size_t N>
119 using iterator_category = std::forward_iterator_tag;
120 using value_type = Type;
121 using difference_type = std::ptrdiff_t;
122 using pointer = Type*;
123 using reference = Type&;
125 explicit ring_iterator (pointer p, std::size_t start, std::size_t pos)
144 inline auto operator * ()
const noexcept -> reference
146 #if defined(__clang__) 147 #pragma clang diagnostic push 148 #if __has_warning("-Wunsafe-buffer-usage") 149 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" 153 #if defined(__clang__) 154 #pragma clang diagnostic pop 158 inline auto operator -> ()
const noexcept -> pointer
166 return lhs.index == rhs.index
167 && lhs.ptr == rhs.ptr
168 && lhs.offset == rhs.offset;
174 return ! (lhs == rhs);
179 pointer ptr{
nullptr};
180 const std::size_t offset{0U};
181 std::size_t index{0U};
188 tmp.index += std::size_t(size);
196 using difference_type = std::ptrdiff_t;
198 using reference = T&;
199 using const_reference =
const T&;
200 using value_type = T;
210 inline auto operator [] (std::size_t index) noexcept -> reference
212 static_assert ( Capacity > 0,
"Ring buffer has no memory" );
216 inline auto operator [] (std::size_t index)
const noexcept -> const_reference
218 static_assert ( Capacity > 0,
"Ring buffer has no memory" );
223 virtual inline auto getClassName()
const ->
FString 225 return "FRingBuffer";
228 inline auto getSize()
const noexcept -> std::size_t
233 constexpr
auto getCapacity()
const noexcept -> std::size_t
238 inline auto begin() noexcept ->
iterator 240 return iterator(buffer.data(), head, 0);
248 inline auto end() noexcept ->
iterator 250 return iterator(buffer.data(), head, getSize());
258 inline auto front() noexcept -> reference
261 return empty_element;
266 inline auto front()
const noexcept -> const_reference
269 return empty_element;
274 inline auto back() noexcept -> reference
277 return empty_element;
279 return buffer[last_index];
282 inline auto back()
const noexcept -> const_reference
285 return empty_element;
287 return buffer[last_index];
291 inline void clear() noexcept
295 last_index = Capacity - 1;
300 constexpr
auto isEmpty()
const noexcept ->
bool 302 return elements == 0;
305 constexpr
auto hasData()
const noexcept ->
bool 310 constexpr
auto isFull()
const noexcept ->
bool 312 return elements == Capacity;
316 inline void push (
const T& item) noexcept
321 static_assert ( Capacity > 0,
"Ring buffer has no memory" );
328 inline void push_back (
const T& item) noexcept
333 template <
typename... Args>
334 inline void emplace (Args&&... args)
339 static_assert ( Capacity > 0,
"Ring buffer has no memory" );
340 buffer[tail] = T(std::forward<Args>(args)...);
346 template <
typename... Args>
347 inline void emplace_back (Args&&... args)
349 emplace (std::forward<Args>(args)...);
352 inline void pop() noexcept
357 static_assert ( Capacity > 0,
"Ring buffer has no memory" );
362 inline void pop_front() noexcept
367 inline void pop (std::size_t s) noexcept
372 static_assert ( Capacity > 0,
"Ring buffer has no memory" );
373 s = std::min(s, elements);
380 std::size_t head{0U};
381 std::size_t tail{0U};
382 std::size_t last_index{0U};
383 std::size_t elements{0U};
384 std::array<value_type, Capacity> buffer;
385 value_type empty_element{};
396 template <std::
size_t Capacity>
409 inline auto getClassName()
const ->
FString override 411 return "CharRingBuffer";
415 auto strncmp_front (
const char*
string 416 , std::size_t length )
const noexcept ->
bool 418 #if defined(__clang__) 419 #pragma clang diagnostic push 420 #if __has_warning("-Wunsafe-buffer-usage") 421 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" 427 if ( length > getSize() )
430 const auto* buf = buffer.data();
433 return std::memcmp(
string, buf + head, length) == 0;
435 const auto l1 = std::min(length, Capacity - head);
437 if ( std::memcmp(
string, buf + head, l1) != 0 )
440 const auto l2 = length - l1;
441 return l2 == 0 || std::memcmp(
string + l1, buf, l2) == 0;
442 #if defined(__clang__) 443 #pragma clang diagnostic pop 451 #endif // CHARRINGBUFFER_H Definition: class_template.cpp:25
Definition: char_ringbuffer.h:71
Definition: char_ringbuffer.h:115
Definition: ftermoutput.h:69
Definition: char_ringbuffer.h:56