all repos — mgba @ d02e8a2a8780433a54e3b39cc01e5eb4b688fe3a

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#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