32#if __has_include(<source_location>)
33 #include <source_location>
34 #define KCENON_MODULE_HAS_SOURCE_LOCATION 1
36 #define KCENON_MODULE_HAS_SOURCE_LOCATION 0
47#if KCENON_MODULE_HAS_SOURCE_LOCATION
48using source_location = std::source_location;
57 const char* file = __builtin_FILE(),
58 const char* function = __builtin_FUNCTION(),
59 int line = __builtin_LINE()
65 constexpr int line() const noexcept {
return line_; }
69 const char* file = __builtin_FILE(),
70 const char* function = __builtin_FUNCTION(),
71 int line = __builtin_LINE()
99template<
typename T, std::
size_t Capacity>
101 static_assert(Capacity > 0,
"CircularBuffer capacity must be greater than zero");
112 bool push(
const T& value,
bool overwrite =
false) {
113 std::lock_guard<std::mutex> lock(
mutex_);
126 bool push(T&& value,
bool overwrite =
false) {
127 std::lock_guard<std::mutex> lock(
mutex_);
144 [[nodiscard]] std::optional<T>
pop() {
145 std::lock_guard<std::mutex> lock(
mutex_);
150 std::lock_guard<std::mutex> lock(
mutex_);
154 [[nodiscard]]
bool full()
const {
155 std::lock_guard<std::mutex> lock(
mutex_);
156 return size_ == Capacity;
159 [[nodiscard]] std::size_t
size()
const {
160 std::lock_guard<std::mutex> lock(
mutex_);
164 [[nodiscard]]
constexpr std::size_t
capacity()
const {
170 index = (index + 1) % Capacity;
174 return size_ == Capacity;
187 mutable std::mutex
mutex_;
188 std::array<T, Capacity>
buffer_{};
189 std::size_t
head_{0};
190 std::size_t
tail_{0};
191 std::size_t
size_{0};
202 ::operator
delete(
static_cast<void*
>(ptr));
223 :
growth_(growth == 0 ? 1 : growth) {}
231 template<
typename... Args>
232 std::unique_ptr<T, std::function<void(T*)>>
acquire(
bool* reused, Args&&... args) {
234 bool reused_local =
false;
236 std::lock_guard<std::mutex> lock(
mutex_);
248 *reused = reused_local;
251 new (raw) T(std::forward<Args>(args)...);
252 return std::unique_ptr<T, std::function<void(T*)>>(raw, [
this](T* ptr) {
257 template<
typename... Args>
258 std::unique_ptr<T, std::function<void(T*)>>
acquire(Args&&... args) {
259 return acquire(
static_cast<bool*
>(
nullptr), std::forward<Args>(args)...);
271 std::lock_guard<std::mutex> lock(
mutex_);
282 std::lock_guard<std::mutex> lock(
mutex_);
290 std::lock_guard<std::mutex> lock(
mutex_);
296 std::lock_guard<std::mutex> lock(
mutex_);
301 using RawPtr = std::unique_ptr<T, detail::RawDelete<T>>;
304 for (std::size_t i = 0; i < count; ++i) {
305 RawPtr block(
static_cast<T*
>(::operator
new(
sizeof(T))));
307 storage_.push_back(std::move(block));
312 mutable std::mutex
mutex_;
Thread-safe fixed-size circular buffer.
constexpr std::size_t capacity() const
bool push(T &&value, bool overwrite=false)
bool push(const T &value, bool overwrite=false)
Push a value to the buffer.
std::optional< T > pop()
Pop a value from the buffer.
void advance(std::size_t &index) noexcept
std::optional< T > pop_locked()
bool is_full_locked() const noexcept
std::array< T, Capacity > buffer_
Thread-safe object pool that reuses raw storage for expensive objects.
void release(T *ptr) noexcept
Return raw storage to the pool (destructor already run).
void allocate_block_unlocked(std::size_t count)
std::vector< RawPtr > storage_
std::unique_ptr< T, std::function< void(T *)> > acquire(bool *reused, Args &&... args)
Acquire an object constructed with the provided arguments.
pointer_type acquire(bool *reused, Args &&... args)
Acquire an object constructed with the provided arguments.
ObjectPool(std::size_t growth=32)
void reserve(std::size_t count)
Add count additional blocks to the pool.
std::unique_ptr< T, detail::RawDelete< T > > RawPtr
std::unique_ptr< T, std::function< void(T *)> > acquire(Args &&... args)
std::size_t available() const
std::stack< T * > free_list_
void clear()
Destroy all cached instances and release memory.
C++17-compatible source_location implementation using compiler builtins.
constexpr source_location(const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE()) noexcept
static constexpr source_location current(const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE()) noexcept
constexpr int line() const noexcept
constexpr int column() const noexcept
constexpr const char * file_name() const noexcept
constexpr const char * function_name() const noexcept
void operator()(T *ptr) const noexcept