code integration
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE
|
||||
*/
|
||||
|
||||
/*
|
||||
ver: 2.x.x - build: 2026-04-28
|
||||
*/
|
||||
|
||||
/*
|
||||
The zlib License
|
||||
|
||||
Copyright (c) 2026 SD-Innovation S.A.S.
|
||||
|
||||
This software is provided ‘as-is’, without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ringBuffer.h"
|
||||
|
||||
namespace sdi_toolBox::common::utils
|
||||
{
|
||||
//--------------------------------------------------------------
|
||||
/**
|
||||
* @brief Fixed-size circular buffer with compile-time capacity
|
||||
* and no-overwrite behavior.
|
||||
*
|
||||
* This template wraps a RingBuffer and prevents new elements from being
|
||||
* written when the buffer is full. Existing data is never overwritten;
|
||||
* push() simply fails and returns false when capacity is reached.
|
||||
*
|
||||
* @tparam T Element type stored in the buffer.
|
||||
* @tparam CAPACITY Compile-time buffer capacity. Must be > 0.
|
||||
*
|
||||
* @note The class provides both optional-returning and out-parameter
|
||||
* overloads for pop/front/back to suit different runtime constraints.
|
||||
* @warning Instantiating with CAPACITY == 0 is forbidden (static_assert).
|
||||
*
|
||||
* @code{.cpp}
|
||||
* CircularBuffer<int, 8> cb;
|
||||
* if (cb.push(42))
|
||||
* {
|
||||
* // element was inserted
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // buffer was full, element was discarded
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template<class T, std::size_t CAPACITY>
|
||||
class CircularBuffer
|
||||
{
|
||||
static_assert(CAPACITY > 0, "CAPACITY must be > 0");
|
||||
|
||||
public:
|
||||
///@name Write operations
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Try to append a value to the buffer.
|
||||
*
|
||||
* If the buffer is full, the value is discarded and no overwrite occurs.
|
||||
* @param value Value to append (copied).
|
||||
*
|
||||
* @return true if the value was inserted, false if the buffer was full.
|
||||
*/
|
||||
bool push(const T &value);
|
||||
|
||||
///@}
|
||||
///@name Read operations
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Remove and return the oldest element from the buffer.
|
||||
*
|
||||
* @return std::optional<T> The oldest element if present, std::nullopt if empty.
|
||||
*/
|
||||
|
||||
std::optional<T> pop();
|
||||
/**
|
||||
* @brief Remove the oldest element and store it in the provided reference.
|
||||
*
|
||||
* @param value Output reference that receives the removed element.
|
||||
*
|
||||
* @return true if an element was removed, false if the buffer was empty.
|
||||
*/
|
||||
bool pop(T &value);
|
||||
|
||||
/**
|
||||
* @brief Return (without removing) the oldest element.
|
||||
*
|
||||
* @return std::optional<T> The oldest element if present, std::nullopt if empty.
|
||||
*/
|
||||
[[nodiscard]] std::optional<T> front() const;
|
||||
|
||||
/**
|
||||
* @brief Copy the oldest element into the provided reference without removing it.
|
||||
*
|
||||
* @param value Output reference that receives the element.
|
||||
*
|
||||
* @return true if the element was copied, false if the buffer is empty.
|
||||
*/
|
||||
[[nodiscard]] bool front(T &value) const;
|
||||
|
||||
/**
|
||||
* @brief Return (without removing) the newest element.
|
||||
*
|
||||
* @return std::optional<T> The newest element if present, std::nullopt if empty.
|
||||
*/
|
||||
[[nodiscard]] std::optional<T> back() const;
|
||||
|
||||
/**
|
||||
* @brief Copy the newest element into the provided reference without removing it.
|
||||
*
|
||||
* @param value Output reference that receives the element.
|
||||
*
|
||||
* @return true if the element was copied, false if the buffer is empty.
|
||||
*/
|
||||
[[nodiscard]] bool back(T &value) const;
|
||||
|
||||
///@}
|
||||
///@name State queries
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Check whether the buffer is empty.
|
||||
*
|
||||
* @return true if empty, false otherwise.
|
||||
*/
|
||||
[[nodiscard]] bool empty() const;
|
||||
|
||||
/**
|
||||
* @brief Check whether the buffer is full.
|
||||
*
|
||||
* @return true if full, false otherwise.
|
||||
*/
|
||||
[[nodiscard]] bool full() const;
|
||||
|
||||
/**
|
||||
* @brief Number of elements currently stored in the buffer.
|
||||
*
|
||||
* @return Current size (0 .. CAPACITY).
|
||||
*/
|
||||
[[nodiscard]] std::size_t size() const;
|
||||
|
||||
/**
|
||||
* @brief Compile-time capacity of the buffer.
|
||||
*
|
||||
* @return The maximum number of elements the buffer can hold.
|
||||
*/
|
||||
[[nodiscard]] constexpr std::size_t capacity() const;
|
||||
|
||||
///@}
|
||||
///@name Modifiers
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Clear the buffer and reset internal indices.
|
||||
*
|
||||
* After calling clear(), empty() returns true and size() returns 0.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
///@name Data members
|
||||
///@{
|
||||
|
||||
RingBuffer<T, CAPACITY> m_buffer{}; ///< Underlying ring buffer
|
||||
|
||||
///@}
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/* Try to append a value to the buffer. If the buffer is full,
|
||||
* the value is discarded. Return true if the value was inserted,
|
||||
* false if the buffer was full. */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
bool CircularBuffer<T, CAPACITY>::push(const T &value)
|
||||
{
|
||||
if (m_buffer.full())
|
||||
return false;
|
||||
return m_buffer.push(value);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Remove and return the oldest value from the buffer. If the
|
||||
* buffer is empty, return std::nullopt */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
std::optional<T> CircularBuffer<T, CAPACITY>::pop()
|
||||
{
|
||||
return m_buffer.pop();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Remove the oldest value from the buffer and store it in
|
||||
* 'value'. Return true if successful, false if the buffer is empty */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
bool CircularBuffer<T, CAPACITY>::pop(T &value)
|
||||
{
|
||||
return m_buffer.pop(value);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Return the oldest value without removing it. If the buffer is
|
||||
* empty, return std::nullopt */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
std::optional<T> CircularBuffer<T, CAPACITY>::front() const
|
||||
{
|
||||
return m_buffer.front();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Return the oldest value without removing it and store it in
|
||||
* 'value'. Return true if successful, false if the buffer is empty */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
bool CircularBuffer<T, CAPACITY>::front(T &value) const
|
||||
{
|
||||
return m_buffer.front(value);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Return the newest value without removing it. If the buffer is
|
||||
* empty, return std::nullopt */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
std::optional<T> CircularBuffer<T, CAPACITY>::back() const
|
||||
{
|
||||
return m_buffer.back();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Return the newest value without removing it and store it in
|
||||
* 'value'. Return true if successful, false if the buffer is empty */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
bool CircularBuffer<T, CAPACITY>::back(T &value) const
|
||||
{
|
||||
return m_buffer.back(value);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Check if the buffer is empty */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
bool CircularBuffer<T, CAPACITY>::empty() const
|
||||
{
|
||||
return m_buffer.empty();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Check if the buffer is full */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
bool CircularBuffer<T, CAPACITY>::full() const
|
||||
{
|
||||
return m_buffer.full();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get the number of elements currently in the buffer */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
std::size_t CircularBuffer<T, CAPACITY>::size() const
|
||||
{
|
||||
return m_buffer.size();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get the maximum capacity of the buffer */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
[[nodiscard]] constexpr std::size_t CircularBuffer<T, CAPACITY>::capacity() const
|
||||
{
|
||||
return CAPACITY;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Clear the buffer, resetting it to an empty state */
|
||||
template<class T, std::size_t CAPACITY>
|
||||
void CircularBuffer<T, CAPACITY>::clear()
|
||||
{
|
||||
m_buffer.clear();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
} // namespace sdi_toolBox::common::utils
|
||||
Reference in New Issue
Block a user