55 template <
class T>
static inline
56 void add(T*& list, T* item) {
62 template <
class T>
static inline
71 template <
class T>
static inline
78 template <
class T>
static inline
82 if (ptr == item)
return true;
91 template <
class T>
static inline
95 if (*ptr == item)
return ptr;
96 if (*ptr == 0)
return 0;
97 ptr = &((*ptr)->m_next);
103 template <
class T>
static inline
106 while (ptr && idx--) {
114 template <
class T>
static inline
116 if (!list)
return false;
117 const T* slow = list;
118 const T* fast = list->m_next;
119 while (fast && fast->m_next) {
120 if (slow == fast || slow == fast->m_next)
return true;
122 fast = fast->m_next->m_next;
128 template <
class T>
static inline
131 item->m_next = where->m_next;
132 where->m_next = item;
137 template <
class T>
static inline
138 unsigned len(
const T* list) {
150 template <
class T>
static inline
156 template <
class T>
static inline
166 template <
class T>
static inline
173 template <
class T>
static inline
175 T** ptr = satcat5::util::ListCore::find_ptr<T>(&list, 0);
181 template <
class T>
static inline
183 T** ptr = satcat5::util::ListCore::find_ptr<T>(&list, item);
184 if (ptr) *ptr = item->m_next;
189 template <
class T>
static inline
192 if (item) item->m_next = 0;
199 template <
class T>
static inline
201 bool adj = (list != item) || (item && list->m_next);
202 if (adj)
reset(list, item);
210 template <
class T>
class List final {
214 constexpr
explicit List(T* item)
218 T* head()
const {
return m_head;}
257 inline unsigned len()
const
261 inline T*
next(
const T* item)
const
Helper functions for manipulating singly-linked lists.
static bool contains(const T *list, const T *item)
Scan the list, looking for the item in question.
static void push_back(T *&list, T *item)
Add a new item at the tail of the list.
static void reset(T *&list, T *item)
Discard list contents and reset to empty or a single item.
static T * get_index(T *list, unsigned idx)
Fetch the Nth item from the linked list.
static void add_list(T *&list1, T *&list2)
Add each item from "list2" onto "list1", destroying "list2".
static void remove(T *&list, T *item)
Remove the designated item from the list.
static T ** find_ptr(T **list, const T *item)
Find the link pointing to the designated item.
static T * pop_front(T *&list)
Remove the item at the head of the list.
static void add(T *&list, T *item)
Add new item to front or back, whichever is simpler.
static bool has_loop(const T *list)
Check if the linked list loops back on itself, using the two-pointer "tortoise and hare" algorithm.
static bool pre_test_reset(T *&list, T *item)
Check if a list contains exactly the specified item.
static void add_safe(T *&list, T *item)
Check if list already contains item before adding.
static void insert_after(T *where, T *item)
Insert a new item just after the designated position.
static T * next(const T *item)
Fetch pointer to the next item.
static unsigned len(const T *list)
Traverse the linked list to count its length.
static void push_front(T *&list, T *item)
Add a new item at the head of the list.
Templated linked-list class.
unsigned len() const
Traverse the linked list to count its length.
void add_list(satcat5::util::List< T > &other)
Add each item from "list2" onto "list1", destroying "list2".
constexpr List()
Construct an empty list.
T * next(const T *item) const
Fetch pointer to the next item.
~List()
Destructor requires no action.
void push_back(T *item)
Add a new item at the tail of the list.
constexpr List(T *item)
Construct list with one item.
T * get_index(unsigned idx)
Fetch the Nth item from the linked list.
void add_safe(T *item)
Check if list already contains item before adding.
void reset(T *item=0)
Discard list contents and reset to empty or a single item.
bool contains(const T *item) const
Scan the list, looking for the item in question.
bool has_loop() const
Check if the linked list loops back on itself, using the two-pointer "tortoise and hare" algorithm.
void insert_after(T *where, T *item)
Insert a new item just after the designated position.
void add(T *item)
Add new item to front or back, whichever is simpler.
bool is_empty() const
Is this list empty?
T * pop_front()
Remove the item at the head of the list.
void remove(T *item)
Remove the designated item from the list.
T * m_head
Pointer to first item, zero if empty.
void push_front(T *item)
Add a new item at the head of the list.