Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
PointerArray.c
Go to the documentation of this file.
1/*
2 * Objectively: Ultra-lightweight object oriented framework for GNU C.
3 * Copyright (C) 2014 Jay Dolan <jay@jaydolan.com>
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24#include <assert.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include "Array.h"
29#include "PointerArray.h"
30
31#define _Class _PointerArray
32
33#define POINTER_ARRAY_CHUNK_SIZE 64
34
35#pragma mark - Object
36
40static void dealloc(Object *self) {
41
42 PointerArray *this = (PointerArray *) self;
43
44 $(this, removeAll);
45
46 free(this->elements);
47
48 super(Object, self, dealloc);
49}
50
51#pragma mark - PointerArray
52
57static void add(PointerArray *self, ident pointer) {
58
59 if (self->count == self->capacity) {
60
62
63 self->elements = realloc(self->elements, self->capacity * sizeof(ident ));
64 assert(self->elements);
65 }
66
67 self->elements[self->count++] = pointer;
68}
69
74static ident get(const PointerArray *self, size_t index) {
75
76 assert(index < self->count);
77
78 return self->elements[index];
79}
80
86 return $(self, initWithDestroy, NULL);
87}
88
94
95 self = (PointerArray *) super(Object, self, init);
96 if (self) {
97 self->destroy = destroy;
98 }
99
100 return self;
101}
102
107static void _remove(PointerArray *self, ident pointer) {
108
109 for (size_t i = 0; i < self->count; i++) {
110 if (self->elements[i] == pointer) {
111 $(self, removeAt, i);
112 return;
113 }
114 }
115}
116
121static void removeAll(PointerArray *self) {
122
123 if (self->destroy) {
124 for (size_t i = 0; i < self->count; i++) {
125 self->destroy(self->elements[i]);
126 }
127 }
128
129 self->count = 0;
130}
131
136static void removeAt(PointerArray *self, size_t index) {
137
138 assert(index < self->count);
139
140 if (self->destroy) {
141 self->destroy(self->elements[index]);
142 }
143
144 const size_t tail = self->count - index - 1;
145 memmove(self->elements + index, self->elements + index + 1, tail * sizeof(ident ));
146
147 self->count--;
148}
149
154static void sort(PointerArray *self, Comparator comparator) {
155 quicksort(self->elements, self->count, sizeof(ident), comparator, NULL);
156}
157
158#pragma mark - Class lifecycle
159
163static void initialize(Class *clazz) {
164
165 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
166
167 ((PointerArrayInterface *) clazz->interface)->add = add;
168 ((PointerArrayInterface *) clazz->interface)->get = get;
169 ((PointerArrayInterface *) clazz->interface)->init = init;
170 ((PointerArrayInterface *) clazz->interface)->initWithDestroy = initWithDestroy;
171 ((PointerArrayInterface *) clazz->interface)->remove = _remove;
172 ((PointerArrayInterface *) clazz->interface)->removeAll = removeAll;
173 ((PointerArrayInterface *) clazz->interface)->removeAt = removeAt;
174 ((PointerArrayInterface *) clazz->interface)->sort = sort;
175}
176
182 static Class *clazz;
183 static Once once;
184
185 do_once(&once, {
186 clazz = _initialize(&(const ClassDef) {
187 .name = "PointerArray",
188 .superclass = _Object(),
189 .instanceSize = sizeof(PointerArray),
190 .interfaceOffset = offsetof(PointerArray, interface),
191 .interfaceSize = sizeof(PointerArrayInterface),
193 });
194 });
195
196 return clazz;
197}
198
199#undef _Class
void quicksort(ident base, size_t count, size_t size, Comparator comparator, ident data)
A portability wrapper around reentrant qsort.
Definition Array.c:69
Arrays.
static void destroy(Class *clazz)
Definition Boole.c:102
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
#define super(type, obj, method,...)
Class * _Object(void)
Definition Object.c:136
static void removeAll(PointerArray *self)
static void add(PointerArray *self, ident pointer)
static ident get(const PointerArray *self, size_t index)
static PointerArray * initWithDestroy(PointerArray *self, Consumer destroy)
static void removeAt(PointerArray *self, size_t index)
static PointerArray * init(PointerArray *self)
static void sort(PointerArray *self, Comparator comparator)
static void dealloc(Object *self)
static void _remove(PointerArray *self, ident pointer)
#define POINTER_ARRAY_CHUNK_SIZE
static void initialize(Class *clazz)
Class * _PointerArray(void)
Growable arrays of raw C pointers.
UTF-8 strings.
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49
Order(* Comparator)(const ident obj1, const ident obj2)
The Comparator function type for ordering Objects.
Definition Types.h:82
void(* Consumer)(ident data)
The Consumer function type.
Definition Types.h:88
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
ident interface
The interface of the Class.
Definition Class.h:105
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46
Growable arrays of raw C pointers.
ident * elements
The backing array of pointers.
PointerArray * initWithDestroy(PointerArray *self, Consumer destroy)
Initializes this PointerArray with a destructor.
Consumer destroy
Optional destructor called when a element is removed.
size_t count
The count of elements.
size_t capacity
The capacity.
void remove(PointerArray *self, ident pointer)
Removes the first occurrence of pointer from this PointerArray.