8 // Linked lists with nodes embedded in the data.
10 // Duplicating for auto-init is ugly, but at least it's implementation
11 // ugliness; inheriting would cause interface ugliness, with users
12 // required to either declare ListAutoInit for the vastly common case,
13 // or else use ListNoAutoInit pointers when following prev or next.
15 // Maybe some sort of templatization could be done.
17 struct ListNoAutoInit {
18 ListNoAutoInit *prev, *next;
37 void add_front(ListNoAutoInit *newelem)
39 assert(newelem->empty());
47 void add_back(ListNoAutoInit *newelem)
49 assert(newelem->empty());
57 template<typename T, int offset>
60 return reinterpret_cast<T *>(reinterpret_cast<ulong>(this) - offset);
89 void add_front(List *newelem)
91 assert(newelem->empty());
99 void add_back(List *newelem)
101 assert(newelem->empty());
103 newelem->next = this;
104 prev->next = newelem;
105 newelem->prev = prev;
109 template<typename T, int offset>
112 return reinterpret_cast<T *>(reinterpret_cast<ulong>(this) - offset);
116 // Ick. We can't pass in "member" as a template parameter, and
117 // it'd be annoying to have to manually use offsetof all over
118 // the place. Use this as if it were a member function, but
119 // be careful of the global name.
121 #define listentry(T, member) entry<T, offsetof(T, member)>()