Freeciv-3.3: /fast/freeciv/nightly/main/utility/specvec.h Source File

Freeciv-3.3

Loading...
Searching...
No Matches
specvec.h
Go to the documentation of this file.
1/**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/* specvectors: "specific vectors".
15
16 This file is used to implement resizable arrays.
17
18 Before including this file, you must define the following:
19 SPECVEC_TAG - this tag will be used to form names for functions etc.
20 You may also define:
21 SPECVEC_TYPE - the typed vector will contain pointers to this type;
22 If SPECVEC_TYPE is not defined, then 'struct SPECVEC_TAG' is used.
23 At the end of this file, these (and other defines) are undef-ed.
24
25 Assuming SPECVEC_TAG were 'foo', and SPECVEC_TYPE were 'foo_t',
26 including this file would provide a struct definition for:
27 struct foo_vector;
28 and prototypes for the following functions:
29 void foo_vector_init(struct foo_vector *tthis);
30 void foo_vector_reserve(struct foo_vector *tthis, int n);
31 int foo_vector_size(const struct foo_vector *tthis);
32 foo_t *foo_vector_get(struct foo_vector *tthis, int svindex);
33 void foo_vector_copy(struct foo_vector *to,
34 const struct foo_vector *from);
35 void foo_vector_free(struct foo_vector *tthis);
36 void foo_vector_append(struct foo_vector *tthis, foo_t pfoo);
37 void foo_vector_remove(struct foo_vector *tthis, int svindex);
38
39 Note this is not protected against multiple inclusions; this is
40 so that you can have multiple different specvectors. For each
41 specvector, this file should be included _once_, inside a .h file
42 which _is_ itself protected against multiple inclusions.
43*/
44
45#ifdef __cplusplus
46extern "C" {
47#endif /* __cplusplus */
48
49#include <string.h> /* for memcpy */
50
51/* utility */
52#include "mem.h"
53
54#ifndef SPECVEC_TAG
55#error Must define a SPECVEC_TAG to use this header
56#endif
57#ifndef SPECVEC_TYPE
58#define SPECVEC_TYPE struct SPECVEC_TAG
59#endif
60
61#define SPECVEC_PASTE_(x,y) x ## y
62#define SPECVEC_PASTE(x,y) SPECVEC_PASTE_(x,y)
63
64#define SPECVEC_VECTOR struct SPECVEC_PASTE(SPECVEC_TAG, _vector)
65
66#define SPECVEC_FOO(suffix) SPECVEC_PASTE(SPECVEC_TAG, suffix)
67
68 SPECVEC_VECTOR {
69 /* Users are allowed to access the data pointer directly. */
70 SPECVEC_TYPE *p;
71
72 size_t size, size_alloc;
73};
74
75 static inline void SPECVEC_FOO(_vector_init) (SPECVEC_VECTOR *tthis)
76{
77 tthis->p = NULL;
78 tthis->size = tthis->size_alloc = 0;
79}
80
81 static inline void SPECVEC_FOO(_vector_reserve) (SPECVEC_VECTOR *tthis,
82 size_t size)
83{
84 if (size > tthis->size_alloc) {
85 size_t new_size = MAX(size, tthis->size_alloc * 2);
86
87 tthis->p = (SPECVEC_TYPE *)fc_realloc(tthis->p,
88 new_size * sizeof(*tthis->p));
89 tthis->size_alloc = new_size;
90 }
91 tthis->size = size;
92}
93
94 static inline size_t SPECVEC_FOO(_vector_size) (const SPECVEC_VECTOR *tthis)
95{
96 return tthis->size;
97}
98
99 static inline SPECVEC_TYPE *SPECVEC_FOO(_vector_get) (const SPECVEC_VECTOR
100 *tthis,
101 int svindex)
102{
103 if (svindex == -1 && tthis->size > 0) {
104 return tthis->p + tthis->size - 1;
105 } else if (svindex >= 0 && (size_t)svindex < tthis->size) {
106 return tthis->p + svindex;
107 } else {
108 return NULL;
109 }
110}
111
112/* You must _init "*to" before using this function */
113 static inline void SPECVEC_FOO(_vector_copy) (SPECVEC_VECTOR *to,
114 const SPECVEC_VECTOR *from)
115{
116 SPECVEC_FOO(_vector_reserve) (to, from->size);
117 if (from->size > 0) {
118 memcpy(to->p, from->p, from->size * sizeof(*to->p));
119 }
120}
121
122 static inline void SPECVEC_FOO(_vector_free) (SPECVEC_VECTOR *tthis)
123{
124 if (tthis->p) {
125 free(tthis->p);
126 }
127 SPECVEC_FOO(_vector_init)(tthis);
128}
129
130 static inline void SPECVEC_FOO(_vector_append) (SPECVEC_VECTOR *tthis,
131 SPECVEC_TYPE const pfoo)
132{
133 SPECVEC_FOO(_vector_reserve) (tthis, tthis->size + 1);
134 tthis->p[tthis->size - 1] = pfoo;
135}
136
137/**************************************************************************
138 Remove element number svindex from the vector.
139**************************************************************************/
140 static inline void SPECVEC_FOO(_vector_remove) (SPECVEC_VECTOR *tthis,
141 const int svindex)
142{
143 size_t i;
144
145 /* Be consistent with SPECVEC_FOO_vector_get(): Allow negative element
146 * number. */
147 const size_t rmpos = (svindex < 0 ?
148 SPECVEC_FOO(_vector_size)(tthis) - svindex :
149 (size_t)svindex);
150
151 fc_assert_ret(rmpos < SPECVEC_FOO(_vector_size)(tthis));
152
153 for (i = rmpos; (i + 1) < SPECVEC_FOO(_vector_size)(tthis); i++) {
154 /* Relocate the elements following the deleted element. */
155 tthis->p[i] = tthis->p[i + 1];
156 }
157
158 SPECVEC_FOO(_vector_reserve)(tthis,
159 SPECVEC_FOO(_vector_size)(tthis) - 1);
160}
161
162
163
164#define TYPED_VECTOR_ITERATE(atype, vector, var) { \
165 unsigned int myiter##var; \
166 atype *var; \
167 for (myiter##var = 0; myiter##var < (vector)->size; myiter##var++) { \
168 var = &(vector)->p[myiter##var]; \
169
170/* Balance for above: */
171#define VECTOR_ITERATE_END }}
172
173
174#undef SPECVEC_TAG
175#undef SPECVEC_TYPE
176#undef SPECVEC_PASTE_
177#undef SPECVEC_PASTE
178#undef SPECVEC_VECTOR
179#undef SPECVEC_FOO
180
181#ifdef __cplusplus
182}
183#endif /* __cplusplus */
incite_cost
char * incite_cost
Definition comments.c:74
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
mem.h
fc_realloc
#define fc_realloc(ptr, sz)
Definition mem.h:36
MAX
#define MAX(x, y)
Definition shared.h:54
_vector_append
static void SPECVEC_FOO() _vector_append(SPECVEC_VECTOR *tthis, SPECVEC_TYPE const pfoo)
Definition specvec.h:130
_vector_free
static void SPECVEC_FOO() _vector_free(SPECVEC_VECTOR *tthis)
Definition specvec.h:122
_vector_init
static void SPECVEC_FOO() _vector_init(SPECVEC_VECTOR *tthis)
Definition specvec.h:75
_vector_remove
static void SPECVEC_FOO() _vector_remove(SPECVEC_VECTOR *tthis, const int svindex)
Definition specvec.h:140
SPECVEC_FOO
#define SPECVEC_FOO(suffix)
Definition specvec.h:66
_vector_copy
static void SPECVEC_FOO() _vector_copy(SPECVEC_VECTOR *to, const SPECVEC_VECTOR *from)
Definition specvec.h:113
_vector_size
static size_t SPECVEC_FOO() _vector_size(const SPECVEC_VECTOR *tthis)
Definition specvec.h:94
size
size_t size
Definition specvec.h:72
size_alloc
size_t size_alloc
Definition specvec.h:72
SPECVEC_VECTOR
#define SPECVEC_VECTOR
Definition specvec.h:64
_vector_reserve
static void SPECVEC_FOO() _vector_reserve(SPECVEC_VECTOR *tthis, size_t size)
Definition specvec.h:81
_vector_get
static SPECVEC_TYPE *SPECVEC_FOO() _vector_get(const SPECVEC_VECTOR *tthis, int svindex)
Definition specvec.h:99
SPECVEC_TYPE
#define SPECVEC_TYPE
Definition specvec.h:58