1 /**
2  * @file
3  * @brief LINKED LIST interface
4  */
5 
6 /*
7 Copyright (C) 2002-2013 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23 
24 */
25 
26 #pragma once
27 
28 #include "../shared/ufotypes.h"
29 
30 struct linkedList_t {
31 	void*         data;
32 	linkedList_t* next;
33 	bool      ptr; /**< don't call Mem_Free for data if this is @c true */
34 };
35 
36 typedef int (*linkedListSort_t) (linkedList_t* entry1, linkedList_t* entry2, const void* userData);
37 
38 /** @brief Iterates over a linked list, it's safe to delete the returned entry from the list while looping over it.
39  * @note @c var must be a simple variable name, because it is declared in the loop macro and is also used to create the name of the internal variables.
40  * @note Don't try to use the internal loop variable. This variable is most likely not at the position you would expect it to be. */
41 #define LIST_Foreach(list, type, var) \
42 	for (bool var##__break = false, var##__once = true; var##__once; var##__once = false) \
43 		for (linkedList_t const* var##__iter = (list); !var##__break && var##__iter;) \
44 			for (type* const var = (var##__break = var##__once = true, static_cast<type*>(var##__iter->data)); var##__once; var##__break = var##__once = false) \
45 				if (var##__iter = var##__iter->next, false) {} else
46 
47 /**
48  * @brief Will sort the list before loop over the sorted list. Make sure the free the sortedList after you done with the loop.
49  */
50 #define LIST_ForeachSorted(list, type, var, sorter, userdata, sortedlist) \
51 	sortedlist = LIST_CopyStructure(list); \
52 	LIST_Sort(&sortedlist, sorter, userdata); \
53 	LIST_Foreach(sortedlist, type, var)
54 
55 void LIST_PrependString(linkedList_t** listDest, const char* data);
56 void LIST_AddString(linkedList_t** list, const char* data);
57 void LIST_AddStringSorted(linkedList_t** listDest, const char* data);
58 void LIST_AddPointer(linkedList_t** listDest, void* data);
59 linkedList_t* LIST_Add(linkedList_t** list, void const* data, size_t length);
60 const linkedList_t* LIST_ContainsString(const linkedList_t* list, const char* string);
61 linkedList_t* LIST_GetPointer(linkedList_t* list, const void* data);
62 void LIST_Delete(linkedList_t** list);
63 bool LIST_RemoveEntry(linkedList_t** list, linkedList_t* entry);
64 bool LIST_IsEmpty(const linkedList_t* list);
65 int LIST_Count(const linkedList_t* list);
66 linkedList_t* LIST_CopyStructure(linkedList_t* src);
67 void* LIST_GetByIdx(linkedList_t* list, int index);
68 bool LIST_Remove(linkedList_t** list, const void* data);
69 void LIST_Sort(linkedList_t** list, linkedListSort_t sorter, const void* userData);
70 void* LIST_GetRandom(linkedList_t* list);
71 
72 /**
73  * Add a copy of data to list and return a reference to the copied data.
74  */
LIST_Add(linkedList_t ** const list,T const & data)75 template<typename T> inline T& LIST_Add(linkedList_t** const list, T const& data)
76 {
77 	return *static_cast<T*>(LIST_Add(list, &data, sizeof(data))->data);
78 }
79