src/util/vector.h (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef VECTOR_H
7#define VECTOR_H
8
9#include "util/common.h"
10
11#define DECLARE_VECTOR(NAME, TYPE) \
12 struct NAME { \
13 TYPE* vector; \
14 size_t size; \
15 size_t capacity; \
16 }; \
17 void NAME ## Init(struct NAME* vector, size_t capacity); \
18 void NAME ## Deinit(struct NAME* vector); \
19 TYPE* NAME ## GetPointer(struct NAME* vector, size_t location); \
20 TYPE* NAME ## Append(struct NAME* vector); \
21 void NAME ## Resize(struct NAME* vector, ssize_t change); \
22 void NAME ## Shift(struct NAME* vector, size_t location, size_t difference); \
23 void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference); \
24 void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity); \
25 size_t NAME ## Size(struct NAME* vector); \
26
27#define DEFINE_VECTOR(NAME, TYPE) \
28 void NAME ## Init(struct NAME* vector, size_t capacity) { \
29 vector->size = 0; \
30 if (capacity == 0) { \
31 capacity = 4; \
32 } \
33 vector->capacity = capacity; \
34 vector->vector = malloc(sizeof(TYPE) * capacity); \
35 } \
36 void NAME ## Deinit(struct NAME* vector) { \
37 free(vector->vector); \
38 vector->vector = 0; \
39 vector->capacity = 0; \
40 } \
41 TYPE* NAME ## GetPointer(struct NAME* vector, size_t location) { \
42 return &vector->vector[location]; \
43 } \
44 TYPE* NAME ## Append(struct NAME* vector) { \
45 NAME ## Resize(vector, 1); \
46 return &vector->vector[vector->size - 1]; \
47 } \
48 void NAME ## Resize(struct NAME* vector, ssize_t change) { \
49 if (change > 0) { \
50 NAME ## EnsureCapacity(vector, vector->size + change); \
51 } \
52 vector->size += change; \
53 } \
54 void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity) { \
55 if (capacity <= vector->capacity) { \
56 return; \
57 } \
58 while (capacity > vector->capacity) { \
59 vector->capacity <<= 1; \
60 } \
61 vector->vector = realloc(vector->vector, vector->capacity * sizeof(TYPE)); \
62 } \
63 void NAME ## Shift(struct NAME* vector, size_t location, size_t difference) { \
64 memmove(&vector->vector[location], &vector->vector[location + difference], (vector->size - location - difference) * sizeof(TYPE)); \
65 vector->size -= difference; \
66 } \
67 void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference) { \
68 NAME ## Resize(vector, difference); \
69 memmove(&vector->vector[location + difference], &vector->vector[location], (vector->size - location - difference) * sizeof(TYPE)); \
70 } \
71 size_t NAME ## Size(struct NAME* vector) { \
72 return vector->size; \
73 } \
74
75#endif