initial commit

This commit is contained in:
2026-02-12 00:45:31 -08:00
commit 5f168f370b
3024 changed files with 804889 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
#pragma once
#include "fl/math_macros.h"
#include "fl/namespace.h"
#include "fl/scoped_array.h"
#include "fl/stdint.h" // For standard integer types
namespace fl {
// TODO:
// ERROR bit to indicate over flow.
// Static version with compile-time capacity
template <typename T, fl::size N>
class StaticCircularBuffer {
public:
StaticCircularBuffer() : mHead(0), mTail(0) {}
void push(const T &value) {
if (full()) {
mTail = (mTail + 1) % (N + 1); // Overwrite the oldest element
}
mBuffer[mHead] = value;
mHead = (mHead + 1) % (N + 1);
}
bool pop(T &value) {
if (empty()) {
return false;
}
value = mBuffer[mTail];
mTail = (mTail + 1) % (N + 1);
return true;
}
fl::size size() const { return (mHead + N + 1 - mTail) % (N + 1); }
constexpr fl::size capacity() const { return N; }
bool empty() const { return mHead == mTail; }
bool full() const { return ((mHead + 1) % (N + 1)) == mTail; }
void clear() { mHead = mTail = 0; }
private:
T mBuffer[N + 1]; // Extra space for distinguishing full/empty
fl::size mHead;
fl::size mTail;
};
// Dynamic version with runtime capacity (existing implementation)
template <typename T> class DynamicCircularBuffer {
public:
DynamicCircularBuffer(fl::size capacity)
: mCapacity(capacity + 1), mHead(0),
mTail(0) { // Extra space for distinguishing full/empty
mBuffer.reset(new T[mCapacity]);
}
DynamicCircularBuffer(const DynamicCircularBuffer &) = delete;
DynamicCircularBuffer &operator=(const DynamicCircularBuffer &) = delete;
bool push_back(const T &value) {
if (full()) {
mTail = increment(mTail); // Overwrite the oldest element
}
mBuffer[mHead] = value;
mHead = increment(mHead);
return true;
}
bool pop_front(T *dst = nullptr) {
if (empty()) {
return false;
}
if (dst) {
*dst = mBuffer[mTail];
}
mTail = increment(mTail);
return true;
}
bool push_front(const T &value) {
if (full()) {
mHead = decrement(mHead); // Overwrite the oldest element
}
mTail = decrement(mTail);
mBuffer[mTail] = value;
return true;
}
bool pop_back(T *dst = nullptr) {
if (empty()) {
return false;
}
mHead = decrement(mHead);
if (dst) {
*dst = mBuffer[mHead];
}
return true;
}
T &front() { return mBuffer[mTail]; }
const T &front() const { return mBuffer[mTail]; }
T &back() { return mBuffer[(mHead + mCapacity - 1) % mCapacity]; }
const T &back() const {
return mBuffer[(mHead + mCapacity - 1) % mCapacity];
}
T &operator[](fl::size index) { return mBuffer[(mTail + index) % mCapacity]; }
const T &operator[](fl::size index) const {
return mBuffer[(mTail + index) % mCapacity];
}
fl::size size() const { return (mHead + mCapacity - mTail) % mCapacity; }
fl::size capacity() const { return mCapacity - 1; }
bool empty() const { return mHead == mTail; }
bool full() const { return increment(mHead) == mTail; }
void clear() { mHead = mTail = 0; }
private:
fl::size increment(fl::size index) const { return (index + 1) % mCapacity; }
fl::size decrement(fl::size index) const {
return (index + mCapacity - 1) % mCapacity;
}
fl::scoped_array<T> mBuffer;
fl::size mCapacity;
fl::size mHead;
fl::size mTail;
};
// For backward compatibility, keep the old name for the dynamic version
template <typename T>
using CircularBuffer = DynamicCircularBuffer<T>;
} // namespace fl