21#include "gdbsupport/intrusive_list.h"
22#include "gdbsupport/selftest.h"
23#include <unordered_set>
35 public intrusive_list_node<item_with_base>
57 intrusive_list_node<item_with_member>
node;
61 = intrusive_member_node<item_with_member, &item_with_member::node>;
63 = intrusive_list<item_with_member, item_with_member_node>;
69template <
typename ListType>
72 using item_type =
typename ListType::value_type;
80 gdb::array_view<const typename ListType::value_type *> expected)
84 for (
typename ListType::iterator it = list.begin ();
90 SELF_CHECK (i < expected.size ());
91 SELF_CHECK (&item == expected[i]);
96 SELF_CHECK (i == expected.size ());
98 for (
typename ListType::reverse_iterator it = list.rbegin ();
107 SELF_CHECK (&item == expected[i]);
120 std::vector<const item_type *> expected;
126 ListType list2 (std::move (list1));
131 expected = {&a, &b, &c};
139 std::vector<const item_type *> expected;
143 ListType list2 (std::move (list1));
155 std::vector<const item_type *> expected;
157 ListType list2 (std::move (list1));
172 item_type a (
"a"), b (
"b"), c (
"c"), d (
"d"), e (
"e");
175 std::vector<const item_type *> expected;
184 list2 = std::move (list1);
189 expected = {&a, &b, &c};
198 std::vector<const item_type *> expected;
204 list2 = std::move (list1);
218 std::vector<const item_type *> expected;
224 list2 = std::move (list1);
229 expected = {&a, &b, &c};
238 std::vector<const item_type *> expected;
243 list2 = std::move (list1);
256 std::vector<const item_type *> expected;
258 list2 = std::move (list1);
273 item_type a (
"a"), b (
"b"), c (
"c"), d (
"d"), e (
"e");
276 std::vector<const item_type *> expected;
285 std::swap (list1, list2);
290 expected = {&a, &b, &c};
299 std::vector<const item_type *> expected;
305 std::swap (list1, list2);
310 expected = {&a, &b, &c};
319 std::vector<const item_type *> expected;
325 std::swap (list1, list2);
327 expected = {&a, &b, &c};
338 std::vector<const item_type *> expected;
340 std::swap (list1, list2);
354 std::vector<const item_type *> expected;
358 std::swap (list1, list2);
366 std::swap (list1, list2);
381 const ListType &clist = list;
387 SELF_CHECK (&list.front () == &a);
388 SELF_CHECK (&clist.front () == &a);
389 SELF_CHECK (&list.back () == &c);
390 SELF_CHECK (&clist.back () == &c);
398 std::vector<const item_type *> expected;
412 expected = {&c, &b, &a};
421 std::vector<const item_type *> expected;
435 expected = {&a, &b, &c};
442 std::vector<const item_type *> expected;
450 list.insert (list.begin (), a);
454 list.insert (list.begin (), b);
458 list.insert (list.begin (), c);
459 expected = {&c, &b, &a};
469 list.insert (list.end (), a);
473 list.insert (list.end (), b);
477 list.insert (list.end (), c);
478 expected = {&a, &b, &c};
490 list.insert (list.iterator_to (b), c);
491 expected = {&a, &c, &b};
500 list.insert (list.end (), a);
511 item_type a (
"a"), b (
"b"), c (
"c"), d (
"d"), e (
"e");
514 std::vector<const item_type *> expected;
523 list1.splice (std::move (list2));
525 expected = {&a, &b, &c, &d, &e};
537 std::vector<const item_type *> expected;
543 list1.splice (std::move (list2));
545 expected = {&a, &b, &c};
557 std::vector<const item_type *> expected;
563 list1.splice (std::move (list2));
565 expected = {&a, &b, &c};
577 std::vector<const item_type *> expected;
579 list1.splice (std::move (list2));
594 std::vector<const item_type *> expected;
618 std::vector<const item_type *> expected;
642 std::vector<const item_type *> expected;
648 list.erase (list.iterator_to (b));
652 list.erase (list.iterator_to (c));
656 list.erase (list.iterator_to (a));
666 std::vector<const item_type *> expected;
687 std::vector<const item_type *> expected;
688 std::unordered_set<const item_type *> disposer_seen;
689 int disposer_calls = 0;
695 auto disposer = [&] (
const item_type *item)
697 disposer_seen.insert (item);
700 list.clear_and_dispose (disposer);
704 SELF_CHECK (disposer_calls == 3);
705 SELF_CHECK (disposer_seen.find (&a) != disposer_seen.end ());
706 SELF_CHECK (disposer_seen.find (&b) != disposer_seen.end ());
707 SELF_CHECK (disposer_seen.find (&c) != disposer_seen.end ());
710 list.clear_and_dispose (disposer);
711 SELF_CHECK (disposer_calls == 3);
720 SELF_CHECK (list.empty ());
722 SELF_CHECK (!list.empty ());
723 list.erase (list.iterator_to (a));
724 SELF_CHECK (list.empty ());
732 const ListType &clist = list;
738 SELF_CHECK (&*list.begin () == &a);
739 SELF_CHECK (&*list.cbegin () == &a);
740 SELF_CHECK (&*clist.begin () == &a);
741 SELF_CHECK (&*list.rbegin () == &c);
742 SELF_CHECK (&*list.crbegin () == &c);
743 SELF_CHECK (&*clist.rbegin () == &c);
755template <
typename ListType>
785 SELF_CHECK (!a.is_linked ());
787 SELF_CHECK (a.is_linked ());
789 SELF_CHECK (!a.is_linked ());
796 SELF_CHECK (!a.
node.is_linked ());
798 SELF_CHECK (a.
node.is_linked ());
800 SELF_CHECK (!a.
node.is_linked ());
807 test_intrusive_list_1<item_with_base_list> ();
808 test_intrusive_list_1<item_with_member_list> ();
816 selftests::register_test
static void test_node_is_linked()
intrusive_member_node< item_with_member, &item_with_member::node > item_with_member_node
static void test_intrusive_list_1()
static void test_intrusive_list()
void _initialize_intrusive_list_selftests()
intrusive_list< item_with_member, item_with_member_node > item_with_member_list
intrusive_list< item_with_base > item_with_base_list
static void test_begin_end()
static void test_front_back()
static void test_move_assignment()
static void test_insert()
static void test_clear_and_dispose()
static void test_pop_back()
typename ListType::value_type item_type
static void test_push_front()
static void test_move_constructor()
static void verify_items(const ListType &list, gdb::array_view< const typename ListType::value_type * > expected)
static void test_push_back()
static void test_pop_front()
static void test_splice()
item_with_base(const char *name)
intrusive_list_node< item_with_member > node
item_with_member(const char *name)