2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file forward_list.h Forward list implementation. */
10 #ifndef FORWARD_LIST_H
11 #define FORWARD_LIST_H
15 * @tparam T The type of the objects in the list.
16 * @tparam S Unused; can be used to disambiguate the class if you need to
17 * derive twice from it.
19 template <class T
, typename S
= void>
20 struct ForwardListLink
{
25 ForwardListLink() : next(NULL
) { }
27 ForwardListLink (const ForwardListLink
&) : next(NULL
) { }
29 ForwardListLink
& operator = (const ForwardListLink
&)
37 * Implementation of a generic forward list.
39 * We have a hand-written implementation of a forward list for the following
42 * 1. std::forward_list is not in C++98, and we still support some compilers
43 * that do not implement C++11.
45 * 2. The implementation of a forward list below has the next element pointer
46 * embedded in the struct, and it must be defined by the struct itself. This
47 * allows a struct to be part of more than one list at the same time.
49 * @tparam TLink The link type; must derive from ForwardListLink.
51 template <class TLink
>
54 typedef typename
Link::Type Type
;
58 ForwardList() : head(NULL
) { }
60 ForwardList (const ForwardList
&) DELETED
;
61 ForwardList
& operator = (const ForwardList
&) DELETED
;
64 /** Internal find function. */
65 Type
**find_internal (const Type
*t
)
68 while (*p
!= NULL
&& *p
!= t
) {
69 p
= &(*p
)->Link::next
;
74 /** Internal find tail function. */
75 Type
**find_tail (void)
77 return find_internal (NULL
);
80 /** Internal predicate-based find function. */
82 Type
**find_pred_internal (Pred pred
)
85 while (*p
!= NULL
&& !pred((const Type
*)(*p
))) {
86 p
= &(*p
)->Link::next
;
91 /** Internal remove function. */
92 Type
*remove_internal (Type
**p
)
95 if (r
== NULL
) return NULL
;
101 /** Internal detach function. */
102 Type
*detach_internal (Type
**p
)
105 if (r
== NULL
) return NULL
;
111 /** Append an item or chain of items. */
112 void append (Type
*t
)
117 /** Prepend an item. */
118 void prepend (Type
*t
)
120 assert (t
->Link::next
== NULL
);
121 t
->Link::next
= head
;
126 Type
*find (const Type
*t
)
128 return *find_internal(t
);
132 template <class Pred
>
133 Type
*find_pred (Pred pred
)
135 return *find_pred_internal(pred
);
138 /** Remove an item. */
139 Type
*remove (const Type
*t
)
141 return remove_internal (find_internal (t
));
144 /** Remove an item. */
145 template <class Pred
>
146 Type
*remove_pred (Pred pred
)
148 return remove_internal (find_pred_internal (pred
));
151 /** Detach an item chain. */
152 Type
*detach (const Type
*t
)
154 return detach_internal (find_internal (t
));
157 /** Detach an item chain. */
158 template <class Pred
>
159 Type
*detach_pred (Pred pred
)
161 return detach_internal (find_pred_internal (pred
));
164 /** Detach the whole list. */
165 Type
*detach_all (void)
173 #endif /* FORWARD_LIST_H */