[message] add range-based for loop for message/priority queue (#7481)

This commit adds support for range-based `for` loop iteration over
`MessageQueue` and `PriorityQueue`. It adds `ConstIterator` and
`Iterator` in `Message` class. The non-const `for` loop iteration
(which uses `Message::Iterator`) works properly and is safe to use
even when the entry is removed from the queue during iteration. This
commit updates other core modules to use the new `for` loop iteration
model which helps simplify the code. It also updates the unit tests
to validate the behavior of the newly added iteration mechanisms.
This commit is contained in:
Abtin Keshavarzian
2022-03-21 09:28:12 -07:00
committed by GitHub
parent c24e5dd6c4
commit 237c91b939
16 changed files with 503 additions and 250 deletions
+70 -4
View File
@@ -46,9 +46,10 @@ static ot::MessagePool *sMessagePool;
// This function verifies the content of the message queue to match the passed in messages
void VerifyMessageQueueContent(ot::MessageQueue &aMessageQueue, int aExpectedLength, ...)
{
va_list args;
ot::Message *message;
ot::Message *msgArg;
const ot::MessageQueue &constQueue = aMessageQueue;
va_list args;
ot::Message * message;
ot::Message * msgArg;
va_start(args, aExpectedLength);
@@ -69,10 +70,34 @@ void VerifyMessageQueueContent(ot::MessageQueue &aMessageQueue, int aExpectedLen
aExpectedLength--;
}
VerifyOrQuit(aExpectedLength == 0, "less entries than expected");
VerifyOrQuit(aExpectedLength == 0, "fewer entries than expected");
}
va_end(args);
// Check range-based `for` loop iteration using non-const iterator
message = aMessageQueue.GetHead();
for (ot::Message &msg : aMessageQueue)
{
VerifyOrQuit(message == &msg, "`for` loop iteration does not match expected");
message = message->GetNext();
}
VerifyOrQuit(message == nullptr, "`for` loop iteration resulted in fewer entries than expected");
// Check range-base `for` iteration using const iterator
message = aMessageQueue.GetHead();
for (const ot::Message &constMsg : constQueue)
{
VerifyOrQuit(message == &constMsg, "`for` loop iteration does not match expected");
message = message->GetNext();
}
VerifyOrQuit(message == nullptr, "`for` loop iteration resulted in fewer entries than expected");
}
void TestMessageQueue(void)
@@ -174,6 +199,47 @@ void TestMessageQueue(void)
messageQueue.Dequeue(*messages[0]);
VerifyMessageQueueContent(messageQueue, 0);
// Range-based `for` and dequeue during iteration
for (uint16_t removeIndex = 0; removeIndex < 5; removeIndex++)
{
uint16_t index = 0;
messageQueue.Enqueue(*messages[0]);
messageQueue.Enqueue(*messages[1]);
messageQueue.Enqueue(*messages[2]);
messageQueue.Enqueue(*messages[3]);
messageQueue.Enqueue(*messages[4]);
VerifyMessageQueueContent(messageQueue, 5, messages[0], messages[1], messages[2], messages[3], messages[4]);
// While iterating over the queue remove the entry at `removeIndex`
for (ot::Message &message : messageQueue)
{
if (index == removeIndex)
{
messageQueue.Dequeue(message);
}
VerifyOrQuit(&message == messages[index++]);
}
index = 0;
// Iterate over the queue and remove all
for (ot::Message &message : messageQueue)
{
if (index == removeIndex)
{
index++;
}
VerifyOrQuit(&message == messages[index++]);
messageQueue.Dequeue(message);
}
VerifyMessageQueueContent(messageQueue, 0);
}
testFreeInstance(sInstance);
}