25#ifndef MICRO_OS_PLUS_UTILS_LISTS_INLINES_H_
26#define MICRO_OS_PLUS_UTILS_LISTS_INLINES_H_
35#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Waggregate-return"
39#pragma clang diagnostic ignored "-Wc++98-compat"
97#pragma GCC diagnostic push
99#if defined(__GNUC__) && !defined(__clang__)
100#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
115#pragma GCC diagnostic pop
137#pragma GCC diagnostic push
139#if defined(__clang__)
140#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
154#pragma GCC diagnostic pop
179 template <
class T,
class N,
class U>
184 template <
class T,
class N,
class U>
192 template <
class T,
class N,
class U>
195 : node_{ &(element.*MP) }
197 static_assert (std::is_convertible<U, T>::value ==
true,
198 "U must be implicitly convertible to T!");
202 template <
class T,
class N,
class U>
209 template <
class T,
class N,
class U>
216 template <
class T,
class N,
class U>
224 template <
class T,
class N,
class U>
228 const auto tmp = *
this;
233 template <
class T,
class N,
class U>
241 template <
class T,
class N,
class U>
245 const auto tmp = *
this;
250 template <
class T,
class N,
class U>
258 template <
class T,
class N,
class U>
266 template <
class T,
class N,
class U>
282 template <
class T,
class L>
285#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS_CONSTRUCT)
286 trace::printf (
"%s() @%p \n", __func__,
this);
289 if constexpr (is_statically_allocated::value)
310 template <
class T,
class L>
313#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS_CONSTRUCT)
314 trace::printf (
"%s() @%p \n", __func__,
this);
319#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS)
322 trace::printf (
"%s() @%p list not empty\n", __func__,
this);
335 template <
class T,
class L>
339 if constexpr (is_statically_allocated::value)
341 return links_.uninitialized ();
362 template <
class T,
class L>
366 if constexpr (is_statically_allocated::value)
368 links_.initialize_once ();
372 template <
class T,
class L>
384 template <
class T,
class L>
388#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS)
389 trace::printf (
"%s() @%p\n", __func__,
this);
394 template <
class T,
class L>
401 template <
class T,
class L>
408 template <
class T,
class L>
412 if constexpr (is_statically_allocated::value)
414 assert (!
links_.uninitialized ());
418 tail ()->link_next (&node);
421 template <
class T,
class L>
425 if constexpr (is_statically_allocated::value)
427 assert (!links_.uninitialized ());
431 head ()->link_previous (&node);
434 template <
class T,
class L>
438 if constexpr (is_statically_allocated::value)
440 assert (!links_.uninitialized ());
443 return iterator{
static_cast<iterator_pointer
> (links_.next ()) };
446 template <
class T,
class L>
454 const_cast<links_type*
> (&links_)) };
459 template <
class T,
class N, N T::*MP,
class U>
465 template <
class T,
class N, N T::*MP,
class U>
472 template <
class T,
class N, N T::*MP,
class U>
475 :
node_{ &(element.*MP) }
477 static_assert (std::is_convertible<U, T>::value ==
true,
478 "U must be implicitly convertible to T!");
481 template <
class T,
class N, N T::*MP,
class U>
488 template <
class T,
class N, N T::*MP,
class U>
495 template <
class T,
class N, N T::*MP,
class U>
503 template <
class T,
class N, N T::*MP,
class U>
507 const auto tmp = *
this;
512 template <
class T,
class N, N T::*MP,
class U>
520 template <
class T,
class N, N T::*MP,
class U>
524 const auto tmp = *
this;
529 template <
class T,
class N, N T::*MP,
class U>
537 template <
class T,
class N, N T::*MP,
class U>
545 template <
class T,
class N, N T::*MP,
class U>
554 const auto offset =
reinterpret_cast<difference_type
> (
555 &(
static_cast<T*
> (
nullptr)->*MP));
559 return reinterpret_cast<pointer> (
reinterpret_cast<difference_type
> (node_)
563 template <
class T,
class N, N T::*MP,
class U>
572 template <
class T,
class N, N T::*MP,
class L,
class U>
577 template <
class T,
class N, N T::*MP,
class L,
class U>
595 template <
class T,
class N, N T::*MP,
class L,
class U>
602 template <
class T,
class N, N T::*MP,
class L,
class U>
609 template <
class T,
class N, N T::*MP,
class L,
class U>
617 const auto offset =
reinterpret_cast<difference_type
> (
618 &(
static_cast<T*
> (
nullptr)->*MP));
622 ->link_next (
reinterpret_cast<N*
> (
623 reinterpret_cast<difference_type
> (&node) + offset));
626 template <
class T,
class N, N T::*MP,
class L,
class U>
634 const auto offset =
reinterpret_cast<difference_type
> (
635 &(
static_cast<T*
> (
nullptr)->*MP));
639 ->link_previous (
reinterpret_cast<N*
> (
640 reinterpret_cast<difference_type
> (&node) + offset));
644#pragma GCC diagnostic push
645#pragma GCC diagnostic ignored "-Waggregate-return"
648 template <
class T,
class N, N T::*MP,
class L,
class U>
658 template <
class T,
class N, N T::*MP,
class L,
class U>
671#pragma GCC diagnostic pop
674 template <
class T,
class N, N T::*MP,
class L,
class U>
684 &(
static_cast<T*
> (
nullptr)->*MP));
692 template <
class T,
class N, N T::*MP,
class L,
class U>
706 template <
class T,
class N, N T::*MP,
class L,
class U>
724#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
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 lists can be uninitialised).
A class template for the 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--()
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.
The µOS++ utilities definitions.