Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
List.c File Reference
#include "Config.h"
#include <assert.h>
#include <stdlib.h>
#include "List.h"

Go to the source code of this file.

Macros

#define _Class   _List
 

Functions

Class_List (void)
 
static void _remove (List *self, const ident element)
 
static void _sort (List *self, Comparator comparator)
 
static void append (List *self, const ident element)
 
static bool contains (const List *self, const ident element)
 
static void dealloc (Object *self)
 
static void enumerate (const List *self, ListEnumerator enumerator, ident element)
 
static void filter (List *self, Predicate predicate, ident data)
 
static ListfilteredList (const List *self, Predicate predicate, ident data)
 
static ident find (const List *self, Predicate predicate, ident data)
 
static Listinit (List *self)
 
static void initialize (Class *clazz)
 
static void insertAfter (List *self, ListNode *node, const ident element)
 
static void map (List *self, Functor functor, ident data)
 
static ListmappedList (const List *self, Functor functor, ident data)
 
static ListNodenodeForElement (const List *self, const ident element)
 
static void prepend (List *self, const ident element)
 
static ident reduce (const List *self, Reducer reducer, ident accumulator, ident data)
 
static void removeAll (List *self)
 
static void removeNode (List *self, ListNode *node)
 

Macro Definition Documentation

◆ _Class

#define _Class   _List

Definition at line 31 of file List.c.

Function Documentation

◆ _List()

Class * _List ( void  )

Definition at line 385 of file List.c.

385 {
386 static Class *clazz;
387 static Once once;
388
389 do_once(&once, {
390 clazz = _initialize(&(const ClassDef) {
391 .name = "List",
392 .superclass = _Object(),
393 .instanceSize = sizeof(List),
394 .interfaceOffset = offsetof(List, interface),
395 .interfaceSize = sizeof(ListInterface),
397 });
398 });
399
400 return clazz;
401}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
static void initialize(Class *clazz)
Definition List.c:358
Class * _Object(void)
Definition Object.c:136
long Once
The Once type.
Definition Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition Once.h:43
ClassDefs are passed to _initialize via an archetype to initialize a Class.
Definition Class.h:41
The runtime representation of a Class.
Definition Class.h:95
Doubly-linked lists of raw C pointers.
Definition List.h:60

◆ _remove()

static void _remove ( List self,
const ident  element 
)
static

Definition at line 290 of file List.c.

290 {
291
292 ListNode *node = $(self, nodeForElement, element);
293 if (node) {
294 $(self, removeNode, node);
295 }
296}
static void removeNode(List *self, ListNode *node)
Definition List.c:302
static ListNode * nodeForElement(const List *self, const ident element)
Definition List.c:218
A node in a List.
Definition List.h:49

◆ _sort()

static void _sort ( List self,
Comparator  comparator 
)
static

Definition at line 330 of file List.c.

330 {
331
332 assert(comparator);
333
334 if (self->count < 2) {
335 return;
336 }
337
338 for (ListNode *node = self->head->next; node; ) {
339 ListNode *next = node->next;
340 ident key = node->element;
341
342 ListNode *j = node->prev;
343 while (j && comparator(j->element, key) > OrderSame) {
344 j->next->element = j->element;
345 j = j->prev;
346 }
347
348 (j ? j->next : self->head)->element = key;
349 node = next;
350 }
351}
static Unicode next(StringReader *self, StringReaderMode mode)
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49
@ OrderSame
Definition Types.h:72
ListNode * head
The head node.
Definition List.h:81
size_t count
The number of elements.
Definition List.h:76
ListNode * prev
Definition List.h:51
ident element
Definition List.h:50
ListNode * next
Definition List.h:52

◆ append()

static void append ( List self,
const ident  element 
)
static

Definition at line 52 of file List.c.

52 {
53
54 ListNode *node = calloc(1, sizeof(ListNode));
55 assert(node);
56
57 node->element = element;
58 node->prev = self->tail;
59
60 if (self->tail) {
61 self->tail->next = node;
62 } else {
63 self->head = node;
64 }
65
66 self->tail = node;
67 self->count++;
68}
ListNode * tail
The tail node.
Definition List.h:86

◆ contains()

static bool contains ( const List self,
const ident  element 
)
static

Definition at line 74 of file List.c.

74 {
75 return $(self, nodeForElement, element) != NULL;
76}

◆ dealloc()

static void dealloc ( Object self)
static
See also
Object::dealloc(Object *)

Definition at line 38 of file List.c.

38 {
39
40 List *this = (List *) self;
41 $(this, removeAll);
42
43 super(Object, self, dealloc);
44}
#define super(type, obj, method,...)
static void removeAll(List *self)
Definition List.c:270
static void dealloc(Object *self)
Definition List.c:38
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

◆ enumerate()

static void enumerate ( const List self,
ListEnumerator  enumerator,
ident  element 
)
static

Definition at line 82 of file List.c.

82 {
83
84 assert(enumerator);
85
86 for (ListNode *node = self->head; node; ) {
87 ListNode *next = node->next;
88 if (enumerator(self, node, element)) {
89 break;
90 }
91 node = next;
92 }
93}

◆ filter()

static void filter ( List self,
Predicate  predicate,
ident  data 
)
static

Definition at line 99 of file List.c.

99 {
100
101 assert(predicate);
102
103 for (ListNode *node = self->head; node; ) {
104 ListNode *next = node->next;
105 if (!predicate(node->element, data)) {
106 $(self, removeNode, node);
107 }
108 node = next;
109 }
110}
static Data * data(void)
Definition Data.c:286

◆ filteredList()

static List * filteredList ( const List self,
Predicate  predicate,
ident  data 
)
static

Definition at line 116 of file List.c.

116 {
117
118 assert(predicate);
119
120 List *list = $(alloc(List), init);
121 for (ListNode *node = self->head; node; node = node->next) {
122 if (predicate(node->element, data)) {
123 $(list, append, node->element);
124 }
125 }
126
127 return list;
128}
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:176
static List * init(List *self)
Definition List.c:153
static void append(List *self, const ident element)
Definition List.c:52

◆ find()

static ident find ( const List self,
Predicate  predicate,
ident  data 
)
static

Definition at line 134 of file List.c.

134 {
135
136 assert(predicate);
137
138 for (ListNode *node = self->head; node; node = node->next) {
139 if (predicate(node->element, data)) {
140 return node->element;
141 }
142 }
143
144 return NULL;
145}

◆ init()

static List * init ( List self)
static

Definition at line 153 of file List.c.

153 {
154
155 self = (List *) super(Object, self, init);
156 return self;
157}

◆ initialize()

static void initialize ( Class clazz)
static
See also
Class::initialize(Class *)

Definition at line 358 of file List.c.

358 {
359
360 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
361
362 ((ListInterface *) clazz->interface)->append = append;
363 ((ListInterface *) clazz->interface)->contains = contains;
364 ((ListInterface *) clazz->interface)->enumerate = enumerate;
365 ((ListInterface *) clazz->interface)->filter = filter;
366 ((ListInterface *) clazz->interface)->filteredList = filteredList;
367 ((ListInterface *) clazz->interface)->find = find;
368 ((ListInterface *) clazz->interface)->init = init;
369 ((ListInterface *) clazz->interface)->insertAfter = insertAfter;
370 ((ListInterface *) clazz->interface)->map = map;
371 ((ListInterface *) clazz->interface)->mappedList = mappedList;
372 ((ListInterface *) clazz->interface)->nodeForElement = nodeForElement;
373 ((ListInterface *) clazz->interface)->prepend = prepend;
374 ((ListInterface *) clazz->interface)->reduce = reduce;
375 ((ListInterface *) clazz->interface)->removeAll = removeAll;
376 ((ListInterface *) clazz->interface)->remove = _remove;
377 ((ListInterface *) clazz->interface)->removeNode = removeNode;
378 ((ListInterface *) clazz->interface)->sort = _sort;
379}
static void prepend(List *self, const ident element)
Definition List.c:233
static bool contains(const List *self, const ident element)
Definition List.c:74
static ident find(const List *self, Predicate predicate, ident data)
Definition List.c:134
static void _remove(List *self, const ident element)
Definition List.c:290
static List * mappedList(const List *self, Functor functor, ident data)
Definition List.c:202
static void insertAfter(List *self, ListNode *node, const ident element)
Definition List.c:163
static void map(List *self, Functor functor, ident data)
Definition List.c:189
static void filter(List *self, Predicate predicate, ident data)
Definition List.c:99
static void _sort(List *self, Comparator comparator)
Definition List.c:330
static ident reduce(const List *self, Reducer reducer, ident accumulator, ident data)
Definition List.c:255
static void enumerate(const List *self, ListEnumerator enumerator, ident element)
Definition List.c:82
static List * filteredList(const List *self, Predicate predicate, ident data)
Definition List.c:116
ident interface
The interface of the Class.
Definition Class.h:105
ident find(const List *self, Predicate predicate, ident data)
Definition List.c:134
ListNode * nodeForElement(const List *self, const ident element)
Definition List.c:218
void insertAfter(List *self, ListNode *node, const ident element)
Inserts an element after the given node.
Definition List.c:163

◆ insertAfter()

static void insertAfter ( List self,
ListNode node,
const ident  element 
)
static

Definition at line 163 of file List.c.

163 {
164
165 if (node == NULL || node == self->tail) {
166 $(self, append, element);
167 return;
168 }
169
170 ListNode *newNode = calloc(1, sizeof(ListNode));
171 assert(newNode);
172
173 newNode->element = element;
174 newNode->prev = node;
175 newNode->next = node->next;
176
177 if (node->next) {
178 node->next->prev = newNode;
179 }
180 node->next = newNode;
181
182 self->count++;
183}

◆ map()

static void map ( List self,
Functor  functor,
ident  data 
)
static

Definition at line 189 of file List.c.

189 {
190
191 assert(functor);
192
193 for (ListNode *node = self->head; node; node = node->next) {
194 node->element = functor(node->element, data);
195 }
196}

◆ mappedList()

static List * mappedList ( const List self,
Functor  functor,
ident  data 
)
static

Definition at line 202 of file List.c.

202 {
203
204 assert(functor);
205
206 List *list = $(alloc(List), init);
207 for (ListNode *node = self->head; node; node = node->next) {
208 $(list, append, functor(node->element, data));
209 }
210
211 return list;
212}

◆ nodeForElement()

static ListNode * nodeForElement ( const List self,
const ident  element 
)
static

Definition at line 218 of file List.c.

218 {
219
220 for (ListNode *node = self->head; node; node = node->next) {
221 if (node->element == element) {
222 return node;
223 }
224 }
225
226 return NULL;
227}

◆ prepend()

static void prepend ( List self,
const ident  element 
)
static

Definition at line 233 of file List.c.

233 {
234
235 ListNode *node = calloc(1, sizeof(ListNode));
236 assert(node);
237
238 node->element = element;
239 node->next = self->head;
240
241 if (self->head) {
242 self->head->prev = node;
243 } else {
244 self->tail = node;
245 }
246
247 self->head = node;
248 self->count++;
249}

◆ reduce()

static ident reduce ( const List self,
Reducer  reducer,
ident  accumulator,
ident  data 
)
static

Definition at line 255 of file List.c.

255 {
256
257 assert(reducer);
258
259 for (ListNode *node = self->head; node; node = node->next) {
260 accumulator = reducer(node->element, accumulator, data);
261 }
262
263 return accumulator;
264}

◆ removeAll()

static void removeAll ( List self)
static

Definition at line 270 of file List.c.

270 {
271
272 ListNode *node = self->head;
273 while (node) {
274 ListNode *next = node->next;
275 if (self->destroy) {
276 self->destroy(node->element);
277 }
278 free(node);
279 node = next;
280 }
281
282 self->head = self->tail = NULL;
283 self->count = 0;
284}
Consumer destroy
Optional destructor called when an element is removed.
Definition List.h:91

◆ removeNode()

static void removeNode ( List self,
ListNode node 
)
static

Definition at line 302 of file List.c.

302 {
303
304 assert(node);
305
306 if (node->prev) {
307 node->prev->next = node->next;
308 } else {
309 self->head = node->next;
310 }
311
312 if (node->next) {
313 node->next->prev = node->prev;
314 } else {
315 self->tail = node->prev;
316 }
317
318 if (self->destroy) {
319 self->destroy(node->element);
320 }
321
322 free(node);
323 self->count--;
324}