Jlm
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 
10 struct 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 
36 TEST(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 
76 TEST(IntrusiveListTests, test_owner_list)
77 {
78  int v1 = 1;
79  int v2 = 2;
80  int v3 = 3;
81 
82  {
83  my_owner_list l;
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
std::unique_ptr< ElementType > unlink(Iterator i) noexcept
void erase(ElementType *element) noexcept
bool empty() const 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