12#ifndef MICRO_OS_PLUS_UTILS_LISTS_INLINES_H_
13#define MICRO_OS_PLUS_UTILS_LISTS_INLINES_H_
22#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Waggregate-return"
26#pragma clang diagnostic ignored "-Wc++98-compat"
84#pragma GCC diagnostic push
86#if defined(__GNUC__) && !defined(__clang__)
87#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
102#pragma GCC diagnostic pop
124#pragma GCC diagnostic push
126#if defined(__clang__)
127#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
138#pragma GCC diagnostic pop
163 template <
class T,
class N,
class U>
168 template <
class T,
class N,
class U>
176 template <
class T,
class N,
class U>
179 : node_{ &(element.*MP) }
181 static_assert (std::is_convertible<U, T>::value ==
true,
182 "U must be implicitly convertible to T!");
186 template <
class T,
class N,
class U>
193 template <
class T,
class N,
class U>
200 template <
class T,
class N,
class U>
208 template <
class T,
class N,
class U>
212 const auto tmp = *
this;
217 template <
class T,
class N,
class U>
225 template <
class T,
class N,
class U>
229 const auto tmp = *
this;
234 template <
class T,
class N,
class U>
242 template <
class T,
class N,
class U>
250 template <
class T,
class N,
class U>
266 template <
class T,
class L>
269#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS_CONSTRUCT)
270 trace::printf (
"%s() @%p \n", __func__,
this);
273 if constexpr (is_statically_allocated::value)
294 template <
class T,
class L>
297#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS_CONSTRUCT)
298 trace::printf (
"%s() @%p \n", __func__,
this);
303#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS)
306 trace::printf (
"%s() @%p list not empty\n", __func__,
this);
319 template <
class T,
class L>
323 if constexpr (is_statically_allocated::value)
325 return links_.uninitialized ();
346 template <
class T,
class L>
350 if constexpr (is_statically_allocated::value)
352 links_.initialize_once ();
356 template <
class T,
class L>
368 template <
class T,
class L>
372#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS)
373 trace::printf (
"%s() @%p\n", __func__,
this);
378 template <
class T,
class L>
385 template <
class T,
class L>
392 template <
class T,
class L>
396 if constexpr (is_statically_allocated::value)
398 assert (!
links_.uninitialized ());
402 tail ()->link_next (&node);
405 template <
class T,
class L>
409 if constexpr (is_statically_allocated::value)
411 assert (!links_.uninitialized ());
415 head ()->link_previous (&node);
418 template <
class T,
class L>
422 if constexpr (is_statically_allocated::value)
424 assert (!links_.uninitialized ());
430 template <
class T,
class L>
438 const_cast<links_type*
> (&links_)) };
443 template <
class T,
class N, N T::*MP,
class U>
449 template <
class T,
class N, N T::*MP,
class U>
456 template <
class T,
class N, N T::*MP,
class U>
459 :
node_{ &(element.*MP) }
461 static_assert (std::is_convertible<U, T>::value ==
true,
462 "U must be implicitly convertible to T!");
465 template <
class T,
class N, N T::*MP,
class U>
472 template <
class T,
class N, N T::*MP,
class U>
479 template <
class T,
class N, N T::*MP,
class U>
487 template <
class T,
class N, N T::*MP,
class U>
491 const auto tmp = *
this;
496 template <
class T,
class N, N T::*MP,
class U>
504 template <
class T,
class N, N T::*MP,
class U>
508 const auto tmp = *
this;
513 template <
class T,
class N, N T::*MP,
class U>
521 template <
class T,
class N, N T::*MP,
class U>
529 template <
class T,
class N, N T::*MP,
class U>
539 &(
static_cast<T*
> (
nullptr)->*MP));
547 template <
class T,
class N, N T::*MP,
class U>
556 template <
class T,
class N, N T::*MP,
class L,
class U>
561 template <
class T,
class N, N T::*MP,
class L,
class U>
579 template <
class T,
class N, N T::*MP,
class L,
class U>
586 template <
class T,
class N, N T::*MP,
class L,
class U>
593 template <
class T,
class N, N T::*MP,
class L,
class U>
602 &(
static_cast<T*
> (
nullptr)->*MP));
606 ->link_next (
reinterpret_cast<N*
> (
607 reinterpret_cast<difference_type
> (&node) + offset));
610 template <
class T,
class N, N T::*MP,
class L,
class U>
618 const auto offset =
reinterpret_cast<difference_type
> (
619 &(
static_cast<T*
> (
nullptr)->*MP));
623 ->link_previous (
reinterpret_cast<N*
> (
624 reinterpret_cast<difference_type
> (&node) + offset));
628#pragma GCC diagnostic push
629#pragma GCC diagnostic ignored "-Waggregate-return"
632 template <
class T,
class N, N T::*MP,
class L,
class U>
642 template <
class T,
class N, N T::*MP,
class L,
class U>
655#pragma GCC diagnostic pop
658 template <
class T,
class N, N T::*MP,
class L,
class U>
668 &(
static_cast<T*
> (
nullptr)->*MP));
676 template <
class T,
class N, N T::*MP,
class L,
class U>
690 template <
class T,
class N, N T::*MP,
class L,
class U>
708#pragma GCC diagnostic pop
A class template for a doubly linked list forward iterator.
constexpr bool operator==(const double_list_iterator &other) const
constexpr pointer get_pointer() const
constexpr pointer operator->() const
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
constexpr double_list_iterator & operator--()
constexpr bool operator!=(const double_list_iterator &other) const
constexpr iterator_pointer get_iterator_pointer() const
constexpr double_list_iterator & operator++()
constexpr reference operator*() const
value_type & reference
Type of reference to object "pointed to" by the iterator.
iterator_pointer node_
Pointer to the node.
constexpr double_list_iterator()
N * iterator_pointer
Type of reference to the iterator internal pointer.
A base class for a doubly linked list.
constexpr ~double_list_links_base()
Destruct the node.
double_list_links_base * previous_
Pointer to the previous node.
constexpr double_list_links_base()
Construct an uninitialised list node.
constexpr double_list_links_base * next(void) const
Get the link to the next node.
constexpr double_list_links_base * previous(void) const
Get the link to the previous node.
double_list_links_base * next_
Pointer to the next node.
constexpr void initialize(void)
Initialise the node links.
constexpr double_list_links()
Construct a list node (initialise the pointers).
constexpr ~double_list_links()
Destruct the node.
void link_head(reference node)
Add a node to the head of the list.
links_type links_
The list top node used to point to head and tail nodes.
L links_type
Type of the links node object where the pointers to the list head and tail are stored.
value_type * iterator_pointer
Type of reference to the iterator internal pointer.
constexpr pointer tail(void) const
Get the list tail.
void initialize_once(void)
Initialize the list only at first run.
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
constexpr const links_type * links_pointer() const
Get the address of the node storing the list links.
constexpr ~double_list()
Destruct the list.
value_type & reference
Type of reference to object "pointed to" by the iterator.
double_list()
Construct a doubly linked list.
void clear(void)
Clear the list.
constexpr pointer head(void) const
Get the list head.
iterator end() const
Iterator end.
iterator begin() const
Iterator begin.
double_list_iterator< value_type > iterator
Type of iterator over the values.
bool empty(void) const
Check if the list is empty.
void link_tail(reference node)
Add a node to the tail of the list.
bool uninitialized(void) const
Check if the list is uninitialised (only statically allocated can be).
A class template for an intrusive list iterator.
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
pointer get_pointer(void) const
Get the object node from the intrusive node.
intrusive_list_iterator & operator++()
N * iterator_pointer
Type of reference to the iterator internal pointer.
reference operator*() const
bool operator==(const intrusive_list_iterator &other) const
iterator_pointer get_iterator_pointer() const
value_type & reference
Type of reference to object "pointed to" by the iterator.
constexpr intrusive_list_iterator()
bool operator!=(const intrusive_list_iterator &other) const
pointer operator->() const
intrusive_list_iterator & operator--()
ptrdiff_t difference_type
Type of pointer difference.
iterator_pointer node_
Pointer to intrusive node.
constexpr intrusive_list()
Construct an intrusive doubly linked list.
constexpr bool empty(void) const
Check if the list is empty.
void link_tail(reference node)
Add a node to the tail of the list.
N * iterator_pointer
Type of reference to the iterator internal pointer.
iterator begin() const
Iterator begin.
pointer unlink_head(void)
Unlink the first element from the list.
void link_head(reference node)
Add a node to the head of the list.
constexpr ~intrusive_list()
Destruct the list.
intrusive_list_iterator< T, N, MP, U > iterator
Type of iterator over the values.
void initialize_once(void)
Initialize the list only at first run.
iterator end() const
Iterator begin.
ptrdiff_t difference_type
Type of pointer difference.
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
pointer unlink_tail(void)
Unlink the last element from the list.
pointer get_pointer(iterator_pointer node) const
Get the address of the node.
constexpr static_double_list_links()
Construct a statically allocated list node (bss initialised).
constexpr ~static_double_list_links()
Destruct the node.
µOS++ utility definitions.