utils-lists 4.0.2
The µOS++ Intrusive Lists
Loading...
Searching...
No Matches
micro_os_plus::utils::static_double_list_links Class Reference

A class for the core of a statically allocated doubly linked list (pointers to neighbours). More...

#include <micro-os-plus/utils/lists.h>

+ Inheritance diagram for micro_os_plus::utils::static_double_list_links:

Public Types

using is_statically_allocated = std::true_type
 Type indicating that the links node is statically allocated.
 

Public Member Functions

constexpr static_double_list_links ()
 Construct a statically allocated list node (BSS initialised).
 
 static_double_list_links (const static_double_list_links &)=delete
 Deleted copy constructor.
 
 static_double_list_links (static_double_list_links &&)=delete
 Deleted move constructor.
 
constexpr ~static_double_list_links ()
 Destruct the node.
 
constexpr void initialize (void)
 Initialise the node links.
 
void initialize_once (void)
 Initialise the node links only if not already initialised.
 
void link_next (double_list_links_base *node)
 Link the new node as next.
 
void link_previous (double_list_links_base *node)
 Link the new node as previous.
 
bool linked (void) const
 Check if the node is linked to a doubly linked list.
 
constexpr double_list_links_basenext (void) const
 Get the link to the next node.
 
void nullify (void)
 Reset the two pointers to nullptr.
 
static_double_list_linksoperator= (const static_double_list_links &)=delete
 Deleted copy assignment operator.
 
static_double_list_linksoperator= (static_double_list_links &&)=delete
 Deleted move assignment operator.
 
constexpr double_list_links_baseprevious (void) const
 Get the link to the previous node.
 
bool uninitialized (void) const
 Check if the node is uninitialised.
 
void unlink (void)
 Remove this node from the list.
 

Protected Attributes

double_list_links_basenext_
 Pointer to the next node.
 
double_list_links_baseprevious_
 Pointer to the previous node.
 

Detailed Description

A class for the core of a statically allocated doubly linked list (pointers to neighbours).

The static_double_list_links class inherits a pair of uninitialised pointers to the next and previous list elements, as well as methods to access and manipulate these pointers, from its base class.

Instances of this class are intended to be statically allocated in the BSS section and automatically cleared (set to zero) during startup. This design enables reliable initialisation before any static constructors are executed, which is essential because the order of static initialisation is not defined by the C++ standard.

Statically allocated lists are commonly used by registrar objects to automate the self-registration of other statically allocated objects, such as drivers, threads, and similar components. By leveraging BSS initialisation, the registrar is guaranteed to be ready before any static objects attempt to register themselves.

As a consequence, list initialisation cannot be performed in the constructor, but must be done manually before invoking any method that adds elements to the list. This approach ensures robust and predictable behaviour in embedded and system-level applications where static object registration is required.

Definition at line 395 of file lists.h.

Member Typedef Documentation

◆ is_statically_allocated

Type indicating that the links node is statically allocated.

Definition at line 401 of file lists.h.

Constructor & Destructor Documentation

◆ static_double_list_links() [1/3]

micro_os_plus::utils::static_double_list_links::static_double_list_links ( )
constexpr

Construct a statically allocated list node (BSS initialised).

This constructor is intended for statically allocated list link nodes. It must be empty and must not modify the member pointers, leaving them unchanged. For statically allocated objects, the entire memory region is zero-initialised at startup (via BSS initialisation), so both previous_ and next_ pointers are set to nullptr, representing an uninitialised state.

This approach ensures that statically allocated lists are in a known, safe state before any constructors run, and avoids unnecessary writes or side effects during construction.

Warning
Code analysis tools may report:
  • Member previous_ was not initialized in constructor
  • Member next_ was not initialized in constructor These warnings are expected and can be safely ignored in this context.
The rule of five
The copy constructor, move constructor, copy assignment operator, and move assignment operator are explicitly deleted to prevent accidental copying or moving of intrusive_list objects. This ensures the integrity of the list structure, as duplicating or moving lists could result in invalid or inconsistent links within the list.

Definition at line 189 of file lists-inlines.h.

◆ static_double_list_links() [2/3]

micro_os_plus::utils::static_double_list_links::static_double_list_links ( const static_double_list_links & )
delete

Deleted copy constructor.

Copying of statically allocated list node objects is explicitly disallowed to prevent accidental duplication, which could compromise the integrity of the list structure.

◆ static_double_list_links() [3/3]

micro_os_plus::utils::static_double_list_links::static_double_list_links ( static_double_list_links && )
delete

Deleted move constructor.

Moving of statically allocated list node objects is explicitly disallowed to avoid invalid or inconsistent links within the list that could result from moving nodes.

◆ ~static_double_list_links()

micro_os_plus::utils::static_double_list_links::~static_double_list_links ( )
constexpr

Destruct the node.

The destructor for static_double_list_links is intentionally left empty to avoid modifying the member pointers. The goal is to revert the content to a state similar to the statically initialised state (BSS zero), but recent versions of GCC may optimize out any code that attempts to clear the pointers (dead store elimination).

As a result, explicit pointer clearing in the destructor is not reliable. If pointer reset is required, use the nullify() method explicitly, or clear the memory before invoking the placement new constructor again.

Warning
The code to clear the pointers is now commented out, since recent GCC optimizes it out (dead store elimination). Depending on the version, there might be some attributes to allow this, but they are not safe, for example __attribute__((optimize("no-lifetime-dse,no-dse,no-inline"))) did not help. The workaround is to use nullify() explicitly, or, even better, to clear the memory before invoking the placement new constructor again.

Definition at line 220 of file lists-inlines.h.

Member Function Documentation

◆ initialize()

void micro_os_plus::utils::double_list_links_base::initialize ( void )
constexprinherited

Initialise the node links.

Parameters
None.
Returns
Nothing.

Sets both the previous_ and next_ pointers to point to this node itself, marking the node as unlinked. This state is used to indicate that the node is not currently part of any list.

This method is called during initialisation and after a node is unlinked from a list, ensuring the node is in a safe, standalone state and cannot be traversed as part of a list.

Note
After unlinking a node from a list, it must be returned to this state to prevent accidental access through stale links.

Definition at line 113 of file lists-inlines.h.

◆ initialize_once()

void micro_os_plus::utils::double_list_links_base::initialize_once ( void )
inherited

Initialise the node links only if not already initialised.

Parameters
None.
Returns
Nothing.

If the statically allocated list is still in the initial uninitialised state (with both pointers nullptr), this method initialises the list to the empty state, with both pointers pointing to itself.

For non-statically initialised lists, this method is ineffective, since the node is always initialised at construct time.

Note
This method must be manually called for a statically allocated list before inserting elements or performing any other operations.

Definition at line 83 of file lists.cpp.

◆ link_next()

void micro_os_plus::utils::double_list_links_base::link_next ( double_list_links_base * node)
inherited

Link the new node as next.

Parameters
[in]nodePointer to the node to be linked as next.
Returns
Nothing.

Insert the new node between the next pointer and the node pointed by it. This operation is used by lists to link new nodes to the list head. The new node's previous_ pointer is set to the current node, and its next_ pointer is set to the current node's next_. The neighbouring nodes are updated to point to the new node, maintaining the integrity of the double-linked list.

Definition at line 101 of file lists.cpp.

◆ link_previous()

void micro_os_plus::utils::double_list_links_base::link_previous ( double_list_links_base * node)
inherited

Link the new node as previous.

Parameters
[in]nodePointer to the node to be linked as previous.
Returns
Nothing.

Insert the new node between the previous pointer and the node pointed by it. Used by lists to link new nodes to the list tail. The new node's next_ pointer is set to the current node, and its previous_ pointer is set to the current node's previous_. The neighbouring nodes are updated to point to the new node, maintaining the integrity of the double-linked list.

Definition at line 127 of file lists.cpp.

◆ linked()

bool micro_os_plus::utils::double_list_links_base::linked ( void ) const
inherited

Check if the node is linked to a doubly linked list.

Parameters
None.
Return values
trueThe node is linked with both pointers.
falseThe node is not linked.

To be linked, both pointers must point to different nodes than itself (double list requirement). If either next_ or previous_ points to this, the node is considered unlinked (empty state). This method checks the node's linkage status for safe list operations.

Definition at line 176 of file lists.cpp.

◆ next()

double_list_links_base * micro_os_plus::utils::double_list_links_base::next ( void ) const
constexprinherited

Get the link to the next node.

Parameters
None.
Return values
Pointerto the next node.

Returns a pointer to the next node in the list. If this node is the last in the list, the returned pointer may refer back to the list's sentinel node (for example, the links node in the list container) or to itself if the list is empty.

Note
The returned pointer is of type double_list_links_base* and may need to be cast to the appropriate derived type by the caller.

Definition at line 137 of file lists-inlines.h.

◆ nullify()

void micro_os_plus::utils::static_double_list_links::nullify ( void )

Reset the two pointers to nullptr.

Parameters
None.
Returns
Nothing.

Sets both the next_ and previous_ pointers to nullptr, marking the node as uninitialized. This is typically used for statically allocated nodes to explicitly place them in an uninitialized state.

Warning
Not very safe, since the compiler may optimise out the code.

Definition at line 203 of file lists.cpp.

◆ operator=() [1/2]

static_double_list_links & micro_os_plus::utils::static_double_list_links::operator= ( const static_double_list_links & )
delete

Deleted copy assignment operator.

Copy assignment is explicitly disallowed to prevent accidental overwriting of list node objects, which could lead to corruption of the list structure.

◆ operator=() [2/2]

static_double_list_links & micro_os_plus::utils::static_double_list_links::operator= ( static_double_list_links && )
delete

Deleted move assignment operator.

Move assignment is explicitly disallowed to avoid invalid or inconsistent links within the list that could result from moving nodes.

◆ previous()

double_list_links_base * micro_os_plus::utils::double_list_links_base::previous ( void ) const
constexprinherited

Get the link to the previous node.

Parameters
None.
Return values
Pointerto the previous node.

Returns a pointer to the previous node in the list. If this node is the first in the list, the returned pointer may refer back to the list's sentinel node (such as the links node in the list container) or to itself if the list is empty.

Note
The returned pointer is of type double_list_links_base* and may need to be cast to the appropriate derived type by the caller.

Definition at line 154 of file lists-inlines.h.

◆ uninitialized()

bool micro_os_plus::utils::double_list_links_base::uninitialized ( void ) const
inherited

Check if the node is uninitialised.

Parameters
None.
Return values
trueThe links are not initialised.
falseThe links are initialised.

An uninitialized node is a node with its pointers set to nullptr. Only statically allocated nodes in their initial state are considered uninitialized. Regular (dynamically or automatically allocated) nodes are always initialized during construction, so this method will only return true for statically allocated nodes that have not yet been initialized.

Definition at line 58 of file lists.cpp.

◆ unlink()

void micro_os_plus::utils::double_list_links_base::unlink ( void )
inherited

Remove this node from the list.

Parameters
None.
Returns
Nothing.

Update both neighbours to point to each other, effectively removing the node from the list. The node is then returned to the initial state (empty), with both pointers pointing to itself. This operation is safe to call even if the node is already unlinked.

Definition at line 151 of file lists.cpp.

Member Data Documentation

◆ next_

double_list_links_base* micro_os_plus::utils::double_list_links_base::next_
protectedinherited

Pointer to the next node.

Definition at line 273 of file lists.h.

◆ previous_

double_list_links_base* micro_os_plus::utils::double_list_links_base::previous_
protectedinherited

Pointer to the previous node.

Definition at line 268 of file lists.h.


The documentation for this class was generated from the following files: