all repos — mgba @ b54a4ba555eaac0de79107db1c321c811980187c

mGBA Game Boy Advance Emulator

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