-
Notifications
You must be signed in to change notification settings - Fork 3
/
embedded-list.cpp
199 lines (158 loc) · 4.98 KB
/
embedded-list.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <iostream>
#include <cassert>
#include <dstruct.hpp>
// g++ -Ilibs/DStruct common/embedded-list.cpp && ./a.out
// C-Style
struct IntList {
int data;
struct IntList *next;
};
void IntList_init(struct IntList *list);
bool IntList_empty(struct IntList *list);
void IntList_add(struct IntList *prev, struct IntList *curr);
void IntList_del(struct IntList *prev, struct IntList *curr);
struct DoubleList {
double data;
struct DoubleList *next;
};
void DoubleList_init(struct DoubleList *list);
bool DoubleList_empty(struct DoubleList *list);
void DoubleList_add(struct DoubleList *prev, struct DoubleList *curr);
void DoubleList_del(struct DoubleList *prev, struct DoubleList *curr);
// Embedded
struct Student {
char *name;
int age;
};
struct StudentListNode {
dstruct::_SinglyLink linker; // 链表链接器
char *name;
int age;
};
struct _StudentListNode {
struct _StudentListNode *next; // 链表链接器
Student student;
};
struct MyList {
int a;
dstruct::_SinglyLink linker;
double b;
char c;
};
using MyListNode = MyList;
// 成员地址-相对偏移
#define offset_of(StructType, member) ((size_t)&((StructType *)0)->member)
// Linker视角转节点视角: 通过成员地址 获取完整结构体类型
#define to_node(linkPtr, StructType, member) \
( \
(StructType *)( (char *)linkPtr - offset_of(StructType, member) ) \
)
// 节点视角转linker视角:
#define to_link(nodePtr) (&((nodePtr)->linker))
int main() {
// example1: Generic-Style / C-No-Generic-Style
dstruct::SLinkedList<int> intList1;
struct IntList intList2;
dstruct::SLinkedList<double> doubleList1;
struct IntList doubleList2;
// example2: embedded DS
dstruct::SLinkedList<Student> studentList1;
dstruct::_SinglyLink studentList2;
dstruct::_SinglyLink::init(&studentList2);
StudentListNode sNode;
dstruct::_SinglyLink::add(&studentList2, &(sNode.linker));
// example3
// 创建&初始化链表
MyList myList;
dstruct::_SinglyLink::init(to_link(&myList));
// 初始化node并添加到链表
for (int i = 0; i < 10; i++) {
// 分配内存
MyListNode *node = (MyListNode *) malloc(sizeof(MyListNode));
// 初始化
node->a = i;
node->b = 0.5 + i;
node->c = 'a' + i;
// 添加到链表(头插法)
dstruct::_SinglyLink::add(to_link(&myList), to_link(node));
}
assert(!dstruct::_SinglyLink::empty(to_link(&myList)));
// 遍历节点 访问数据 并释放节点
auto linkPtr = to_link(&myList)->next; // 获取第一个节点地址
for (; linkPtr != to_link(&myList); linkPtr = linkPtr->next) {
auto nodePtr = to_node(linkPtr, MyListNode, linker); // 1.转成节点指针
printf("%d %f %c\n", nodePtr->a, nodePtr->b, nodePtr->c); // 2.访问数据
}
// 释放链表
linkPtr = to_link(&myList)->next;
while (dstruct::_SinglyLink::empty(to_link(&myList))) {
auto next = linkPtr->next;
free(to_node(linkPtr, MyListNode, linker));
linkPtr = next;
}
// example4
/*{
IntList intList;
// build
IntList_init(&intList);
for (int i = 0; i < 10; i++) {
// 分配内存
IntList *node = (IntList *) malloc(sizeof(IntList));
// 初始化
node->data = i;
// 添加到链表(头插法)
IntList_add(&intList, node);
}
// access
for (IntList *node = intList.next; node != &intList; node = node->next) {
printf("%d\n", node->data);
}
// release
while (!IntList_empty(&intList)) {
IntList *node = intList.next;
intList.next = node->next;
free(node);
}
}*/
{
dstruct::SLinkedList<int> intList;
// build
for (int i = 0; i < 10; i++) {
intList.push_back(i);
}
// access
for (auto v : intList) {
printf("%d\n", v);
}
// auto-release memory
// ...
}
{
struct IntList {
dstruct::_SinglyLink linker;
int data;
};
dstruct::_SinglyLink intList;
// build
dstruct::_SinglyLink::init(&intList);
for (int i = 0; i < 10; i++) {
// 分配内存
IntList *node = (IntList *) malloc(sizeof(IntList));
node->data = i; // 初始化
// 添加到链表(头插法)
dstruct::_SinglyLink::add(&intList, to_link(node));
}
// access
for (auto *linkPtr = intList.next; linkPtr != &intList; linkPtr = linkPtr->next) {
IntList *node = to_node(linkPtr, IntList, linker);
printf("%d\n", node->data);
}
// release
while (!dstruct::_SinglyLink::empty(&intList)) {
IntList *node = to_node(intList.next, IntList, linker);
intList.next = node->linker.next;
free(node);
}
}
return 0;
}