Jlm
Loading...
Searching...
No Matches
IntrusiveListTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 Helge Bahmann <hcb@chaoticmind.net>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
9
10struct MyItem
11{
13 : p(nullptr)
14 {}
15
16 explicit MyItem(int * ptr)
17 : p(ptr)
18 {}
19
21 {
22 if (p)
23 {
24 *p = 0;
25 }
26 }
27
28 int * p;
31};
32
35
36TEST(IntrusiveListTests, test_simple_list)
37{
38 my_list l;
39
40 EXPECT_TRUE(l.empty());
41 MyItem i1, i2, i3;
42
43 l.push_back(&i2);
44 EXPECT_EQ(l.begin().ptr(), &i2);
45 EXPECT_EQ(std::next(l.begin()), l.end());
46 EXPECT_EQ(std::prev(l.end()).ptr(), &i2);
47
48 l.insert(l.begin(), &i1);
49 EXPECT_EQ(l.begin().ptr(), &i1);
50 EXPECT_EQ(std::next(l.begin()).ptr(), &i2);
51 EXPECT_EQ(std::next(l.begin(), 2), l.end());
52 EXPECT_EQ(std::prev(l.end()).ptr(), &i2);
53
54 l.insert(l.end(), &i3);
55 EXPECT_EQ(l.begin().ptr(), &i1);
56 EXPECT_EQ(std::next(l.begin()).ptr(), &i2);
57 EXPECT_EQ(std::next(l.begin(), 2).ptr(), &i3);
58 EXPECT_EQ(std::next(l.begin(), 3), l.end());
59 EXPECT_EQ(std::prev(l.end()).ptr(), &i3);
60 EXPECT_EQ(std::prev(l.end(), 2).ptr(), &i2);
61 EXPECT_EQ(std::prev(l.end(), 3).ptr(), &i1);
62
63 l.erase(&i2);
64 EXPECT_EQ(l.begin().ptr(), &i1);
65 EXPECT_EQ(std::next(l.begin()).ptr(), &i3);
66 EXPECT_EQ(std::next(l.begin(), 2), l.end());
67 EXPECT_EQ(std::prev(l.end()).ptr(), &i3);
68 EXPECT_EQ(std::prev(l.end(), 2).ptr(), &i1);
69
70 my_list l2;
71 l2.splice(l2.begin(), l);
72 EXPECT_TRUE(l.empty());
73 EXPECT_EQ(l2.size(), 2u);
74}
75
76TEST(IntrusiveListTests, test_owner_list)
77{
78 int v1 = 1;
79 int v2 = 2;
80 int v3 = 3;
81
82 {
84
85 EXPECT_TRUE(l.empty());
86
87 l.push_back(std::unique_ptr<MyItem>(new MyItem(&v2)));
88 EXPECT_EQ(l.begin()->p, &v2);
89 EXPECT_EQ(std::next(l.begin()), l.end());
90 EXPECT_EQ(std::prev(l.end())->p, &v2);
91
92 l.insert(l.begin(), std::unique_ptr<MyItem>(new MyItem(&v1)));
93 EXPECT_EQ(l.begin()->p, &v1);
94 EXPECT_EQ(std::next(l.begin())->p, &v2);
95 EXPECT_EQ(std::next(l.begin(), 2), l.end());
96 EXPECT_EQ(std::prev(l.end())->p, &v2);
97
98 l.insert(l.end(), std::unique_ptr<MyItem>(new MyItem(&v3)));
99 EXPECT_EQ(l.begin()->p, &v1);
100 EXPECT_EQ(std::next(l.begin())->p, &v2);
101 EXPECT_EQ(std::next(l.begin(), 2)->p, &v3);
102 EXPECT_EQ(std::next(l.begin(), 3), l.end());
103 EXPECT_EQ(std::prev(l.end())->p, &v3);
104 EXPECT_EQ(std::prev(l.end(), 2)->p, &v2);
105 EXPECT_EQ(std::prev(l.end(), 3)->p, &v1);
106
107 l.erase(std::next(l.begin()));
108 EXPECT_EQ(v1, 1);
109 EXPECT_EQ(v2, 0); // destructor should have been called
110 EXPECT_EQ(v3, 3);
111
112 EXPECT_EQ(l.begin()->p, &v1);
113 EXPECT_EQ(std::next(l.begin())->p, &v3);
114 EXPECT_EQ(std::next(l.begin(), 2), l.end());
115 EXPECT_EQ(std::prev(l.end())->p, &v3);
116 EXPECT_EQ(std::prev(l.end(), 2)->p, &v1);
117
118 std::unique_ptr<MyItem> i = l.unlink(l.begin());
119 EXPECT_EQ(v1, 1); // destructor not invoked, transferred ownership
120 EXPECT_EQ(v2, 0);
121 EXPECT_EQ(v3, 3);
122
123 i.reset();
124 EXPECT_EQ(v1, 0); // destructor called now
125
126 EXPECT_EQ(l.begin()->p, &v3);
127 EXPECT_EQ(std::next(l.begin()), l.end());
128 EXPECT_EQ(std::prev(l.end())->p, &v3);
129
130 my_owner_list l2;
131 l2.splice(l2.begin(), l);
132 EXPECT_EQ(l.size(), 0u);
133 EXPECT_EQ(l2.size(), 1u);
134 }
135 EXPECT_EQ(v3, 0);
136}
jlm::util::OwnerIntrusiveList< MyItem, MyItem::accessor > my_owner_list
TEST(IntrusiveListTests, test_simple_list)
jlm::util::IntrusiveList< MyItem, MyItem::accessor > my_list
ElementType * ptr() const noexcept
Iterator end() noexcept
bool empty() const noexcept
void erase(ElementType *element) noexcept
void splice(Iterator position, IntrusiveList &other) noexcept
size_type size() const noexcept
Iterator insert(Iterator i, ElementType *element) noexcept
Iterator begin() noexcept
void push_back(ElementType *element) noexcept
void splice(Iterator position, OwnerIntrusiveList &other) noexcept
void erase(ElementType *element) noexcept
std::unique_ptr< ElementType > unlink(Iterator i) noexcept
Iterator insert(Iterator i, std::unique_ptr< ElementType > element) noexcept
void push_back(std::unique_ptr< ElementType > element) noexcept
size_type size() const noexcept
struct MyItem::@0 nullptr
jlm::util::IntrusiveListAccessor< MyItem, &MyItem::anchor > accessor
MyItem(int *ptr)
jlm::util::IntrusiveListAnchor< MyItem > anchor