xref: /haiku/src/tests/system/kernel/util/SinglyLinkedListTest.cpp (revision 77b1fd224322628748a663de467af3775a474690)
1*77b1fd22SAxel Dörfler #include <cppunit/Test.h>
2*77b1fd22SAxel Dörfler #include <cppunit/TestCaller.h>
3*77b1fd22SAxel Dörfler #include <cppunit/TestSuite.h>
4*77b1fd22SAxel Dörfler #include <stdio.h>
5*77b1fd22SAxel Dörfler #include <TestUtils.h>
6*77b1fd22SAxel Dörfler 
7*77b1fd22SAxel Dörfler #include "SinglyLinkedListTest.h"
8*77b1fd22SAxel Dörfler #include "SinglyLinkedList.h"
9*77b1fd22SAxel Dörfler 
10*77b1fd22SAxel Dörfler SinglyLinkedListTest::SinglyLinkedListTest(std::string name)
11*77b1fd22SAxel Dörfler 	: BTestCase(name)
12*77b1fd22SAxel Dörfler {
13*77b1fd22SAxel Dörfler }
14*77b1fd22SAxel Dörfler 
15*77b1fd22SAxel Dörfler CppUnit::Test*
16*77b1fd22SAxel Dörfler SinglyLinkedListTest::Suite() {
17*77b1fd22SAxel Dörfler 	CppUnit::TestSuite *suite = new CppUnit::TestSuite("SLL");
18*77b1fd22SAxel Dörfler 
19*77b1fd22SAxel Dörfler 	suite->addTest(new CppUnit::TestCaller<SinglyLinkedListTest>("SinglyLinkedList::User Strategy Test (default next parameter)", &SinglyLinkedListTest::UserDefaultTest));
20*77b1fd22SAxel Dörfler 	suite->addTest(new CppUnit::TestCaller<SinglyLinkedListTest>("SinglyLinkedList::User Strategy Test (custom next parameter)", &SinglyLinkedListTest::UserCustomTest));
21*77b1fd22SAxel Dörfler 	suite->addTest(new CppUnit::TestCaller<SinglyLinkedListTest>("SinglyLinkedList::Auto Strategy Test (MallocFreeAllocator)", &SinglyLinkedListTest::AutoTest));
22*77b1fd22SAxel Dörfler 
23*77b1fd22SAxel Dörfler 	return suite;
24*77b1fd22SAxel Dörfler }
25*77b1fd22SAxel Dörfler 
26*77b1fd22SAxel Dörfler // Class used for testing default User strategy
27*77b1fd22SAxel Dörfler class Link {
28*77b1fd22SAxel Dörfler public:
29*77b1fd22SAxel Dörfler 	Link* next;
30*77b1fd22SAxel Dörfler 	long data;
31*77b1fd22SAxel Dörfler 
32*77b1fd22SAxel Dörfler 	bool operator==(const Link &ref) {
33*77b1fd22SAxel Dörfler 		return data == ref.data;
34*77b1fd22SAxel Dörfler 	}
35*77b1fd22SAxel Dörfler };
36*77b1fd22SAxel Dörfler 
37*77b1fd22SAxel Dörfler // Class used for testing custom User strategy
38*77b1fd22SAxel Dörfler class MyLink {
39*77b1fd22SAxel Dörfler public:
40*77b1fd22SAxel Dörfler 	MyLink* mynext;
41*77b1fd22SAxel Dörfler 	long data;
42*77b1fd22SAxel Dörfler 
43*77b1fd22SAxel Dörfler 	bool operator==(const MyLink &ref) {
44*77b1fd22SAxel Dörfler 		return data == ref.data;
45*77b1fd22SAxel Dörfler 	}
46*77b1fd22SAxel Dörfler };
47*77b1fd22SAxel Dörfler 
48*77b1fd22SAxel Dörfler using Strategy::SinglyLinkedList::User;
49*77b1fd22SAxel Dörfler using Strategy::SinglyLinkedList::Auto;
50*77b1fd22SAxel Dörfler 
51*77b1fd22SAxel Dörfler //! Tests the given list
52*77b1fd22SAxel Dörfler template <class List>
53*77b1fd22SAxel Dörfler void
54*77b1fd22SAxel Dörfler SinglyLinkedListTest::TestList(List &list, typename List::ValueType *values, int valueCount)
55*77b1fd22SAxel Dörfler {
56*77b1fd22SAxel Dörfler 	list.MakeEmpty();
57*77b1fd22SAxel Dörfler 
58*77b1fd22SAxel Dörfler 	// PushFront
59*77b1fd22SAxel Dörfler 	for (int i = 0; i < valueCount; i++) {
60*77b1fd22SAxel Dörfler 		NextSubTest();
61*77b1fd22SAxel Dörfler 		CHK(list.Count() == i);
62*77b1fd22SAxel Dörfler 		CHK(list.PushFront(values[i]) == B_OK);
63*77b1fd22SAxel Dörfler 		CHK(list.Count() == i+1);
64*77b1fd22SAxel Dörfler 	}
65*77b1fd22SAxel Dörfler 
66*77b1fd22SAxel Dörfler {
67*77b1fd22SAxel Dörfler 	// Prefix increment
68*77b1fd22SAxel Dörfler 	int preIndex = valueCount-1;
69*77b1fd22SAxel Dörfler 	typename List::Iterator iterator;
70*77b1fd22SAxel Dörfler 	for (iterator = list.Begin(); iterator != list.End(); --preIndex) {
71*77b1fd22SAxel Dörfler 		NextSubTest();
72*77b1fd22SAxel Dörfler // 		printf("(%p, %ld) %s (%p, %ld)\n", iterator->next, iterator->data, ((*iterator == values[preIndex]) ? "==" : "!="), values[preIndex].next, values[preIndex].data);
73*77b1fd22SAxel Dörfler 		CHK(*iterator == values[preIndex]);
74*77b1fd22SAxel Dörfler 		typename List::Iterator copy = iterator;
75*77b1fd22SAxel Dörfler 		CHK(copy == iterator);
76*77b1fd22SAxel Dörfler 		CHK(copy != ++iterator);
77*77b1fd22SAxel Dörfler 	}
78*77b1fd22SAxel Dörfler 	CHK(preIndex == -1);
79*77b1fd22SAxel Dörfler }
80*77b1fd22SAxel Dörfler 	list.MakeEmpty();
81*77b1fd22SAxel Dörfler 
82*77b1fd22SAxel Dörfler 	// PushBack
83*77b1fd22SAxel Dörfler 	for (int i = 0; i < valueCount; i++) {
84*77b1fd22SAxel Dörfler 		NextSubTest();
85*77b1fd22SAxel Dörfler 		CHK(list.Count() == i);
86*77b1fd22SAxel Dörfler 		CHK(list.PushBack(values[i]) == B_OK);
87*77b1fd22SAxel Dörfler 		CHK(list.Count() == i+1);
88*77b1fd22SAxel Dörfler 	}
89*77b1fd22SAxel Dörfler 
90*77b1fd22SAxel Dörfler 	// Postfix increment
91*77b1fd22SAxel Dörfler 	int postIndex = 0;
92*77b1fd22SAxel Dörfler 	for (typename List::Iterator iterator = list.Begin(); iterator != list.End(); ++postIndex) {
93*77b1fd22SAxel Dörfler 		NextSubTest();
94*77b1fd22SAxel Dörfler // 		printf("(%p, %ld) %s (%p, %ld)\n", iterator->next, iterator->data, ((*iterator == values[postIndex]) ? "==" : "!="), values[postIndex].next, values[postIndex].data);
95*77b1fd22SAxel Dörfler 		CHK(*iterator == values[postIndex]);
96*77b1fd22SAxel Dörfler 		typename List::Iterator copy = iterator;
97*77b1fd22SAxel Dörfler 		CHK(copy == iterator);
98*77b1fd22SAxel Dörfler 		CHK(copy == iterator++);
99*77b1fd22SAxel Dörfler 	}
100*77b1fd22SAxel Dörfler 	CHK(postIndex == valueCount);
101*77b1fd22SAxel Dörfler 
102*77b1fd22SAxel Dörfler }
103*77b1fd22SAxel Dörfler 
104*77b1fd22SAxel Dörfler //! Test using the User strategy with the default NextMember.
105*77b1fd22SAxel Dörfler void
106*77b1fd22SAxel Dörfler SinglyLinkedListTest::UserDefaultTest() {
107*77b1fd22SAxel Dörfler 	SinglyLinkedList<Link, User<Link> > list;
108*77b1fd22SAxel Dörfler 	const int valueCount = 10;
109*77b1fd22SAxel Dörfler 	Link values[valueCount];
110*77b1fd22SAxel Dörfler 	for (int i = 0; i < valueCount; i++) {
111*77b1fd22SAxel Dörfler 		values[i].data = i;
112*77b1fd22SAxel Dörfler 		if (i % 2)
113*77b1fd22SAxel Dörfler 			values[i].next = NULL;	// Leave some next pointers invalid just for fun
114*77b1fd22SAxel Dörfler 	}
115*77b1fd22SAxel Dörfler 
116*77b1fd22SAxel Dörfler 	TestList(list, values, valueCount);
117*77b1fd22SAxel Dörfler }
118*77b1fd22SAxel Dörfler 
119*77b1fd22SAxel Dörfler //! Test using the User strategy with a custom NextMember.
120*77b1fd22SAxel Dörfler void
121*77b1fd22SAxel Dörfler SinglyLinkedListTest::UserCustomTest() {
122*77b1fd22SAxel Dörfler 	SinglyLinkedList<MyLink, User<MyLink, &MyLink::mynext> > list;
123*77b1fd22SAxel Dörfler 	const int valueCount = 10;
124*77b1fd22SAxel Dörfler 	MyLink values[valueCount];
125*77b1fd22SAxel Dörfler 	for (int i = 0; i < valueCount; i++) {
126*77b1fd22SAxel Dörfler 		values[i].data = i*2;
127*77b1fd22SAxel Dörfler 		if (!(i % 2))
128*77b1fd22SAxel Dörfler 			values[i].mynext = NULL;	// Leave some next pointers invalid just for fun
129*77b1fd22SAxel Dörfler 	}
130*77b1fd22SAxel Dörfler 
131*77b1fd22SAxel Dörfler 	TestList(list, values, valueCount);
132*77b1fd22SAxel Dörfler }
133*77b1fd22SAxel Dörfler 
134*77b1fd22SAxel Dörfler //! Test using the Auto strategy.
135*77b1fd22SAxel Dörfler void
136*77b1fd22SAxel Dörfler SinglyLinkedListTest::AutoTest() {
137*77b1fd22SAxel Dörfler 	SinglyLinkedList<long> list;
138*77b1fd22SAxel Dörfler 	const int valueCount = 10;
139*77b1fd22SAxel Dörfler 	long values[valueCount];
140*77b1fd22SAxel Dörfler 	for (int i = 0; i < valueCount; i++) {
141*77b1fd22SAxel Dörfler 		values[i] = i*3;
142*77b1fd22SAxel Dörfler 	}
143*77b1fd22SAxel Dörfler 
144*77b1fd22SAxel Dörfler 	TestList(list, values, valueCount);
145*77b1fd22SAxel Dörfler }
146