ring

Overview

The estd::ring is a container similar to circular queue,that holds number of elements ordered in a FIFO (first-in-first-out) sequence. Elements are inserted at the back using a push operation and are deleted from the front using pop operation.

slice is used to manage the underlying memory, which is allocated for holding control variables and the remaining is dedicated to the ring buffer. If the provided memory is insufficient, it returns nullptr. Additionally, an assertion is triggered when the index passed to the at() function is out of the bounds.

Attempting to push an element when the ring is at maximum capacity will lead to overwriting the oldest element in the ring.

Usage

The usage constraints and guidelines apply for ring:

Constraints

Creation of ring with particular size should be within the maximum size limit.

Returns nullptr if attempt to create is made.

Usage guidance

Size of ring should be checked before accessing the elements.

Accessing outside the bounds of ring using at() function will result in assertion.

Example

ring is a container similar to circular queue.The operations are performed based on FIFO (First In First Out) principle.

Usage example to create and perform operation on ring:

// The array of size 1000 is created.
uint8_t mem[1000];
// The slice object is referencing to array named mem.
::estd::slice<uint8_t> s(mem);
// ring of size 5 is created from slice object.
::estd::ring<uint16_t>& r = *::estd::ring<uint16_t>::make(5, s);

// Checks whether the ring r is empty.
ASSERT_TRUE(r.empty());

// Checking the size of the ring.
EXPECT_EQ(5U, r.length());

// Pushing elements at the back of the ring using push_back() function.
r.push_back(10);
r.push_back(20);
r.push_back(30);

// Checks the number of used index of the ring.
EXPECT_EQ(3, r.used());

// Element at particular index is accessed using at() function.
EXPECT_EQ(10, r.at(0));
EXPECT_EQ(20, r.at(1));
EXPECT_EQ(30, r.at(2));

// The oldest or the front element can be accessed using front() function.
EXPECT_EQ(10, r.front());
// Popping front element from the ring.
r.pop_front();
// The front element will be 20 after pop_front().
ASSERT_EQ(20, r.front());
r.pop_front();
r.pop_front();
// 'r.empty()' returns true, since there are no elements in the ring.
EXPECT_TRUE(r.empty());

The following example shows that pushing an element into the full ring will overwrite the oldest element in the ring:

// The array of size 100 is created.
uint8_t mem[100];
// The slice object is referencing to array named mem.
::estd::slice<uint8_t> s(mem);
// ring of size 3 is created from slice object.
::estd::ring<uint16_t>& r = *::estd::ring<uint16_t>::make(3, s);

// Pushing elements at the back of the ring using push_back() function.
r.push_back(10);
r.push_back(20);
r.push_back(30);
EXPECT_EQ(10, r.at(0));
// Checks if the ring is full. It returns true, since ring is at maximum capacity.
EXPECT_TRUE(r.full());

// Pushing element to overwrite the ring.
r.push_back(40);

// Overwritten elements.
EXPECT_EQ(20, r.at(0));
EXPECT_EQ(30, r.at(1));
EXPECT_EQ(40, r.at(2));