Objectively
Object oriented framework for 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 Object * copy (const Object *self)
 
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 List * filteredList (const List *self, Predicate predicate, ident data)
 
static ident find (const List *self, Predicate predicate, ident data)
 
static List * init (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 List * mappedList (const List *self, Functor functor, ident data)
 
static ListNode * nodeForElement (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 406 of file List.c.

406 {
407 static Class *clazz;
408 static Once once;
409
410 do_once(&once, {
411 clazz = _initialize(&(const ClassDef) {
412 .name = "List",
413 .superclass = _Object(),
414 .instanceSize = sizeof(List),
415 .interfaceSize = sizeof(ListInterface),
416 .initialize = initialize,
417 });
418 });
419
420 return clazz;
421}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:151
static void initialize(Class *clazz)
Definition List.c:378
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:90
Doubly-linked lists of raw C pointers.
Definition List.h:60

◆ _remove()

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

Definition at line 310 of file List.c.

310 {
311
312 ListNode *node = $(self, nodeForElement, element);
313 if (node) {
314 $(self, removeNode, node);
315 }
316}
static void removeNode(List *self, ListNode *node)
Definition List.c:322
static ListNode * nodeForElement(const List *self, const ident element)
Definition List.c:238
A node in a List.
Definition List.h:49

◆ _sort()

static void _sort ( List *  self,
Comparator  comparator 
)
static

Definition at line 350 of file List.c.

350 {
351
352 assert(comparator);
353
354 if (self->count < 2) {
355 return;
356 }
357
358 for (ListNode *node = self->head->next; node; ) {
359 ListNode *next = node->next;
360 ident key = node->element;
361
362 ListNode *j = node->prev;
363 while (j && comparator(j->element, key) > OrderSame) {
364 j->next->element = j->element;
365 j = j->prev;
366 }
367
368 (j ? j->next : self->head)->element = key;
369 node = next;
370 }
371}
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 72 of file List.c.

72 {
73
74 ListNode *node = calloc(1, sizeof(ListNode));
75 assert(node);
76
77 node->element = element;
78 node->prev = self->tail;
79
80 if (self->tail) {
81 self->tail->next = node;
82 } else {
83 self->head = node;
84 }
85
86 self->tail = node;
87 self->count++;
88}
ListNode * tail
The tail node.
Definition List.h:86

◆ contains()

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

Definition at line 94 of file List.c.

94 {
95 return $(self, nodeForElement, element) != NULL;
96}

◆ copy()

static Object * copy ( const Object *  self)
static
See also
Object::copy(const Object *)
Remarks
Elements are not retained, since List does not retain them on insertion either. The copy does not inherit destroy, and so borrows the elements rather than owning them, as filteredList and mappedList do.

Definition at line 41 of file List.c.

41 {
42
43 const List *this = (List *) self;
44
45 List *copy = $(alloc(List), init);
46 assert(copy);
47
48 for (ListNode *node = this->head; node; node = node->next) {
49 $(copy, append, node->element);
50 }
51
52 return (Object *) copy;
53}
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:226
static List * init(List *self)
Definition List.c:173
static void append(List *self, const ident element)
Definition List.c:72
static Object * copy(const Object *self)
Definition List.c:41
static int head(RESTClient *self, const char *url, const char **headers)
Definition RESTClient.c:188
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

◆ dealloc()

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

Definition at line 58 of file List.c.

58 {
59
60 List *this = (List *) self;
61 $(this, removeAll);
62
63 super(Object, self, dealloc);
64}
#define super(type, obj, method,...)
static void removeAll(List *self)
Definition List.c:290
static void dealloc(Object *self)
Definition List.c:58

◆ enumerate()

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

Definition at line 102 of file List.c.

102 {
103
104 assert(enumerator);
105
106 for (ListNode *node = self->head; node; ) {
107 ListNode *next = node->next;
108 if (enumerator(self, node, element)) {
109 break;
110 }
111 node = next;
112 }
113}

◆ filter()

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

Definition at line 119 of file List.c.

119 {
120
121 assert(predicate);
122
123 for (ListNode *node = self->head; node; ) {
124 ListNode *next = node->next;
125 if (!predicate(node->element, data)) {
126 $(self, removeNode, node);
127 }
128 node = next;
129 }
130}
static Data * data(void)
Definition Data.c:286

◆ filteredList()

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

Definition at line 136 of file List.c.

136 {
137
138 assert(predicate);
139
140 List *list = $(alloc(List), init);
141 for (ListNode *node = self->head; node; node = node->next) {
142 if (predicate(node->element, data)) {
143 $(list, append, node->element);
144 }
145 }
146
147 return list;
148}

◆ find()

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

Definition at line 154 of file List.c.

154 {
155
156 assert(predicate);
157
158 for (ListNode *node = self->head; node; node = node->next) {
159 if (predicate(node->element, data)) {
160 return node->element;
161 }
162 }
163
164 return NULL;
165}

◆ init()

static List * init ( List *  self)
static

Definition at line 173 of file List.c.

173 {
174
175 self = (List *) super(Object, self, init);
176 return self;
177}

◆ initialize()

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

Definition at line 378 of file List.c.

378 {
379
380 ((ObjectInterface *) clazz->interface)->copy = copy;
381 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
382
383 ((ListInterface *) clazz->interface)->append = append;
384 ((ListInterface *) clazz->interface)->contains = contains;
385 ((ListInterface *) clazz->interface)->enumerate = enumerate;
386 ((ListInterface *) clazz->interface)->filter = filter;
387 ((ListInterface *) clazz->interface)->filteredList = filteredList;
388 ((ListInterface *) clazz->interface)->find = find;
389 ((ListInterface *) clazz->interface)->init = init;
390 ((ListInterface *) clazz->interface)->insertAfter = insertAfter;
391 ((ListInterface *) clazz->interface)->map = map;
392 ((ListInterface *) clazz->interface)->mappedList = mappedList;
393 ((ListInterface *) clazz->interface)->nodeForElement = nodeForElement;
394 ((ListInterface *) clazz->interface)->prepend = prepend;
395 ((ListInterface *) clazz->interface)->reduce = reduce;
396 ((ListInterface *) clazz->interface)->removeAll = removeAll;
397 ((ListInterface *) clazz->interface)->remove = _remove;
398 ((ListInterface *) clazz->interface)->removeNode = removeNode;
399 ((ListInterface *) clazz->interface)->sort = _sort;
400}
static void prepend(List *self, const ident element)
Definition List.c:253
static bool contains(const List *self, const ident element)
Definition List.c:94
static ident find(const List *self, Predicate predicate, ident data)
Definition List.c:154
static void _remove(List *self, const ident element)
Definition List.c:310
static List * mappedList(const List *self, Functor functor, ident data)
Definition List.c:222
static void insertAfter(List *self, ListNode *node, const ident element)
Definition List.c:183
static void map(List *self, Functor functor, ident data)
Definition List.c:209
static void filter(List *self, Predicate predicate, ident data)
Definition List.c:119
static void _sort(List *self, Comparator comparator)
Definition List.c:350
static ident reduce(const List *self, Reducer reducer, ident accumulator, ident data)
Definition List.c:275
static void enumerate(const List *self, ListEnumerator enumerator, ident element)
Definition List.c:102
static List * filteredList(const List *self, Predicate predicate, ident data)
Definition List.c:136
ident interface
The interface of the Class.
Definition Class.h:100
ident find(const List *self, Predicate predicate, ident data)
Definition List.c:154
ListNode * nodeForElement(const List *self, const ident element)
Definition List.c:238
void insertAfter(List *self, ListNode *node, const ident element)
Inserts an element after the given node.
Definition List.c:183
void dealloc(Object *self)
Frees all resources held by this Object.
Definition Array.c:99

◆ insertAfter()

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

Definition at line 183 of file List.c.

183 {
184
185 if (node == NULL || node == self->tail) {
186 $(self, append, element);
187 return;
188 }
189
190 ListNode *newNode = calloc(1, sizeof(ListNode));
191 assert(newNode);
192
193 newNode->element = element;
194 newNode->prev = node;
195 newNode->next = node->next;
196
197 if (node->next) {
198 node->next->prev = newNode;
199 }
200 node->next = newNode;
201
202 self->count++;
203}

◆ map()

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

Definition at line 209 of file List.c.

209 {
210
211 assert(functor);
212
213 for (ListNode *node = self->head; node; node = node->next) {
214 node->element = functor(node->element, data);
215 }
216}

◆ mappedList()

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

Definition at line 222 of file List.c.

222 {
223
224 assert(functor);
225
226 List *list = $(alloc(List), init);
227 for (ListNode *node = self->head; node; node = node->next) {
228 $(list, append, functor(node->element, data));
229 }
230
231 return list;
232}

◆ nodeForElement()

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

Definition at line 238 of file List.c.

238 {
239
240 for (ListNode *node = self->head; node; node = node->next) {
241 if (node->element == element) {
242 return node;
243 }
244 }
245
246 return NULL;
247}

◆ prepend()

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

Definition at line 253 of file List.c.

253 {
254
255 ListNode *node = calloc(1, sizeof(ListNode));
256 assert(node);
257
258 node->element = element;
259 node->next = self->head;
260
261 if (self->head) {
262 self->head->prev = node;
263 } else {
264 self->tail = node;
265 }
266
267 self->head = node;
268 self->count++;
269}

◆ reduce()

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

Definition at line 275 of file List.c.

275 {
276
277 assert(reducer);
278
279 for (ListNode *node = self->head; node; node = node->next) {
280 accumulator = reducer(node->element, accumulator, data);
281 }
282
283 return accumulator;
284}

◆ removeAll()

static void removeAll ( List *  self)
static

Definition at line 290 of file List.c.

290 {
291
292 ListNode *node = self->head;
293 while (node) {
294 ListNode *next = node->next;
295 if (self->destroy) {
296 self->destroy(node->element);
297 }
298 free(node);
299 node = next;
300 }
301
302 self->head = self->tail = NULL;
303 self->count = 0;
304}
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 322 of file List.c.

322 {
323
324 assert(node);
325
326 if (node->prev) {
327 node->prev->next = node->next;
328 } else {
329 self->head = node->next;
330 }
331
332 if (node->next) {
333 node->next->prev = node->prev;
334 } else {
335 self->tail = node->prev;
336 }
337
338 if (self->destroy) {
339 self->destroy(node->element);
340 }
341
342 free(node);
343 self->count--;
344}