13#ifndef MICRO_OS_PLUS_UTILS_LISTS_INLINES_H_
14#define MICRO_OS_PLUS_UTILS_LISTS_INLINES_H_
23#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Waggregate-return"
27#pragma clang diagnostic ignored "-Wc++98-compat"
85#pragma GCC diagnostic push
87#if defined(__GNUC__) && !defined(__clang__)
88#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
103#pragma GCC diagnostic pop
125#pragma GCC diagnostic push
127#if defined(__clang__)
128#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
139#pragma GCC diagnostic pop
164 template <
class T,
class N,
class U>
169 template <
class T,
class N,
class U>
177 template <
class T,
class N,
class U>
180 : node_{ &(element.*MP) }
182 static_assert (std::is_convertible<U, T>::value ==
true,
183 "U must be implicitly convertible to T!");
187 template <
class T,
class N,
class U>
191 return get_pointer ();
194 template <
class T,
class N,
class U>
198 return *get_pointer ();
201 template <
class T,
class N,
class U>
205 node_ =
static_cast<N*
> (node_->next ());
209 template <
class T,
class N,
class U>
213 const auto tmp = *
this;
218 template <
class T,
class N,
class U>
226 template <
class T,
class N,
class U>
230 const auto tmp = *
this;
235 template <
class T,
class N,
class U>
240 return node_ == other.
node_;
243 template <
class T,
class N,
class U>
248 return node_ != other.
node_;
251 template <
class T,
class N,
class U>
267 template <
class T,
class L>
270#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS_CONSTRUCT)
271 trace::printf (
"%s() @%p \n", __func__,
this);
274 if constexpr (is_statically_allocated::value)
295 template <
class T,
class L>
298#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS_CONSTRUCT)
299 trace::printf (
"%s() @%p \n", __func__,
this);
304#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS)
307 trace::printf (
"%s() @%p list not empty\n", __func__,
this);
320 template <
class T,
class L>
324 if constexpr (is_statically_allocated::value)
326 return links_.uninitialized ();
347 template <
class T,
class L>
351 if constexpr (is_statically_allocated::value)
353 links_.initialize_once ();
357 template <
class T,
class L>
362 return !links_.linked ();
369 template <
class T,
class L>
373#if defined(MICRO_OS_PLUS_TRACE_UTILS_LISTS)
374 trace::printf (
"%s() @%p\n", __func__,
this);
376 links_.initialize ();
379 template <
class T,
class L>
383 return reinterpret_cast<pointer> (links_.next ());
386 template <
class T,
class L>
390 return reinterpret_cast<pointer> (links_.previous ());
393 template <
class T,
class L>
397 if constexpr (is_statically_allocated::value)
399 assert (!links_.uninitialized ());
403 tail ()->link_next (&node);
406 template <
class T,
class L>
410 if constexpr (is_statically_allocated::value)
412 assert (!links_.uninitialized ());
416 head ()->link_previous (&node);
419 template <
class T,
class L>
423 if constexpr (is_statically_allocated::value)
425 assert (!links_.uninitialized ());
431 template <
class T,
class L>
444 template <
class T,
class N, N T::*MP,
class U>
450 template <
class T,
class N, N T::*MP,
class U>
457 template <
class T,
class N, N T::*MP,
class U>
460 : node_{ &(element.*MP) }
462 static_assert (std::is_convertible<U, T>::value ==
true,
463 "U must be implicitly convertible to T!");
466 template <
class T,
class N, N T::*MP,
class U>
470 return get_pointer ();
473 template <
class T,
class N, N T::*MP,
class U>
477 return *get_pointer ();
480 template <
class T,
class N, N T::*MP,
class U>
488 template <
class T,
class N, N T::*MP,
class U>
492 const auto tmp = *
this;
497 template <
class T,
class N, N T::*MP,
class U>
505 template <
class T,
class N, N T::*MP,
class U>
509 const auto tmp = *
this;
514 template <
class T,
class N, N T::*MP,
class U>
519 return node_ == other.
node_;
522 template <
class T,
class N, N T::*MP,
class U>
527 return node_ != other.
node_;
530 template <
class T,
class N, N T::*MP,
class U>
539 const auto offset =
reinterpret_cast<difference_type
> (
540 &(
static_cast<T*
> (
nullptr)->*MP));
544 return reinterpret_cast<pointer> (
reinterpret_cast<difference_type
> (node_)
548 template <
class T,
class N, N T::*MP,
class U>
557 template <
class T,
class N, N T::*MP,
class L,
class U>
562 template <
class T,
class N, N T::*MP,
class L,
class U>
580 template <
class T,
class N, N T::*MP,
class L,
class U>
587 template <
class T,
class N, N T::*MP,
class L,
class U>
594 template <
class T,
class N, N T::*MP,
class L,
class U>
602 const auto offset =
reinterpret_cast<difference_type
> (
603 &(
static_cast<T*
> (
nullptr)->*MP));
607 ->link_next (
reinterpret_cast<N*
> (
608 reinterpret_cast<difference_type
> (&node) + offset));
611 template <
class T,
class N, N T::*MP,
class L,
class U>
619 const auto offset =
reinterpret_cast<difference_type
> (
620 &(
static_cast<T*
> (
nullptr)->*MP));
624 ->link_previous (
reinterpret_cast<N*
> (
625 reinterpret_cast<difference_type
> (&node) + offset));
629#pragma GCC diagnostic push
630#pragma GCC diagnostic ignored "-Waggregate-return"
633 template <
class T,
class N, N T::*MP,
class L,
class U>
643 template <
class T,
class N, N T::*MP,
class L,
class U>
656#pragma GCC diagnostic pop
659 template <
class T,
class N, N T::*MP,
class L,
class U>
669 &(
static_cast<T*
> (
nullptr)->*MP));
677 template <
class T,
class N, N T::*MP,
class L,
class U>
688 return get_pointer (it);
691 template <
class T,
class N, N T::*MP,
class L,
class U>
702 return get_pointer (it);
709#pragma GCC diagnostic pop
A class template for a double linked list forward iterator.
constexpr bool operator==(const double_list_iterator &other) 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 double 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.
A class template for a double linked list of nodes.
void link_head(reference node)
Add a node to the head of the list.
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 double 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.
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--()
iterator_pointer node_
Pointer to intrusive node.
constexpr intrusive_list()
Construct an intrusive double 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.