zengine-old/engine/3rdparty/zlib/include/zstd/pool_static.h

59 lines
1.3 KiB
C++

#pragma once
#include <concepts>
namespace zstd {
template<size_t T>
struct static_buffer {
char data[T];
};
template<std::move_constructible T, size_t T_capacity = 1>
class channel_static {
static_assert(T_capacity != 0);
protected:
int m_tail;
int m_head;
static_buffer<sizeof(T)> m_buf[T_capacity];
std::mutex m_mtx;
std::condition_variable m_cv;
public:
~channel_static() {
reset();
}
channel_static() : m_tail(0), m_head(0), m_buf() {}
int head() {
return m_head;
}
int tail() {
return m_tail;
}
int count() {
return m_head - m_tail;
}
void reset() {
for (int i = m_tail; i < m_head; i++) {
std::destroy_at((T*)(m_buf + m_tail % T_capacity));
}
m_tail = 0;
m_head = 0;
}
template<typename... Args>
void release(Args... args) {
std::unique_lock<std::mutex> lck(m_mtx);
while (m_head >= m_tail + T_capacity) {
m_cv.wait(lck);
}
std::construct_at((T*)(m_buf + m_head % T_capacity), std::forward<Args>(args)...);
if (m_head++ == m_tail)
m_cv.notify_one();
};
T acquire() {
std::unique_lock<std::mutex> lck(m_mtx);
while (m_tail >= m_head) {
m_cv.wait(lck);
}
int tail = m_tail % T_capacity;
if (m_tail++ == m_head - T_capacity)
m_cv.notify_one();
return std::move(*(T*)(m_buf + tail));
};
};
}