utils-lists 4.0.0
µOS++ C++ intrusive lists utilities
Loading...
Searching...
No Matches
lists.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus/)
4 * Copyright (c) 2016 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/MIT/.
11 */
12
13/*
14 * This library implements several double linked lists, used by some
15 * µOS++ components to keep track of internal objects; however it is
16 * generic enough to be useful in other applications too, thus packing
17 * it as a separate library.
18 *
19 * The main differentiator from `std::list` is that the implementation
20 * does not require dynamic memory allocation for the list links,
21 * hence it does not need an allocator.
22 *
23 * Instead, it uses intrusive lists, which store the links inside the
24 * list elements.
25 *
26 * Another specific feature is statically initialised lists.
27 *
28 * These are lists created in the global scope which do not change the
29 * content of any of their members in the constructors; instead,
30 * they are fully initialized by setting the entire content to zero
31 * during startup (via BSS init).
32 *
33 * This allows other static objects to auto-register themselves to
34 * static registrar objects. This requires the registrar to be
35 * initialised before the clients need to register; since the order
36 * of static constructors is not defined, the only solution that
37 * guarantees this is to initialize the registrar during startup
38 * (via BSS init) before the static constructors.
39 */
40
41#ifndef MICRO_OS_PLUS_UTILS_LISTS_H_
42#define MICRO_OS_PLUS_UTILS_LISTS_H_
43
44// ----------------------------------------------------------------------------
45
46#ifdef __cplusplus
47
48// ----------------------------------------------------------------------------
49
50#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
51#include <micro-os-plus/config.h>
52#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
53
54#include <cstdint>
55#include <cstddef>
56#include <cassert>
57#include <iterator>
58
59// ----------------------------------------------------------------------------
60
61#if defined(__GNUC__)
62#pragma GCC diagnostic push
63
64#pragma GCC diagnostic ignored "-Waggregate-return"
65#if defined(__clang__)
66#pragma clang diagnostic ignored "-Wc++98-compat"
67#endif
68#endif
69
74{
75 // ==========================================================================
76
93 {
94 public:
98 constexpr double_list_links_base ();
99
104 // The rule of five.
108 operator= (const double_list_links_base&)
109 = delete;
111 operator= (double_list_links_base&&)
112 = delete;
113
121 constexpr ~double_list_links_base ();
122
130 bool
131 uninitialized (void) const;
132
140 constexpr void
141 initialize (void);
142
150 void
151 initialize_once (void);
152
160 void
162
170 void
172
178 void
179 unlink (void);
180
186 bool
187 linked (void) const;
188
193 constexpr double_list_links_base*
194 next (void) const;
195
200 constexpr double_list_links_base*
201 previous (void) const;
202
203 protected:
208
213 };
214
215 // ==========================================================================
216
233 {
234 public:
239 using is_statically_allocated = std::false_type;
240
244 constexpr double_list_links ();
245
250 // The rule of five.
251 double_list_links (const double_list_links&) = delete;
254 operator= (const double_list_links&)
255 = delete;
257 operator= (double_list_links&&)
258 = delete;
259
267 constexpr ~double_list_links ();
268 };
269
270 // ==========================================================================
271
307 {
308 public:
312 using is_statically_allocated = std::true_type;
313
318 constexpr static_double_list_links ();
319
324 // The rule of five.
328 operator= (const static_double_list_links&)
329 = delete;
331 operator= (static_double_list_links&&)
332 = delete;
333
341 constexpr ~static_double_list_links ();
342
350 void
351 nullify (void);
352 };
353
354 // ==========================================================================
355
371 template <class T, class N = T, class U = T>
373 {
374 public:
378 using value_type = U;
379
384
389
394
398 using difference_type = ptrdiff_t;
399
403 using iterator_category = std::forward_iterator_tag;
404
405 // ------------------------------------------------------------------------
406 constexpr double_list_iterator ();
407
408 constexpr explicit double_list_iterator (iterator_pointer const node);
409
410 constexpr explicit double_list_iterator (reference element);
411
412 // DO NOT delete the copy constructors, since the default one are
413 // used.
414
415 constexpr pointer
416 operator->() const;
417
418 constexpr reference
419 operator* () const;
420
421 constexpr double_list_iterator&
422 operator++ ();
423
424 constexpr double_list_iterator
425 operator++ (int);
426
427 constexpr double_list_iterator&
428 operator-- ();
429
430 constexpr double_list_iterator
431 operator-- (int);
432
433 constexpr bool
434 operator== (const double_list_iterator& other) const;
435
436 constexpr bool
437 operator!= (const double_list_iterator& other) const;
438
439 constexpr pointer
440 get_pointer () const;
441
442 constexpr iterator_pointer
443 get_iterator_pointer () const;
444
445 protected:
450 };
451
452 // ==========================================================================
453
485 template <class T, class L = double_list_links>
487 {
488 public:
489 static_assert (std::is_base_of<double_list_links_base, L>::value == true,
490 "L must be derived from double_list_links_base!");
491 static_assert (std::is_base_of<double_list_links_base, T>::value == true,
492 "T must be derived from double_list_links_base!");
493
498 using links_type = L;
499
503 using value_type = T;
504
509
514
519
524
529 typename links_type::is_statically_allocated;
530
534 double_list ();
535
540 // The rule of five.
541 double_list (const double_list&) = delete;
542 double_list (double_list&&) = delete;
544 operator= (const double_list&)
545 = delete;
547 operator= (double_list&&)
548 = delete;
549
557 constexpr ~double_list ();
558
559 public:
568 bool
569 uninitialized (void) const;
570
578 void
579 initialize_once (void);
580
588 bool
589 empty (void) const;
590
598 void
599 clear (void);
600
607 constexpr pointer
608 head (void) const;
609
616 constexpr pointer
617 tail (void) const;
618
622 void
623 link_tail (reference node);
624
628 void
629 link_head (reference node);
630
631 // ------------------------------------------------------------------------
632
638 begin () const;
639
645 end () const;
646
647 // Required in derived class iterator end(), where direct
648 // access to member fails.
653 constexpr const links_type*
655 {
656 return &links_;
657 }
658
659 // ------------------------------------------------------------------------
660
661 protected:
674 };
675
676 // ==========================================================================
677
694 template <class T, class N, N T::*MP, class U = T>
696 {
697 public:
701 using value_type = U;
702
707
712
717
721 using difference_type = ptrdiff_t;
722
726 using iterator_category = std::forward_iterator_tag;
727
728 // ------------------------------------------------------------------------
729 constexpr intrusive_list_iterator ();
730
731 constexpr explicit intrusive_list_iterator (iterator_pointer const node);
732
733 constexpr explicit intrusive_list_iterator (reference element);
734
735 // DO NOT delete the copy constructors, since the default one are
736 // used.
737
738 pointer
739 operator->() const;
740
742 operator* () const;
743
745 operator++ ();
746
748 operator++ (int);
749
751 operator-- ();
752
754 operator-- (int);
755
756 bool
757 operator== (const intrusive_list_iterator& other) const;
758
759 bool
760 operator!= (const intrusive_list_iterator& other) const;
761
766 pointer
767 get_pointer (void) const;
768
770 get_iterator_pointer () const;
771
772 protected:
777 };
778
779 // ==========================================================================
780
816 template <class T, class N, N T::*MP, class L = double_list_links,
817 class U = T>
818 class intrusive_list : public double_list<N, L>
819 {
820 public:
821 static_assert (std::is_base_of<double_list_links_base, L>::value == true,
822 "L must be derived from double_list_links_base!");
823 static_assert (std::is_base_of<double_list_links_base, N>::value == true,
824 "N must be derived from double_list_links_base!");
825
830 using links_type = L;
831
835 using value_type = U;
836
841
846
851
856 typename links_type::is_statically_allocated;
857
862
866 using difference_type = ptrdiff_t;
867
871 constexpr intrusive_list ();
872
877 // The rule of five.
878 intrusive_list (const intrusive_list&) = delete;
879 intrusive_list (intrusive_list&&) = delete;
881 operator= (const intrusive_list&)
882 = delete;
884 operator= (intrusive_list&&)
885 = delete;
886
894 constexpr ~intrusive_list ();
895
896 public:
904 void
905 initialize_once (void);
906
914 constexpr bool
915 empty (void) const;
916
923 void
924 link_tail (reference node);
925
932 void
933 link_head (reference node);
934
939 pointer
940 unlink_tail (void);
941
946 pointer
947 unlink_head (void);
948
949 // ------------------------------------------------------------------------
950
956 begin () const;
957
963 end () const;
964
965 // ------------------------------------------------------------------------
966 protected:
971 pointer
972 get_pointer (iterator_pointer node) const;
973 };
974
975 // --------------------------------------------------------------------------
976} // namespace micro_os_plus::utils
977
978#if defined(__GNUC__)
979#pragma GCC diagnostic pop
980#endif
981
982// ----------------------------------------------------------------------------
983
984#endif // __cplusplus
985
986// ===== Inline & template implementations ====================================
987
988// All other inlines.
989#include "inlines.h"
990
991// ----------------------------------------------------------------------------
992
993#endif // MICRO_OS_PLUS_UTILS_LISTS_H_
994
995// ----------------------------------------------------------------------------
A class template for a double linked list forward iterator.
Definition lists.h:373
constexpr double_list_iterator(reference element)
ptrdiff_t difference_type
Type of pointer difference.
Definition lists.h:398
constexpr bool operator==(const double_list_iterator &other) const
Definition inlines.h:237
constexpr pointer get_pointer() const
constexpr pointer operator->() const
Definition inlines.h:189
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
Definition lists.h:383
constexpr double_list_iterator & operator--()
Definition inlines.h:220
constexpr bool operator!=(const double_list_iterator &other) const
Definition inlines.h:245
std::forward_iterator_tag iterator_category
Category of iterator.
Definition lists.h:403
constexpr iterator_pointer get_iterator_pointer() const
Definition inlines.h:253
constexpr double_list_iterator & operator++()
Definition inlines.h:203
constexpr reference operator*() const
Definition inlines.h:196
value_type & reference
Type of reference to object "pointed to" by the iterator.
Definition lists.h:388
iterator_pointer node_
Pointer to the node.
Definition lists.h:449
U value_type
Type of value "pointed to" by the iterator.
Definition lists.h:378
N * iterator_pointer
Type of reference to the iterator internal pointer.
Definition lists.h:393
A class template for a double linked list of nodes.
Definition lists.h:487
void link_head(reference node)
Add a node to the head of the list.
Definition inlines.h:408
links_type links_
The list top node used to point to head and tail nodes.
Definition lists.h:673
L links_type
Type of the links node object where the pointers to the list head and tail are stored.
Definition lists.h:498
value_type * iterator_pointer
Type of reference to the iterator internal pointer.
Definition lists.h:523
constexpr pointer tail(void) const
Get the list tail.
Definition inlines.h:388
void initialize_once(void)
Initialize the list only at first run.
Definition inlines.h:349
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
Definition lists.h:508
constexpr const links_type * links_pointer() const
Get the address of the node storing the list links.
Definition lists.h:654
constexpr ~double_list()
Destruct the list.
Definition inlines.h:296
value_type & reference
Type of reference to object "pointed to" by the iterator.
Definition lists.h:513
double_list()
Construct a double linked list.
Definition inlines.h:268
void clear(void)
Clear the list.
Definition inlines.h:371
constexpr pointer head(void) const
Get the list head.
Definition inlines.h:381
iterator end() const
Iterator end.
Definition inlines.h:433
T value_type
Type of value "pointed to" by the iterator.
Definition lists.h:503
iterator begin() const
Iterator begin.
Definition inlines.h:421
bool empty(void) const
Check if the list is empty.
Definition inlines.h:359
void link_tail(reference node)
Add a node to the tail of the list.
Definition inlines.h:395
bool uninitialized(void) const
Check if the list is uninitialised (only statically allocated can be).
Definition inlines.h:322
typename links_type::is_statically_allocated is_statically_allocated
Type indicating that the links node is statically allocated.
Definition lists.h:528
A class template for an intrusive list iterator.
Definition lists.h:696
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
Definition lists.h:706
std::forward_iterator_tag iterator_category
Category of iterator.
Definition lists.h:726
pointer get_pointer(void) const
Get the object node from the intrusive node.
Definition inlines.h:532
intrusive_list_iterator & operator++()
Definition inlines.h:482
N * iterator_pointer
Type of reference to the iterator internal pointer.
Definition lists.h:716
bool operator==(const intrusive_list_iterator &other) const
Definition inlines.h:516
iterator_pointer get_iterator_pointer() const
Definition inlines.h:550
value_type & reference
Type of reference to object "pointed to" by the iterator.
Definition lists.h:711
bool operator!=(const intrusive_list_iterator &other) const
Definition inlines.h:524
U value_type
Type of value "pointed to" by the iterator.
Definition lists.h:701
intrusive_list_iterator & operator--()
Definition inlines.h:499
ptrdiff_t difference_type
Type of pointer difference.
Definition lists.h:721
iterator_pointer node_
Pointer to intrusive node.
Definition lists.h:776
A class template for a list of nodes which store the links inside themselves as intrusive nodes.
Definition lists.h:819
constexpr intrusive_list()
Construct an intrusive double linked list.
Definition inlines.h:558
L links_type
Type of the list links node object where the pointers to the list head and tail are stored.
Definition lists.h:830
constexpr bool empty(void) const
Check if the list is empty.
Definition inlines.h:589
void link_tail(reference node)
Add a node to the tail of the list.
Definition inlines.h:596
N * iterator_pointer
Type of reference to the iterator internal pointer.
Definition lists.h:861
iterator begin() const
Iterator begin.
Definition inlines.h:635
typename links_type::is_statically_allocated is_statically_allocated
Type of reference to the iterator internal pointer.
Definition lists.h:855
pointer unlink_head(void)
Unlink the first element from the list.
Definition inlines.h:679
void link_head(reference node)
Add a node to the head of the list.
Definition inlines.h:613
constexpr ~intrusive_list()
Destruct the list.
Definition inlines.h:563
void initialize_once(void)
Initialize the list only at first run.
Definition inlines.h:582
U value_type
Type of value "pointed to" by the iterator.
Definition lists.h:835
iterator end() const
Iterator begin.
Definition inlines.h:645
value_type & reference
Type of reference to object "pointed to" by the iterator.
Definition lists.h:845
ptrdiff_t difference_type
Type of pointer difference.
Definition lists.h:866
value_type * pointer
Type of pointer to object "pointed to" by the iterator.
Definition lists.h:840
pointer unlink_tail(void)
Unlink the last element from the list.
Definition inlines.h:693
pointer get_pointer(iterator_pointer node) const
Get the address of the node.
Definition inlines.h:661
µOS++ utility definitions.
Definition inlines.h:34