31 #ifndef ETL_INTRUSIVE_LINKS_INCLUDED
32 #define ETL_INTRUSIVE_LINKS_INCLUDED
68 link_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
69 :
exception(reason_, file_name_, line_number_)
82 :
link_exception(ETL_ERROR_TEXT(
"link:still linked", ETL_FILE
"A"), file_name_, line_number_)
90 template <const
size_t ID_>
100 etl_next = ETL_NULLPTR;
103 bool is_linked()
const
105 return etl_next != ETL_NULLPTR;
112 template <
typename TLink>
114 link(TLink& lhs, TLink& rhs)
120 template <
typename TLink>
122 link_splice(TLink& lhs, TLink& rhs)
124 rhs.etl_next = lhs.etl_next;
129 template <
typename TLink>
131 link(TLink* lhs, TLink* rhs)
133 if (lhs != ETL_NULLPTR)
140 template <
typename TLink>
142 link_splice(TLink* lhs, TLink* rhs)
144 if (lhs != ETL_NULLPTR)
146 if (rhs != ETL_NULLPTR)
148 rhs->etl_next = lhs->etl_next;
156 template <
typename TLink>
158 link(TLink& lhs, TLink* rhs)
164 template <
typename TLink>
166 link_splice(TLink& lhs, TLink* rhs)
168 if (rhs != ETL_NULLPTR)
170 rhs->etl_next = lhs.etl_next;
177 template <
typename TLink>
179 link(TLink* lhs, TLink& rhs)
181 if (lhs != ETL_NULLPTR)
183 lhs->etl_next = &rhs;
188 template <
typename TLink>
190 link_splice(TLink* lhs, TLink& rhs)
192 if (lhs != ETL_NULLPTR)
194 rhs.etl_next = lhs->etl_next;
195 lhs->etl_next = &rhs;
200 template <
typename TLink>
202 link_splice(TLink& lhs, TLink& first, TLink& last)
204 last.etl_next = lhs.etl_next;
205 lhs.etl_next = &first;
209 template <
typename TLink>
211 link_splice(TLink* lhs, TLink& first, TLink& last)
213 if (lhs != ETL_NULLPTR)
215 last.etl_next = lhs->etl_next;
216 lhs->etl_next = &first;
220 last.etl_next = ETL_NULLPTR;
225 template <
typename TLink>
227 unlink_after(TLink& node)
229 if (node.etl_next != ETL_NULLPTR)
231 TLink* unlinked_node = node.etl_next;
232 node.etl_next = unlinked_node->etl_next;
237 template <
typename TLink>
239 unlink_after(TLink& before, TLink& last)
241 before.etl_next = last.etl_next;
247 template <const
size_t ID_>
257 etl_previous = ETL_NULLPTR;
258 etl_next = ETL_NULLPTR;
261 bool is_linked()
const
263 return (etl_previous != ETL_NULLPTR) || (etl_next != ETL_NULLPTR);
270 swap(etl_previous, etl_next);
279 if (etl_previous != ETL_NULLPTR)
281 etl_previous->etl_next = etl_next;
285 if (etl_next != ETL_NULLPTR)
287 etl_next->etl_previous = etl_previous;
293 template <
typename TLink>
295 link(TLink& lhs, TLink& rhs)
298 rhs.etl_previous = &lhs;
302 template <
typename TLink>
304 link_splice(TLink& lhs, TLink& rhs)
306 rhs.etl_next = lhs.etl_next;
307 rhs.etl_previous = &lhs;
309 if (lhs.etl_next != ETL_NULLPTR)
311 lhs.etl_next->etl_previous = &rhs;
318 template <
typename TLink>
320 link(TLink* lhs, TLink* rhs)
322 if (lhs != ETL_NULLPTR)
327 if (rhs != ETL_NULLPTR)
329 rhs->etl_previous = lhs;
334 template <
typename TLink>
336 link_splice(TLink* lhs, TLink* rhs)
338 if (rhs != ETL_NULLPTR)
340 if (lhs != ETL_NULLPTR)
342 rhs->etl_next = lhs->etl_next;
345 rhs->etl_previous = lhs;
348 if (lhs != ETL_NULLPTR)
350 if (lhs->etl_next != ETL_NULLPTR)
352 lhs->etl_next->etl_previous = rhs;
360 template <
typename TLink>
362 link(TLink& lhs, TLink* rhs)
366 if (rhs != ETL_NULLPTR)
368 rhs->etl_previous = &lhs;
373 template <
typename TLink>
375 link_splice(TLink& lhs, TLink* rhs)
377 if (rhs != ETL_NULLPTR)
379 rhs->etl_next = lhs.etl_next;
380 rhs->etl_previous = &lhs;
383 if (lhs.etl_next != ETL_NULLPTR)
385 lhs.etl_next->etl_previous = rhs;
392 template <
typename TLink>
394 link(TLink* lhs, TLink& rhs)
396 if (lhs != ETL_NULLPTR)
398 lhs->etl_next = &rhs;
401 rhs.etl_previous = lhs;
405 template <
typename TLink>
407 link_splice(TLink* lhs, TLink& rhs)
409 if (lhs != ETL_NULLPTR)
411 rhs.etl_next = lhs->etl_next;
414 rhs.etl_previous = lhs;
416 if (lhs != ETL_NULLPTR)
418 if (lhs->etl_next != ETL_NULLPTR)
420 lhs->etl_next->etl_previous = &rhs;
423 lhs->etl_next = &rhs;
428 template <
typename TLink>
430 link_splice(TLink& lhs, TLink& first, TLink& last)
432 last.etl_next = lhs.etl_next;
433 first.etl_previous = &lhs;
435 if (last.etl_next != ETL_NULLPTR)
437 last.etl_next->etl_previous = &last;
440 lhs.etl_next = &first;
444 template <
typename TLink>
446 link_splice(TLink* lhs, TLink& first, TLink& last)
448 if (lhs != ETL_NULLPTR)
450 last.etl_next = lhs->etl_next;
454 last.etl_next = ETL_NULLPTR;
457 first.etl_previous = lhs;
459 if (last.etl_next != ETL_NULLPTR)
461 last.etl_next->etl_previous = &last;
464 if (lhs != ETL_NULLPTR)
466 lhs->etl_next = &first;
471 template <
typename TLink>
479 template <
typename TLink>
481 unlink(TLink& first, TLink& last)
489 if (last.etl_next != ETL_NULLPTR)
491 last.etl_next->etl_previous = first.etl_previous;
494 if (first.etl_previous != ETL_NULLPTR)
496 first.etl_previous->etl_next = last.etl_next;
504 template <const
size_t ID_>
514 etl_parent = ETL_NULLPTR;
515 etl_left = ETL_NULLPTR;
516 etl_right = ETL_NULLPTR;
519 bool is_linked()
const
521 return (etl_parent != ETL_NULLPTR) || (etl_left != ETL_NULLPTR) || (etl_right != ETL_NULLPTR);
530 template <
typename TLink>
532 link_left(TLink& parent, TLink& leaf)
534 parent.etl_left = &leaf;
535 leaf.etl_parent = &parent;
538 template <
typename TLink>
540 link_right(TLink& parent, TLink& leaf)
542 parent.etl_right = &leaf;
543 leaf.etl_parent = &parent;
547 template <
typename TLink>
549 link_left(TLink* parent, TLink* leaf)
551 if (parent != ETL_NULLPTR)
553 parent->etl_left = leaf;
556 if (leaf != ETL_NULLPTR)
558 leaf->etl_parent = parent;
562 template <
typename TLink>
564 link_right(TLink* parent, TLink* leaf)
566 if (parent != ETL_NULLPTR)
568 parent->etl_right = leaf;
571 if (leaf != ETL_NULLPTR)
573 leaf->etl_parent = parent;
578 template <
typename TLink>
580 link_left(TLink& parent, TLink* leaf)
582 parent.etl_left = leaf;
584 if (leaf != ETL_NULLPTR)
586 leaf->etl_parent = &parent;
590 template <
typename TLink>
592 link_right(TLink& parent, TLink* leaf)
594 parent.etl_right = leaf;
596 if (leaf != ETL_NULLPTR)
598 leaf->etl_parent = &parent;
603 template <
typename TLink>
605 link_left(TLink* parent, TLink& leaf)
607 if (parent != ETL_NULLPTR)
609 parent->etl_left = &leaf;
612 leaf.etl_parent = parent;
615 template <
typename TLink>
617 link_right(TLink* parent, TLink& leaf)
619 if (parent != ETL_NULLPTR)
621 parent->etl_right = &leaf;
624 leaf.etl_parent = parent;
628 template <
typename TLink>
630 link_rotate_left(TLink& parent, TLink& leaf)
632 parent.etl_right = leaf.etl_left;
634 if (parent.etl_right != ETL_NULLPTR)
636 parent.etl_right->etl_parent = &parent;
639 leaf.etl_parent = parent.etl_parent;
640 parent.etl_parent = &leaf;
641 leaf.etl_left = &parent;
644 template <
typename TLink>
646 link_rotate_right(TLink& parent, TLink& leaf)
648 parent.etl_left = leaf.etl_right;
650 if (parent.etl_left != ETL_NULLPTR)
652 parent.etl_left->etl_parent = &parent;
655 leaf.etl_parent = parent.etl_parent;
656 parent.etl_parent = &leaf;
657 leaf.etl_right = &parent;
661 template <
typename TLink>
663 link_rotate_left(TLink* parent, TLink* leaf)
665 if ((parent != ETL_NULLPTR) && (leaf != ETL_NULLPTR))
667 link_rotate_left(*parent, *leaf);
671 template <
typename TLink>
673 link_rotate_right(TLink* parent, TLink* leaf)
675 if ((parent != ETL_NULLPTR) && (leaf != ETL_NULLPTR))
677 link_rotate_right(*parent, *leaf);
682 template <
typename TLink>
684 link_rotate_left(TLink& parent, TLink* leaf)
686 if (leaf != ETL_NULLPTR)
688 link_rotate_left(parent, *leaf);
692 template <
typename TLink>
694 link_rotate_right(TLink& parent, TLink* leaf)
696 if (leaf != ETL_NULLPTR)
698 link_rotate_right(parent, *leaf);
703 template <
typename TLink>
705 link_rotate_left(TLink* parent, TLink& leaf)
707 if (parent != ETL_NULLPTR)
709 link_rotate_left(*parent, leaf);
713 template <
typename TLink>
715 link_rotate_right(TLink* parent, TLink& leaf)
717 if (parent != ETL_NULLPTR)
719 link_rotate_right(*parent, leaf);
725 template <
typename TLink>
729 if (parent.etl_left == &leaf)
731 etl::link_rotate_right(parent, leaf);
735 etl::link_rotate_left(parent, leaf);
741 template <
typename TLink>
745 if ((parent != ETL_NULLPTR) && (leaf != ETL_NULLPTR))
747 if (parent->etl_left == leaf)
749 etl::link_rotate_right(*parent, *leaf);
753 etl::link_rotate_left(*parent, *leaf);
760 template <
typename TLink>
764 if (leaf != ETL_NULLPTR)
766 if (parent.etl_left == leaf)
768 etl::link_rotate_right(parent, *leaf);
772 etl::link_rotate_left(parent, *leaf);
779 template <
typename TLink>
783 if (parent != ETL_NULLPTR)
785 if (parent->etl_left == &leaf)
787 etl::link_rotate_right(*parent, leaf);
791 etl::link_rotate_left(*parent, leaf);
Link exception.
Definition: intrusive_links.h:65
not unlinked exception.
Definition: intrusive_links.h:78
exception(string_type reason_, string_type file_, numeric_type line_)
Constructor.
Definition: exception.h:67
Definition: exception.h:47
enable_if
Definition: type_traits_generator.h:1228
Definition: absolute.h:37
etl::enable_if< etl::is_same< TLink, etl::tree_link< TLink::ID > >::value, void >::type link_rotate(TLink &parent, TLink &leaf)
Automatically detects whether a left or right rotate is expected.
Definition: intrusive_links.h:727
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:570
A bidirectional link.
Definition: intrusive_links.h:249
A forward link.
Definition: intrusive_links.h:92
A binary tree link.
Definition: intrusive_links.h:506