include/mgba-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 <mgba-util/common.h>
10
11CXX_GUARD_START
12
13#ifdef vector
14#undef vector
15#endif
16
17#define DECLARE_VECTOR(NAME, TYPE) \
18 struct NAME { \
19 TYPE* vector; \
20 size_t size; \
21 size_t capacity; \
22 }; \
23 void NAME ## Init(struct NAME* vector, size_t capacity); \
24 void NAME ## Deinit(struct NAME* vector); \
25 TYPE* NAME ## GetPointer(struct NAME* vector, size_t location); \
26 TYPE const* NAME ## GetConstPointer(const struct NAME* vector, size_t location); \
27 TYPE* NAME ## Append(struct NAME* vector); \
28 void NAME ## Clear(struct NAME* vector); \
29 void NAME ## Resize(struct NAME* vector, ssize_t change); \
30 void NAME ## Shift(struct NAME* vector, size_t location, size_t difference); \
31 void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference); \
32 void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity); \
33 size_t NAME ## Size(const struct NAME* vector); \
34 size_t NAME ## Index(const struct NAME* vector, const TYPE* member); \
35 void NAME ## Copy(struct NAME* dest, const struct NAME* src);
36
37#define DEFINE_VECTOR(NAME, TYPE) \
38 void NAME ## Init(struct NAME* vector, size_t capacity) { \
39 vector->size = 0; \
40 if (capacity == 0) { \
41 capacity = 4; \
42 } \
43 vector->capacity = capacity; \
44 vector->vector = calloc(capacity, sizeof(TYPE)); \
45 } \
46 void NAME ## Deinit(struct NAME* vector) { \
47 free(vector->vector); \
48 vector->vector = 0; \
49 vector->capacity = 0; \
50 vector->size = 0; \
51 } \
52 TYPE* NAME ## GetPointer(struct NAME* vector, size_t location) { \
53 return &vector->vector[location]; \
54 } \
55 TYPE const* NAME ## GetConstPointer(const struct NAME* vector, size_t location) { \
56 return &vector->vector[location]; \
57 } \
58 TYPE* NAME ## Append(struct NAME* vector) { \
59 NAME ## Resize(vector, 1); \
60 return &vector->vector[vector->size - 1]; \
61 } \
62 void NAME ## Resize(struct NAME* vector, ssize_t change) { \
63 if (change > 0) { \
64 NAME ## EnsureCapacity(vector, vector->size + change); \
65 } \
66 vector->size += change; \
67 } \
68 void NAME ## Clear(struct NAME* vector) { \
69 vector->size = 0; \
70 } \
71 void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity) { \
72 if (capacity <= vector->capacity) { \
73 return; \
74 } \
75 while (capacity > vector->capacity) { \
76 vector->capacity <<= 1; \
77 } \
78 vector->vector = realloc(vector->vector, vector->capacity * sizeof(TYPE)); \
79 } \
80 void NAME ## Shift(struct NAME* vector, size_t location, size_t difference) { \
81 memmove(&vector->vector[location], &vector->vector[location + difference], (vector->size - location - difference) * sizeof(TYPE)); \
82 vector->size -= difference; \
83 } \
84 void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference) { \
85 NAME ## Resize(vector, difference); \
86 memmove(&vector->vector[location + difference], &vector->vector[location], (vector->size - location - difference) * sizeof(TYPE)); \
87 } \
88 size_t NAME ## Size(const struct NAME* vector) { \
89 return vector->size; \
90 } \
91 size_t NAME ## Index(const struct NAME* vector, const TYPE* member) { \
92 return member - (const TYPE*) vector->vector; \
93 } \
94 void NAME ## Copy(struct NAME* dest, const struct NAME* src) { \
95 NAME ## EnsureCapacity(dest, src->size); \
96 memcpy(dest->vector, src->vector, src->size * sizeof(TYPE)); \
97 dest->size = src->size; \
98 } \
99
100DECLARE_VECTOR(StringList, char*);
101
102CXX_GUARD_END
103
104#endif