all repos — mgba @ 178f9a83bb120db15d2b7450b63ed0dd5766a08b

mGBA Game Boy Advance Emulator

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 ## Clear(struct NAME* vector); \
22	void NAME ## Resize(struct NAME* vector, ssize_t change); \
23	void NAME ## Shift(struct NAME* vector, size_t location, size_t difference); \
24	void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference); \
25	void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity); \
26	size_t NAME ## Size(const struct NAME* vector); \
27	size_t NAME ## Index(const struct NAME* vector, const TYPE* member);
28
29#define DEFINE_VECTOR(NAME, TYPE) \
30	void NAME ## Init(struct NAME* vector, size_t capacity) { \
31		vector->size = 0; \
32		if (capacity == 0) { \
33			capacity = 4; \
34		} \
35		vector->capacity = capacity; \
36		vector->vector = malloc(sizeof(TYPE) * capacity); \
37	} \
38	void NAME ## Deinit(struct NAME* vector) { \
39		free(vector->vector); \
40		vector->vector = 0; \
41		vector->capacity = 0; \
42	} \
43	TYPE* NAME ## GetPointer(struct NAME* vector, size_t location) { \
44		return &vector->vector[location]; \
45	} \
46	TYPE* NAME ## Append(struct NAME* vector) { \
47		NAME ## Resize(vector, 1); \
48		return &vector->vector[vector->size - 1]; \
49	} \
50	void NAME ## Resize(struct NAME* vector, ssize_t change) { \
51		if (change > 0) { \
52			NAME ## EnsureCapacity(vector, vector->size + change); \
53		} \
54		vector->size += change; \
55	} \
56	void NAME ## Clear(struct NAME* vector) { \
57		vector->size = 0; \
58	} \
59	void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity) { \
60		if (capacity <= vector->capacity) { \
61			return; \
62		} \
63		while (capacity > vector->capacity) { \
64			vector->capacity <<= 1; \
65		} \
66		vector->vector = realloc(vector->vector, vector->capacity * sizeof(TYPE)); \
67	} \
68	void NAME ## Shift(struct NAME* vector, size_t location, size_t difference) { \
69		memmove(&vector->vector[location], &vector->vector[location + difference], (vector->size - location - difference) * sizeof(TYPE)); \
70		vector->size -= difference; \
71	} \
72	void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference) { \
73		NAME ## Resize(vector, difference); \
74		memmove(&vector->vector[location + difference], &vector->vector[location], (vector->size - location - difference) * sizeof(TYPE)); \
75	} \
76	size_t NAME ## Size(const struct NAME* vector) { \
77		return vector->size; \
78	} \
79	size_t NAME ## Index(const struct NAME* vector, const TYPE* member) { \
80		return member - (const TYPE*) vector->vector; \
81	} \
82
83#endif