simplify Qeue, update some comments and include paths

This commit is contained in:
Niklas Gollenstede
2025-05-26 18:21:22 +02:00
committed by Eggert Jung
parent 68e11c9793
commit d9978ddc37
13 changed files with 55 additions and 93 deletions

View File

@@ -11,39 +11,16 @@
/*! \brief Templated Queue for arbitrary objects.
*
* Queue is implemented by a head-object (Queue<T>) and next-pointers embedded
* in the queued objects. This Queue supports arrays of next-pointers by passing
* an index into the constructor identifying the index into the next-pointer
* array. By passing a different get_link function into the constructor, the
* member name of the next-pointer array can be changed and objects can be
* contained in different independent queues.
* in the queued objects. By passing a different get_link function into the
* constructor, the member name of the next-pointer can be changed and objects
* can be contained in different independent queues.
*/
template <class T>
class Queue {
/*! \brief Default get_link implementation returns a pointer to the
* link_index'th element of the next-pointer array.
* The function assumes a member named "queue_link" that stores the
* next-pointer.
*
* If your object contains a queue_link member you can just ignore this
* function and the get_link keyword argument of the constructor.
*
* \param[in] obj the object whose link should be accessed.
* \param[in] link_index the index within the array.
*
* \return A pointer to the next-object pointer.
*/
static T** default_get_link(T& obj, unsigned link_index) {
assert(link_index < sizeof(T::queue_link) / sizeof(void*));
return &obj.queue_link[link_index];
}
/// Default get_link implementation returns a pointer to the next-pointer.
static T** default_get_link(T& obj) { return &obj.queue_link; }
/// Type definition for the get_link function
typedef T** (*NextFunc)(T&, unsigned);
/// Queue-local index into the next-pointer array
unsigned link_index;
/// Provides the same signature for single- and multi-core Queue
T** get_link_wrapped(T& obj) { return get_link(obj, link_index); }
typedef T** (*NextFunc)(T&);
/// Function pointer to the get_link function, called whenever the
/// next pointer array is referenced
@@ -106,18 +83,15 @@ class Queue {
constexpr Queue(Queue&&) = default;
/*! \brief Constructor
* \param[in] link_index denotes the index into the next-pointer array
* to be used by this
*queue-object
* \param[in] get_link A function pointer to the get_link, i.e. a function
* which returns a pointer to the
*next-pointer of an element in the Queue.
*/
explicit Queue(unsigned link_index, NextFunc get_link = default_get_link)
: link_index(link_index),
get_link(get_link),
head(nullptr),
tail(nullptr) {}
explicit Queue(NextFunc get_link = default_get_link)
: get_link(get_link), head(nullptr), tail(nullptr) {
assert(get_link != nullptr &&
"get_link function pointer must not be nullptr!");
};
/*! \brief Enqueues the provided item at the end of the queue. If the element
* is already contained in the queue, false will be returned
@@ -126,7 +100,7 @@ class Queue {
* or not (and it is now enqueued, then true)
*/
bool enqueue(T& item) {
T** nextptr = get_link_wrapped(item);
T** nextptr = get_link(item);
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
return false;
}
@@ -136,7 +110,7 @@ class Queue {
head = tail = &item;
} else {
assert(tail != nullptr);
*get_link_wrapped(*tail) = &item;
*get_link(*tail) = &item;
tail = &item;
}
return true;
@@ -147,7 +121,7 @@ class Queue {
* \return true if successful, false if item was already in the queue
**/
bool insertFirst(T& item) {
T** nextptr = get_link_wrapped(item);
T** nextptr = get_link(item);
if (*nextptr != nullptr || (head != nullptr && tail == &item)) {
return false;
}
@@ -177,13 +151,13 @@ class Queue {
if (&after == tail) {
return enqueue(item);
}
T** nextptr = get_link_wrapped(item);
T** nextptr = get_link(item);
// if item is already in the list return false
if (*nextptr != nullptr || tail == &item) {
return false;
}
T** pnextptr = get_link_wrapped(after);
T** pnextptr = get_link(after);
// if after is NOT in the list, return false
if (!(pnextptr != nullptr || tail == &after)) {
return false;
@@ -201,8 +175,7 @@ class Queue {
*not in this list
**/
T* next(T& item) {
T** nextptr = get_link_wrapped(item);
// if item is already in the list return nullptr
T** nextptr = get_link(item);
if (head == nullptr || (*nextptr == nullptr && tail != &item)) {
return nullptr;
}
@@ -222,7 +195,7 @@ class Queue {
T* dequeue() {
T* out = head;
if (head != nullptr) {
T** nextptr = get_link_wrapped(*head);
T** nextptr = get_link(*head);
head = *nextptr;
*nextptr = nullptr;
}
@@ -239,21 +212,21 @@ class Queue {
T** next_link;
if (head == that) {
head = *get_link_wrapped(*head);
head = *get_link(*head);
*get_link_wrapped(*that) = nullptr;
*get_link(*that) = nullptr;
return that;
}
while (cur) {
next_link = get_link_wrapped(*cur);
next_link = get_link(*cur);
if (*next_link == that) {
*next_link = *get_link_wrapped(**next_link);
*next_link = *get_link(**next_link);
if (that == tail) {
tail = cur;
}
*get_link_wrapped(*that) = nullptr;
*get_link(*that) = nullptr;
return that;
}
cur = *next_link;