Objectively 1.0.0
Ultra-lightweight object oriented framework for GNU C.
MutableIndexSet.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
27#include "MutableIndexSet.h"
28
29#define _Class _MutableIndexSet
30
31#define INDEX_SET_CHUNK_SIZE 8
32
33#pragma mark - Object
34
38static void dealloc(Object *self) {
39
40 //..
41
42 super(Object, self, dealloc);
43}
44
45#pragma mark - MutableIndexSet
46
51static void addIndex(MutableIndexSet *self, size_t index) {
52
53 IndexSet *this = &self->indexSet;
54
55 size_t i;
56 for (i = 0; i < this->count; i++) {
57 if (this->indexes[i] == index) {
58 return;
59 }
60 if (this->indexes[i] > index) {
61 break;
62 }
63 }
64
65 if (this->count == self->capacity) {
67
68 this->indexes = realloc(this->indexes, self->capacity * sizeof(size_t));
69 assert(this->indexes);
70 }
71
72 for (size_t j = this->count; j > i; j--) {
73 this->indexes[j] = this->indexes[j - 1];
74 }
75
76 this->indexes[i] = index;
77 this->count++;
78}
79
84static void addIndexes(MutableIndexSet *self, size_t *indexes, size_t count) {
85
86 for (size_t i = 0; i < count; i++) {
87 $(self, addIndex, indexes[i]);
88 }
89}
90
98static void addIndexesInRange(MutableIndexSet *self, const Range range) {
99
100 for (size_t i = range.location; i < range.length; i++) {
101 $(self, addIndex, i);
102 }
103}
104
110 return $(self, initWithCapacity, INDEX_SET_CHUNK_SIZE);
111}
112
117static MutableIndexSet *initWithCapacity(MutableIndexSet *self, size_t capacity) {
118
119 self = (MutableIndexSet *) super(Object, self, init);
120 if (self) {
121 self->capacity = capacity;
122
123 IndexSet *this = & self->indexSet;
124
125 this->indexes = malloc(self->capacity * sizeof(size_t));
126 assert(this->indexes);
127 }
128
129 return self;
130}
131
137
138 IndexSet *this = &self->indexSet;
139
140 free(this->indexes);
141 this->indexes = NULL;
142
143 this->count = 0;
144 self->capacity = 0;
145}
146
151static void removeIndex(MutableIndexSet *self, size_t index) {
152
153 IndexSet *this = &self->indexSet;
154 for (size_t i = 0; i < this->count; i++) {
155 if (this->indexes[i] == index) {
156 this->count--;
157 for (size_t j = i; j < this->count; j++) {
158 this->indexes[j] = this->indexes[j + 1];
159 }
160 return;
161 }
162 }
163}
164
169static void removeIndexes(MutableIndexSet *self, size_t *indexes, size_t count) {
170
171 for (size_t i = 0; i < count; i++) {
172 $(self, removeIndex, indexes[i]);
173 }
174}
175
180static void removeIndexesInRange(MutableIndexSet *self, const Range range) {
181
182 for (size_t i = range.location; i < range.length; i++) {
183 $(self, removeIndex, i);
184 }
185}
186
187#pragma mark - Class lifecycle
188
192static void initialize(Class *clazz) {
193
194 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
195
196 ((MutableIndexSetInterface *) clazz->interface)->addIndex = addIndex;
197 ((MutableIndexSetInterface *) clazz->interface)->addIndexes = addIndexes;
198 ((MutableIndexSetInterface *) clazz->interface)->addIndexesInRange = addIndexesInRange;
199 ((MutableIndexSetInterface *) clazz->interface)->init = init;
200 ((MutableIndexSetInterface *) clazz->interface)->initWithCapacity = initWithCapacity;
201 ((MutableIndexSetInterface *) clazz->interface)->removeAllIndexes = removeAllIndexes;
202 ((MutableIndexSetInterface *) clazz->interface)->removeIndex = removeIndex;
203 ((MutableIndexSetInterface *) clazz->interface)->removeIndexes = removeIndexes;
204 ((MutableIndexSetInterface *) clazz->interface)->removeIndexesInRange = removeIndexesInRange;
205}
206
212 static Class *clazz;
213 static Once once;
214
215 do_once(&once, {
216 clazz = _initialize(&(const ClassDef) {
217 .name = "MutableIndexSet",
218 .superclass = _IndexSet(),
219 .instanceSize = sizeof(MutableIndexSet),
220 .interfaceOffset = offsetof(MutableIndexSet, interface),
221 .interfaceSize = sizeof(MutableIndexSetInterface),
223 });
224 });
225
226 return clazz;
227}
228
229#undef _Class
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition: Class.c:91
#define super(type, obj, method,...)
static void initialize(Class *clazz)
#define INDEX_SET_CHUNK_SIZE
Mutable collections of unique index values.
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
Condition * init(Condition *self)
Initializes this Condition.
Definition: Condition.c:67
Immutable collections of unique index values.
Definition: IndexSet.h:41
Class * _IndexSet(void)
The IndexSet archetype.
Definition: IndexSet.c:218
MutableArray * initWithCapacity(MutableArray *self, size_t capacity)
Initializes this MutableArray with the specified capacity.
Definition: MutableArray.c:195
Mutable collections of unique index values.
void addIndexes(MutableIndexSet *self, size_t *indexes, size_t count)
Adds the specified indexes to this MutableIndexSet.
void removeIndexesInRange(MutableIndexSet *self, const Range range)
Removes indexes in the specified Range from this MutableIndexSet.
void addIndex(MutableIndexSet *self, size_t index)
Adds the specified index to this MutableIndexSet.
void removeIndex(MutableIndexSet *self, size_t index)
Removes the specified index from this MutableIndexSet.
void removeIndexes(MutableIndexSet *self, size_t *indexes, size_t count)
Removes the specified indexes from this MutableIndexSet.
void addIndexesInRange(MutableIndexSet *self, const Range range)
Adds indexes in the specified Range to this MutableIndexSet.
size_t capacity
The capacity.
Class * _MutableIndexSet(void)
The MutableIndexSet archetype.
IndexSet indexSet
The superclass.
void removeAllIndexes(MutableIndexSet *self)
Removes all indexes from this MutableIndexSet.
Object is the root Class of The Objectively Class hierarchy.
Definition: Object.h:46
void dealloc(Object *self)
Frees all resources held by this Object.
Definition: Array.c:50
A location and length into contiguous collections.
Definition: Types.h:54
ssize_t location
The location.
Definition: Types.h:59
size_t length
The length.
Definition: Types.h:64