1 /* Tests fpr intrusive double linked list for GDB, the GNU debugger.
2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "gdbsupport/intrusive_list.h"
21 #include "gdbsupport/owning_intrusive_list.h"
22 #include "gdbsupport/selftest.h"
23 #include <unordered_set>
25 /* Count of how many item_with_base or item_with_member objects are
28 static int items_alive
= 0;
30 /* An item type using intrusive_list_node by inheriting from it and its
31 corresponding list type. Put another base before intrusive_list_node
32 so that a pointer to the node != a pointer to the item. */
39 struct item_with_base
: public other_base
,
40 public intrusive_list_node
<item_with_base
>
42 explicit item_with_base (const char *name
)
48 DISABLE_COPY_AND_ASSIGN (item_with_base
);
50 ~item_with_base () { --items_alive
; }
52 const char *const name
;
55 using item_with_base_list
= intrusive_list
<item_with_base
>;
57 /* An item type using intrusive_list_node as a field and its corresponding
58 list type. Put the other field before the node, so that a pointer to the
59 node != a pointer to the item. */
61 struct item_with_member
63 explicit item_with_member (const char *name
)
69 DISABLE_COPY_AND_ASSIGN (item_with_member
);
71 ~item_with_member () { --items_alive
; }
73 const char *const name
;
74 intrusive_list_node
<item_with_member
> node
;
77 /* Verify that LIST contains exactly the items in EXPECTED.
79 Traverse the list forward and backwards to exercise all links. */
81 template <typename ListType
>
83 verify_items (const ListType
&list
,
84 gdb::array_view
<const typename
ListType::value_type
*> expected
)
86 using item_type
= typename
ListType::value_type
;
90 for (typename
ListType::iterator it
= list
.begin (); it
!= list
.end (); ++it
)
92 const item_type
&item
= *it
;
94 SELF_CHECK (i
< expected
.size ());
95 SELF_CHECK (&item
== expected
[i
]);
97 /* Access the item, to make sure the object is still alive. */
98 SELF_CHECK (strcmp (item
.name
, expected
[i
]->name
) == 0);
103 SELF_CHECK (i
== expected
.size ());
105 for (typename
ListType::reverse_iterator it
= list
.rbegin ();
106 it
!= list
.rend (); ++it
)
108 const item_type
&item
= *it
;
113 SELF_CHECK (&item
== expected
[i
]);
115 /* Access the item, to make sure the object is still alive. */
116 SELF_CHECK (strcmp (item
.name
, expected
[i
]->name
) == 0);
122 /* intrusive_list tests
124 To run all tests using both the base and member methods, all tests are
125 declared in this templated class, which is instantiated once for each
128 using item_with_member_node
129 = intrusive_member_node
<item_with_member
, &item_with_member::node
>;
130 using item_with_member_list
131 = intrusive_list
<item_with_member
, item_with_member_node
>;
133 template <typename ListType
>
134 struct intrusive_list_test
136 using item_type
= typename
ListType::value_type
;
139 test_move_constructor ()
142 /* Other list is not empty. */
143 item_type
a ("a"), b ("b"), c ("c");
145 std::vector
<const item_type
*> expected
;
151 ListType
list2 (std::move (list1
));
154 verify_items (list1
, expected
);
156 expected
= {&a
, &b
, &c
};
157 verify_items (list2
, expected
);
161 /* Other list contains 1 element. */
164 std::vector
<const item_type
*> expected
;
168 ListType
list2 (std::move (list1
));
171 verify_items (list1
, expected
);
174 verify_items (list2
, expected
);
178 /* Other list is empty. */
180 std::vector
<const item_type
*> expected
;
182 ListType
list2 (std::move (list1
));
185 verify_items (list1
, expected
);
188 verify_items (list2
, expected
);
193 test_move_assignment ()
196 /* Both lists are not empty. */
197 item_type
a ("a"), b ("b"), c ("c"), d ("d"), e ("e");
200 std::vector
<const item_type
*> expected
;
209 list2
= std::move (list1
);
212 verify_items (list1
, expected
);
214 expected
= {&a
, &b
, &c
};
215 verify_items (list2
, expected
);
219 /* rhs list is empty. */
220 item_type
a ("a"), b ("b"), c ("c");
223 std::vector
<const item_type
*> expected
;
229 list2
= std::move (list1
);
232 verify_items (list1
, expected
);
235 verify_items (list2
, expected
);
239 /* lhs list is empty. */
240 item_type
a ("a"), b ("b"), c ("c");
243 std::vector
<const item_type
*> expected
;
249 list2
= std::move (list1
);
252 verify_items (list1
, expected
);
254 expected
= {&a
, &b
, &c
};
255 verify_items (list2
, expected
);
259 /* Both lists contain 1 item. */
260 item_type
a ("a"), b ("b");
263 std::vector
<const item_type
*> expected
;
268 list2
= std::move (list1
);
271 verify_items (list1
, expected
);
274 verify_items (list2
, expected
);
278 /* Both lists are empty. */
281 std::vector
<const item_type
*> expected
;
283 list2
= std::move (list1
);
286 verify_items (list1
, expected
);
289 verify_items (list2
, expected
);
297 /* Two non-empty lists. */
298 item_type
a ("a"), b ("b"), c ("c"), d ("d"), e ("e");
301 std::vector
<const item_type
*> expected
;
310 std::swap (list1
, list2
);
313 verify_items (list1
, expected
);
315 expected
= {&a
, &b
, &c
};
316 verify_items (list2
, expected
);
320 /* Other is empty. */
321 item_type
a ("a"), b ("b"), c ("c");
324 std::vector
<const item_type
*> expected
;
330 std::swap (list1
, list2
);
333 verify_items (list1
, expected
);
335 expected
= {&a
, &b
, &c
};
336 verify_items (list2
, expected
);
340 /* *this is empty. */
341 item_type
a ("a"), b ("b"), c ("c");
344 std::vector
<const item_type
*> expected
;
350 std::swap (list1
, list2
);
352 expected
= {&a
, &b
, &c
};
353 verify_items (list1
, expected
);
356 verify_items (list2
, expected
);
360 /* Both lists empty. */
363 std::vector
<const item_type
*> expected
;
365 std::swap (list1
, list2
);
368 verify_items (list1
, expected
);
371 verify_items (list2
, expected
);
375 /* Swap one element twice. */
379 std::vector
<const item_type
*> expected
;
383 std::swap (list1
, list2
);
386 verify_items (list1
, expected
);
389 verify_items (list2
, expected
);
391 std::swap (list1
, list2
);
394 verify_items (list1
, expected
);
397 verify_items (list2
, expected
);
404 item_type
a ("a"), b ("b"), c ("c");
406 const ListType
&clist
= list
;
412 SELF_CHECK (&list
.front () == &a
);
413 SELF_CHECK (&clist
.front () == &a
);
414 SELF_CHECK (&list
.back () == &c
);
415 SELF_CHECK (&clist
.back () == &c
);
421 item_type
a ("a"), b ("b"), c ("c");
423 std::vector
<const item_type
*> expected
;
426 verify_items (list
, expected
);
430 verify_items (list
, expected
);
434 verify_items (list
, expected
);
437 expected
= {&c
, &b
, &a
};
438 verify_items (list
, expected
);
444 item_type
a ("a"), b ("b"), c ("c");
446 std::vector
<const item_type
*> expected
;
449 verify_items (list
, expected
);
453 verify_items (list
, expected
);
457 verify_items (list
, expected
);
460 expected
= {&a
, &b
, &c
};
461 verify_items (list
, expected
);
467 std::vector
<const item_type
*> expected
;
470 /* Insert at beginning. */
471 item_type
a ("a"), b ("b"), c ("c");
475 auto a_it
= list
.insert (list
.begin (), a
);
476 SELF_CHECK (&*a_it
== &a
);
478 verify_items (list
, expected
);
480 auto b_it
= list
.insert (list
.begin (), b
);
481 SELF_CHECK (&*b_it
== &b
);
483 verify_items (list
, expected
);
485 auto c_it
= list
.insert (list
.begin (), c
);
486 SELF_CHECK (&*c_it
== &c
);
487 expected
= {&c
, &b
, &a
};
488 verify_items (list
, expected
);
493 item_type
a ("a"), b ("b"), c ("c");
497 auto a_it
= list
.insert (list
.end (), a
);
498 SELF_CHECK (&*a_it
== &a
);
500 verify_items (list
, expected
);
502 auto b_it
= list
.insert (list
.end (), b
);
503 SELF_CHECK (&*b_it
== &b
);
505 verify_items (list
, expected
);
507 auto c_it
= list
.insert (list
.end (), c
);
508 SELF_CHECK (&*c_it
== &c
);
509 expected
= {&a
, &b
, &c
};
510 verify_items (list
, expected
);
514 /* Insert in the middle. */
515 item_type
a ("a"), b ("b"), c ("c");
521 auto c_it
= list
.insert (list
.iterator_to (b
), c
);
522 SELF_CHECK (&*c_it
== &c
);
523 expected
= {&a
, &c
, &b
};
524 verify_items (list
, expected
);
528 /* Insert in empty list. */
532 auto a_it
= list
.insert (list
.end (), a
);
533 SELF_CHECK (&*a_it
== &a
);
535 verify_items (list
, expected
);
543 /* Two non-empty lists. */
544 item_type
a ("a"), b ("b"), c ("c"), d ("d"), e ("e");
547 std::vector
<const item_type
*> expected
;
556 list1
.splice (std::move (list2
));
558 expected
= {&a
, &b
, &c
, &d
, &e
};
559 verify_items (list1
, expected
);
562 verify_items (list2
, expected
);
566 /* Receiving list empty. */
567 item_type
a ("a"), b ("b"), c ("c");
570 std::vector
<const item_type
*> expected
;
576 list1
.splice (std::move (list2
));
578 expected
= {&a
, &b
, &c
};
579 verify_items (list1
, expected
);
582 verify_items (list2
, expected
);
586 /* Giving list empty. */
587 item_type
a ("a"), b ("b"), c ("c");
590 std::vector
<const item_type
*> expected
;
596 list1
.splice (std::move (list2
));
598 expected
= {&a
, &b
, &c
};
599 verify_items (list1
, expected
);
602 verify_items (list2
, expected
);
606 /* Both lists empty. */
609 std::vector
<const item_type
*> expected
;
611 list1
.splice (std::move (list2
));
614 verify_items (list1
, expected
);
617 verify_items (list2
, expected
);
624 item_type
a ("a"), b ("b"), c ("c");
626 std::vector
<const item_type
*> expected
;
634 verify_items (list
, expected
);
638 verify_items (list
, expected
);
642 verify_items (list
, expected
);
648 item_type
a ("a"), b ("b"), c ("c");
650 std::vector
<const item_type
*> expected
;
658 verify_items (list
, expected
);
662 verify_items (list
, expected
);
666 verify_items (list
, expected
);
672 item_type
a ("a"), b ("b"), c ("c");
674 std::vector
<const item_type
*> expected
;
680 list
.erase (list
.iterator_to (b
));
682 verify_items (list
, expected
);
684 list
.erase (list
.iterator_to (c
));
686 verify_items (list
, expected
);
688 list
.erase (list
.iterator_to (a
));
690 verify_items (list
, expected
);
696 item_type
a ("a"), b ("b"), c ("c");
698 std::vector
<const item_type
*> expected
;
706 verify_items (list
, expected
);
708 /* Verify idempotency. */
711 verify_items (list
, expected
);
715 test_clear_and_dispose ()
717 item_type
a ("a"), b ("b"), c ("c");
719 std::vector
<const item_type
*> expected
;
720 std::unordered_set
<const item_type
*> disposer_seen
;
721 int disposer_calls
= 0;
727 auto disposer
= [&] (const item_type
*item
)
729 disposer_seen
.insert (item
);
732 list
.clear_and_dispose (disposer
);
735 verify_items (list
, expected
);
736 SELF_CHECK (disposer_calls
== 3);
737 SELF_CHECK (disposer_seen
.find (&a
) != disposer_seen
.end ());
738 SELF_CHECK (disposer_seen
.find (&b
) != disposer_seen
.end ());
739 SELF_CHECK (disposer_seen
.find (&c
) != disposer_seen
.end ());
741 /* Verify idempotency. */
742 list
.clear_and_dispose (disposer
);
743 SELF_CHECK (disposer_calls
== 3);
752 SELF_CHECK (list
.empty ());
754 SELF_CHECK (!list
.empty ());
755 list
.erase (list
.iterator_to (a
));
756 SELF_CHECK (list
.empty ());
762 item_type
a ("a"), b ("b"), c ("c");
764 const ListType
&clist
= list
;
770 SELF_CHECK (&*list
.begin () == &a
);
771 SELF_CHECK (&*list
.cbegin () == &a
);
772 SELF_CHECK (&*clist
.begin () == &a
);
773 SELF_CHECK (&*list
.rbegin () == &c
);
774 SELF_CHECK (&*list
.crbegin () == &c
);
775 SELF_CHECK (&*clist
.rbegin () == &c
);
777 /* At least check that they compile. */
787 template <typename ListType
>
789 test_intrusive_list_1 ()
791 intrusive_list_test
<ListType
> tests
;
793 tests
.test_move_constructor ();
794 tests
.test_move_assignment ();
796 tests
.test_front_back ();
797 tests
.test_push_front ();
798 tests
.test_push_back ();
799 tests
.test_insert ();
800 tests
.test_splice ();
801 tests
.test_pop_front ();
802 tests
.test_pop_back ();
805 tests
.test_clear_and_dispose ();
807 tests
.test_begin_end ();
810 /* owning_intrusive_list tests
812 To run all tests using both the base and member methods, all tests are
813 declared in this templated class, which is instantiated once for each
816 using item_with_base_owning_list
= owning_intrusive_list
<item_with_base
>;
817 using item_with_member_owning_list
818 = owning_intrusive_list
<item_with_member
, item_with_member_node
>;
820 template<typename ListType
>
821 struct owning_intrusive_list_test
823 using item_type
= typename
ListType::value_type
;
825 static void test_move_constructor ()
828 /* Other list is not empty. */
830 std::vector
<const item_type
*> expected
;
832 auto &a
= list1
.emplace_back ("a");
833 auto &b
= list1
.emplace_back ("b");
834 auto &c
= list1
.emplace_back ("c");
836 SELF_CHECK (items_alive
== 3);
837 ListType
list2 (std::move (list1
));
838 SELF_CHECK (items_alive
== 3);
841 verify_items (list1
, expected
);
843 expected
= { &a
, &b
, &c
};
844 verify_items (list2
, expected
);
848 /* Other list contains 1 element. */
850 std::vector
<const item_type
*> expected
;
852 auto &a
= list1
.emplace_back ("a");
854 SELF_CHECK (items_alive
== 1);
855 ListType
list2 (std::move (list1
));
856 SELF_CHECK (items_alive
== 1);
859 verify_items (list1
, expected
);
862 verify_items (list2
, expected
);
866 /* Other list is empty. */
868 std::vector
<const item_type
*> expected
;
870 SELF_CHECK (items_alive
== 0);
871 ListType
list2 (std::move (list1
));
872 SELF_CHECK (items_alive
== 0);
875 verify_items (list1
, expected
);
878 verify_items (list2
, expected
);
882 static void test_move_assignment ()
885 /* Both lists are not empty. */
888 std::vector
<const item_type
*> expected
;
890 auto &a
= list1
.emplace_back ("a");
891 auto &b
= list1
.emplace_back ("b");
892 auto &c
= list1
.emplace_back ("c");
894 list2
.emplace_back ("d");
895 list2
.emplace_back ("e");
897 SELF_CHECK (items_alive
== 5);
898 list2
= std::move (list1
);
899 SELF_CHECK (items_alive
== 3);
902 verify_items (list1
, expected
);
904 expected
= { &a
, &b
, &c
};
905 verify_items (list2
, expected
);
909 /* rhs list is empty. */
912 std::vector
<const item_type
*> expected
;
914 list2
.emplace_back ("a");
915 list2
.emplace_back ("b");
916 list2
.emplace_back ("c");
918 SELF_CHECK (items_alive
== 3);
919 list2
= std::move (list1
);
920 SELF_CHECK (items_alive
== 0);
923 verify_items (list1
, expected
);
926 verify_items (list2
, expected
);
930 /* lhs list is empty. */
933 std::vector
<const item_type
*> expected
;
935 auto &a
= list1
.emplace_back ("a");
936 auto &b
= list1
.emplace_back ("b");
937 auto &c
= list1
.emplace_back ("c");
939 SELF_CHECK (items_alive
== 3);
940 list2
= std::move (list1
);
941 SELF_CHECK (items_alive
== 3);
944 verify_items (list1
, expected
);
946 expected
= { &a
, &b
, &c
};
947 verify_items (list2
, expected
);
951 /* Both lists contain 1 item. */
954 std::vector
<const item_type
*> expected
;
956 auto &a
= list1
.emplace_back ("a");
957 list2
.emplace_back ("b");
959 SELF_CHECK (items_alive
== 2);
960 list2
= std::move (list1
);
961 SELF_CHECK (items_alive
== 1);
964 verify_items (list1
, expected
);
967 verify_items (list2
, expected
);
971 /* Both lists are empty. */
974 std::vector
<const item_type
*> expected
;
976 SELF_CHECK (items_alive
== 0);
977 list2
= std::move (list1
);
978 SELF_CHECK (items_alive
== 0);
981 verify_items (list1
, expected
);
984 verify_items (list2
, expected
);
988 static void test_swap ()
991 /* Two non-empty lists. */
994 std::vector
<const item_type
*> expected
;
996 auto &a
= list1
.emplace_back ("a");
997 auto &b
= list1
.emplace_back ("b");
998 auto &c
= list1
.emplace_back ("c");
1000 auto &d
= list2
.emplace_back ("d");
1001 auto &e
= list2
.emplace_back ("e");
1003 SELF_CHECK (items_alive
== 5);
1004 std::swap (list1
, list2
);
1005 SELF_CHECK (items_alive
== 5);
1007 expected
= { &d
, &e
};
1008 verify_items (list1
, expected
);
1010 expected
= { &a
, &b
, &c
};
1011 verify_items (list2
, expected
);
1015 /* Other is empty. */
1018 std::vector
<const item_type
*> expected
;
1020 auto &a
= list1
.emplace_back ("a");
1021 auto &b
= list1
.emplace_back ("b");
1022 auto &c
= list1
.emplace_back ("c");
1024 SELF_CHECK (items_alive
== 3);
1025 std::swap (list1
, list2
);
1026 SELF_CHECK (items_alive
== 3);
1029 verify_items (list1
, expected
);
1031 expected
= { &a
, &b
, &c
};
1032 verify_items (list2
, expected
);
1036 /* *this is empty. */
1039 std::vector
<const item_type
*> expected
;
1041 auto &a
= list2
.emplace_back ("a");
1042 auto &b
= list2
.emplace_back ("b");
1043 auto &c
= list2
.emplace_back ("c");
1045 SELF_CHECK (items_alive
== 3);
1046 std::swap (list1
, list2
);
1047 SELF_CHECK (items_alive
== 3);
1049 expected
= { &a
, &b
, &c
};
1050 verify_items (list1
, expected
);
1053 verify_items (list2
, expected
);
1057 /* Both lists empty. */
1060 std::vector
<const item_type
*> expected
;
1062 SELF_CHECK (items_alive
== 0);
1063 std::swap (list1
, list2
);
1064 SELF_CHECK (items_alive
== 0);
1067 verify_items (list1
, expected
);
1070 verify_items (list2
, expected
);
1074 /* Swap one element twice. */
1077 std::vector
<const item_type
*> expected
;
1079 auto &a
= list1
.emplace_back ("a");
1081 SELF_CHECK (items_alive
== 1);
1082 std::swap (list1
, list2
);
1083 SELF_CHECK (items_alive
== 1);
1086 verify_items (list1
, expected
);
1089 verify_items (list2
, expected
);
1091 std::swap (list1
, list2
);
1092 SELF_CHECK (items_alive
== 1);
1095 verify_items (list1
, expected
);
1098 verify_items (list2
, expected
);
1102 static void test_front_back ()
1105 const ListType
&clist
= list
;
1107 auto &a
= list
.emplace_back ("a");
1108 list
.emplace_back ("b");
1109 auto &c
= list
.emplace_back ("c");
1111 SELF_CHECK (&list
.front () == &a
);
1112 SELF_CHECK (&clist
.front () == &a
);
1113 SELF_CHECK (&list
.back () == &c
);
1114 SELF_CHECK (&clist
.back () == &c
);
1117 static void test_push_front ()
1120 std::vector
<const item_type
*> expected
;
1122 SELF_CHECK (items_alive
== 0);
1123 list
.push_front (std::make_unique
<item_type
> ("a"));
1124 auto &a
= list
.front ();
1126 verify_items (list
, expected
);
1127 SELF_CHECK (items_alive
== 1);
1129 list
.push_front (std::make_unique
<item_type
> ("b"));
1130 auto &b
= list
.front ();
1131 expected
= { &b
, &a
};
1132 verify_items (list
, expected
);
1133 SELF_CHECK (items_alive
== 2);
1135 list
.push_front (std::make_unique
<item_type
> ("c"));
1136 auto &c
= list
.front ();
1137 expected
= { &c
, &b
, &a
};
1138 verify_items (list
, expected
);
1139 SELF_CHECK (items_alive
== 3);
1142 static void test_push_back ()
1145 std::vector
<const item_type
*> expected
;
1147 SELF_CHECK (items_alive
== 0);
1148 list
.push_back (std::make_unique
<item_type
> ("a"));
1149 auto &a
= list
.back ();
1151 verify_items (list
, expected
);
1152 SELF_CHECK (items_alive
== 1);
1154 list
.push_back (std::make_unique
<item_type
> ("b"));
1155 auto &b
= list
.back ();
1156 expected
= { &a
, &b
};
1157 verify_items (list
, expected
);
1158 SELF_CHECK (items_alive
== 2);
1160 list
.push_back (std::make_unique
<item_type
> ("c"));
1161 auto &c
= list
.back ();
1162 expected
= { &a
, &b
, &c
};
1163 verify_items (list
, expected
);
1164 SELF_CHECK (items_alive
== 3);
1167 static void test_insert ()
1169 std::vector
<const item_type
*> expected
;
1172 /* Insert at beginning. */
1175 auto &a
= *list
.insert (list
.begin (), std::make_unique
<item_type
> ("a"));
1177 verify_items (list
, expected
);
1178 SELF_CHECK (items_alive
== 1);
1180 auto &b
= *list
.insert (list
.begin (), std::make_unique
<item_type
> ("b"));
1181 expected
= { &b
, &a
};
1182 verify_items (list
, expected
);
1183 SELF_CHECK (items_alive
== 2);
1185 auto &c
= *list
.insert (list
.begin (), std::make_unique
<item_type
> ("c"));
1186 expected
= { &c
, &b
, &a
};
1187 verify_items (list
, expected
);
1188 SELF_CHECK (items_alive
== 3);
1192 /* Insert at end. */
1195 auto &a
= *list
.insert (list
.end (), std::make_unique
<item_type
> ("a"));
1197 verify_items (list
, expected
);
1198 SELF_CHECK (items_alive
== 1);
1200 auto &b
= *list
.insert (list
.end (), std::make_unique
<item_type
> ("b"));
1201 expected
= { &a
, &b
};
1202 verify_items (list
, expected
);
1203 SELF_CHECK (items_alive
== 2);
1205 auto &c
= *list
.insert (list
.end (), std::make_unique
<item_type
> ("c"));
1206 expected
= { &a
, &b
, &c
};
1207 verify_items (list
, expected
);
1208 SELF_CHECK (items_alive
== 3);
1212 /* Insert in the middle. */
1215 auto &a
= list
.emplace_back ("a");
1216 auto &b
= list
.emplace_back ("b");
1218 SELF_CHECK (items_alive
== 2);
1219 auto &c
= *list
.insert (list
.iterator_to (b
),
1220 std::make_unique
<item_type
> ("c"));
1221 expected
= { &a
, &c
, &b
};
1222 verify_items (list
, expected
);
1223 SELF_CHECK (items_alive
== 3);
1227 /* Insert in empty list. */
1230 SELF_CHECK (items_alive
== 0);
1231 auto &a
= *list
.insert (list
.end (), std::make_unique
<item_type
> ("a"));
1233 verify_items (list
, expected
);
1234 SELF_CHECK (items_alive
== 1);
1238 static void test_emplace_front ()
1241 std::vector
<const item_type
*> expected
;
1243 SELF_CHECK (items_alive
== 0);
1244 auto &a
= list
.emplace_front ("a");
1246 verify_items (list
, expected
);
1247 SELF_CHECK (items_alive
== 1);
1249 auto &b
= list
.emplace_front ("b");
1250 expected
= { &b
, &a
};
1251 verify_items (list
, expected
);
1252 SELF_CHECK (items_alive
== 2);
1254 auto &c
= list
.emplace_front ("c");
1255 expected
= { &c
, &b
, &a
};
1256 verify_items (list
, expected
);
1257 SELF_CHECK (items_alive
== 3);
1260 static void test_emplace_back ()
1263 std::vector
<const item_type
*> expected
;
1265 SELF_CHECK (items_alive
== 0);
1266 auto &a
= list
.emplace_back ("a");
1268 verify_items (list
, expected
);
1269 SELF_CHECK (items_alive
== 1);
1271 auto &b
= list
.emplace_back ("b");
1272 expected
= { &a
, &b
};
1273 verify_items (list
, expected
);
1274 SELF_CHECK (items_alive
== 2);
1276 auto &c
= list
.emplace_back ("c");
1277 expected
= { &a
, &b
, &c
};
1278 verify_items (list
, expected
);
1279 SELF_CHECK (items_alive
== 3);
1282 static void test_emplace ()
1284 std::vector
<const item_type
*> expected
;
1287 /* Emplace at beginning. */
1290 auto &a
= list
.emplace (list
.begin (), "a");
1292 verify_items (list
, expected
);
1293 SELF_CHECK (items_alive
== 1);
1295 auto &b
= list
.emplace (list
.begin (), "b");
1296 expected
= { &b
, &a
};
1297 verify_items (list
, expected
);
1298 SELF_CHECK (items_alive
== 2);
1300 auto &c
= list
.emplace (list
.begin (), "c");
1301 expected
= { &c
, &b
, &a
};
1302 verify_items (list
, expected
);
1303 SELF_CHECK (items_alive
== 3);
1307 /* Emplace at end. */
1310 auto &a
= list
.emplace (list
.end (), "a");
1312 verify_items (list
, expected
);
1313 SELF_CHECK (items_alive
== 1);
1315 auto &b
= list
.emplace (list
.end (), "b");
1316 expected
= { &a
, &b
};
1317 verify_items (list
, expected
);
1318 SELF_CHECK (items_alive
== 2);
1320 auto &c
= list
.emplace (list
.end (), "c");
1321 expected
= { &a
, &b
, &c
};
1322 verify_items (list
, expected
);
1323 SELF_CHECK (items_alive
== 3);
1327 /* Emplace in the middle. */
1330 auto &a
= list
.emplace_back ("a");
1331 auto &b
= list
.emplace_back ("b");
1333 SELF_CHECK (items_alive
== 2);
1334 auto &c
= list
.emplace (list
.iterator_to (b
), "c");
1335 expected
= { &a
, &c
, &b
};
1336 verify_items (list
, expected
);
1337 SELF_CHECK (items_alive
== 3);
1341 /* Emplace in empty list. */
1344 SELF_CHECK (items_alive
== 0);
1345 auto &a
= list
.emplace (list
.end (), "a");
1347 verify_items (list
, expected
);
1348 SELF_CHECK (items_alive
== 1);
1352 static void test_splice ()
1355 /* Two non-empty lists. */
1358 std::vector
<const item_type
*> expected
;
1360 auto &a
= list1
.emplace_back ("a");
1361 auto &b
= list1
.emplace_back ("b");
1362 auto &c
= list1
.emplace_back ("c");
1364 auto &d
= list2
.emplace_back ("d");
1365 auto &e
= list2
.emplace_back ("e");
1367 SELF_CHECK (items_alive
== 5);
1368 list1
.splice (std::move (list2
));
1369 SELF_CHECK (items_alive
== 5);
1371 expected
= { &a
, &b
, &c
, &d
, &e
};
1372 verify_items (list1
, expected
);
1375 verify_items (list2
, expected
);
1379 /* Receiving list empty. */
1382 std::vector
<const item_type
*> expected
;
1384 auto &a
= list2
.emplace_back ("a");
1385 auto &b
= list2
.emplace_back ("b");
1386 auto &c
= list2
.emplace_back ("c");
1388 SELF_CHECK (items_alive
== 3);
1389 list1
.splice (std::move (list2
));
1390 SELF_CHECK (items_alive
== 3);
1392 expected
= { &a
, &b
, &c
};
1393 verify_items (list1
, expected
);
1396 verify_items (list2
, expected
);
1400 /* Giving list empty. */
1403 std::vector
<const item_type
*> expected
;
1405 auto &a
= list1
.emplace_back ("a");
1406 auto &b
= list1
.emplace_back ("b");
1407 auto &c
= list1
.emplace_back ("c");
1409 SELF_CHECK (items_alive
== 3);
1410 list1
.splice (std::move (list2
));
1411 SELF_CHECK (items_alive
== 3);
1413 expected
= { &a
, &b
, &c
};
1414 verify_items (list1
, expected
);
1417 verify_items (list2
, expected
);
1421 /* Both lists empty. */
1424 std::vector
<const item_type
*> expected
;
1426 SELF_CHECK (items_alive
== 0);
1427 list1
.splice (std::move (list2
));
1428 SELF_CHECK (items_alive
== 0);
1431 verify_items (list1
, expected
);
1434 verify_items (list2
, expected
);
1438 static void test_pop_front ()
1441 std::vector
<const item_type
*> expected
;
1443 list
.emplace_back ("a");
1444 auto &b
= list
.emplace_back ("b");
1445 auto &c
= list
.emplace_back ("c");
1447 SELF_CHECK (items_alive
== 3);
1449 expected
= { &b
, &c
};
1450 verify_items (list
, expected
);
1451 SELF_CHECK (items_alive
== 2);
1455 verify_items (list
, expected
);
1456 SELF_CHECK (items_alive
== 1);
1460 verify_items (list
, expected
);
1461 SELF_CHECK (items_alive
== 0);
1464 static void test_pop_back ()
1467 std::vector
<const item_type
*> expected
;
1469 auto &a
= list
.emplace_back ("a");
1470 auto &b
= list
.emplace_back ("b");
1471 list
.emplace_back ("c");
1473 SELF_CHECK (items_alive
== 3);
1475 expected
= { &a
, &b
};
1476 verify_items (list
, expected
);
1477 SELF_CHECK (items_alive
== 2);
1481 verify_items (list
, expected
);
1482 SELF_CHECK (items_alive
== 1);
1486 verify_items (list
, expected
);
1487 SELF_CHECK (items_alive
== 0);
1490 static void test_release ()
1493 std::vector
<const item_type
*> expected
;
1495 auto &a
= list
.emplace_back ("a");
1496 auto &b
= list
.emplace_back ("b");
1497 auto &c
= list
.emplace_back ("c");
1500 SELF_CHECK (items_alive
== 3);
1501 auto [next_it
, released
] = list
.release (list
.iterator_to (b
));
1502 SELF_CHECK (&*next_it
== &c
);
1503 expected
= { &a
, &c
};
1504 verify_items (list
, expected
);
1505 SELF_CHECK (items_alive
== 3);
1507 SELF_CHECK (items_alive
== 2);
1511 auto [next_it
, released
] = list
.release (list
.iterator_to (c
));
1512 SELF_CHECK (next_it
== list
.end ());
1514 verify_items (list
, expected
);
1515 SELF_CHECK (items_alive
== 2);
1517 SELF_CHECK (items_alive
== 1);
1521 auto [next_it
, released
] = list
.release (list
.iterator_to (a
));
1522 SELF_CHECK (next_it
== list
.end ());
1524 verify_items (list
, expected
);
1525 SELF_CHECK (items_alive
== 1);
1527 SELF_CHECK (items_alive
== 0);
1531 static void test_clear ()
1534 std::vector
<const item_type
*> expected
;
1536 list
.emplace_back ("a");
1537 list
.emplace_back ("b");
1538 list
.emplace_back ("c");
1540 SELF_CHECK (items_alive
== 3);
1543 verify_items (list
, expected
);
1544 SELF_CHECK (items_alive
== 0);
1546 /* Verify idempotency. */
1549 verify_items (list
, expected
);
1550 SELF_CHECK (items_alive
== 0);
1553 static void test_empty ()
1557 SELF_CHECK (list
.empty ());
1558 auto &a
= list
.emplace_back ("a");
1559 SELF_CHECK (!list
.empty ());
1560 list
.erase (list
.iterator_to (a
));
1561 SELF_CHECK (list
.empty ());
1564 static void test_begin_end ()
1567 const ListType
&clist
= list
;
1569 auto &a
= list
.emplace_back ("a");
1570 list
.emplace_back ("b");
1571 auto &c
= list
.emplace_back ("c");
1573 SELF_CHECK (&*list
.begin () == &a
);
1574 SELF_CHECK (&*list
.cbegin () == &a
);
1575 SELF_CHECK (&*clist
.begin () == &a
);
1576 SELF_CHECK (&*list
.rbegin () == &c
);
1577 SELF_CHECK (&*list
.crbegin () == &c
);
1578 SELF_CHECK (&*clist
.rbegin () == &c
);
1580 /* At least check that they compile. */
1590 template<typename ListType
>
1592 test_owning_intrusive_list_1 ()
1594 owning_intrusive_list_test
<ListType
> tests
;
1596 tests
.test_move_constructor ();
1597 tests
.test_move_assignment ();
1599 tests
.test_front_back ();
1600 tests
.test_push_front ();
1601 tests
.test_push_back ();
1602 tests
.test_insert ();
1603 tests
.test_emplace_front ();
1604 tests
.test_emplace_back ();
1605 tests
.test_emplace ();
1606 tests
.test_splice ();
1607 tests
.test_pop_front ();
1608 tests
.test_pop_back ();
1609 tests
.test_release ();
1610 tests
.test_clear ();
1611 tests
.test_empty ();
1612 tests
.test_begin_end ();
1616 test_node_is_linked ()
1619 item_with_base
a ("a");
1620 item_with_base_list list
;
1622 SELF_CHECK (!a
.is_linked ());
1624 SELF_CHECK (a
.is_linked ());
1626 SELF_CHECK (!a
.is_linked ());
1630 item_with_member
a ("a");
1631 item_with_member_list list
;
1633 SELF_CHECK (!a
.node
.is_linked ());
1635 SELF_CHECK (a
.node
.is_linked ());
1637 SELF_CHECK (!a
.node
.is_linked ());
1642 test_intrusive_list ()
1644 test_intrusive_list_1
<item_with_base_list
> ();
1645 test_intrusive_list_1
<item_with_member_list
> ();
1646 test_owning_intrusive_list_1
<item_with_base_owning_list
> ();
1647 test_owning_intrusive_list_1
<item_with_member_owning_list
> ();
1648 test_node_is_linked ();
1651 void _initialize_intrusive_list_selftests ();
1654 _initialize_intrusive_list_selftests ()
1656 selftests::register_test ("intrusive_list", test_intrusive_list
);