mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-03 14:08:52 +08:00
IntrusiveQueue add remove method, iterators, and update test
This commit is contained in:
@@ -95,6 +95,58 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool remove(T removeNode)
|
||||||
|
{
|
||||||
|
// base case
|
||||||
|
if (removeNode == _head) {
|
||||||
|
if (_head->next_intrusive_queue_node() != nullptr) {
|
||||||
|
_head = _head->next_intrusive_queue_node();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_head = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (T node = _head; node != nullptr; node = node->next_intrusive_queue_node()) {
|
||||||
|
// is sibling the node to remove?
|
||||||
|
if (node->next_intrusive_queue_node() == removeNode) {
|
||||||
|
// replace sibling
|
||||||
|
if (node->next_intrusive_queue_node() != nullptr) {
|
||||||
|
node->set_next_intrusive_queue_node(node->next_intrusive_queue_node()->next_intrusive_queue_node());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
node->set_next_intrusive_queue_node(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Iterator {
|
||||||
|
T node;
|
||||||
|
Iterator(T v) : node(v) {}
|
||||||
|
|
||||||
|
operator T() const { return node; }
|
||||||
|
operator T &() { return node; }
|
||||||
|
T operator* () const { return node; }
|
||||||
|
Iterator &operator++ ()
|
||||||
|
{
|
||||||
|
if (node) {
|
||||||
|
node = node->next_intrusive_queue_node();
|
||||||
|
};
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Iterator begin() { return Iterator(_head); }
|
||||||
|
Iterator end() { return Iterator(nullptr); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
T _head{nullptr};
|
T _head{nullptr};
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public:
|
|||||||
bool test_push();
|
bool test_push();
|
||||||
bool test_pop();
|
bool test_pop();
|
||||||
bool test_push_duplicate();
|
bool test_push_duplicate();
|
||||||
|
bool test_remove();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ bool IntrusiveQueueTest::run_tests()
|
|||||||
ut_run_test(test_push);
|
ut_run_test(test_push);
|
||||||
ut_run_test(test_pop);
|
ut_run_test(test_pop);
|
||||||
ut_run_test(test_push_duplicate);
|
ut_run_test(test_push_duplicate);
|
||||||
|
ut_run_test(test_remove);
|
||||||
|
|
||||||
return (_tests_failed == 0);
|
return (_tests_failed == 0);
|
||||||
}
|
}
|
||||||
@@ -211,4 +213,59 @@ bool IntrusiveQueueTest::test_push_duplicate()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IntrusiveQueueTest::test_remove()
|
||||||
|
{
|
||||||
|
IntrusiveQueue<testContainer *> q1;
|
||||||
|
|
||||||
|
// size should be 0 initially
|
||||||
|
ut_compare("size initially 0", q1.size(), 0);
|
||||||
|
ut_assert_true(q1.empty());
|
||||||
|
|
||||||
|
// insert 100
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
testContainer *t = new testContainer();
|
||||||
|
t->i = i;
|
||||||
|
q1.push(t);
|
||||||
|
|
||||||
|
ut_compare("size increasing with i", q1.size(), i + 1);
|
||||||
|
ut_assert_true(!q1.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify full size (100)
|
||||||
|
ut_assert_true(q1.size() == 100);
|
||||||
|
|
||||||
|
// test removing elements
|
||||||
|
for (int remove_i = 0; remove_i < 100; remove_i++) {
|
||||||
|
|
||||||
|
// find node with i == remove_i
|
||||||
|
for (auto t : q1) {
|
||||||
|
if (t->i == remove_i) {
|
||||||
|
ut_assert_true(q1.remove(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate list again to verify removal
|
||||||
|
for (auto t : q1) {
|
||||||
|
ut_assert_true(t->i != remove_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
ut_assert_true(q1.size() == 100 - remove_i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// list should now be empty
|
||||||
|
ut_assert_true(q1.empty());
|
||||||
|
ut_compare("size 0", q1.size(), 0);
|
||||||
|
|
||||||
|
// delete all elements (should be safe on empty list)
|
||||||
|
while (!q1.empty()) {
|
||||||
|
q1.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify list has been cleared
|
||||||
|
ut_assert_true(q1.empty());
|
||||||
|
ut_compare("size 0", q1.size(), 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ut_declare_test_c(test_IntrusiveQueue, IntrusiveQueueTest)
|
ut_declare_test_c(test_IntrusiveQueue, IntrusiveQueueTest)
|
||||||
|
|||||||
Reference in New Issue
Block a user