[Freeciv-Dev] Re: (PR#8683) remove specvec?
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8683 >
After discussion with Vasco, I think specvec should stay but become a
wrapper for an array. To wit:
- It should not be a wrapper for athing but should use its own
implementation. This sounds like a big deal but it's not: only 8
additional lines of code are required, and the implementation is faster.
The difference here is that specvecs have constant, known size whereas
athings must have their size given on initialization. See the attached
patch.
- Users should be allowed to access the array directly. The functions
are therefore just a convenient way to resize the data. Why call
foo_vector_get(v, 5) when you can just have v->vec[5]? It would be nice
to access the data as v[5] but this would require some very ugly "magic".
- Eventually astring and athing should be replaced by specvecs. These
are just special-cases of convenient resizable arrays.
jason
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.115
diff -u -r1.115 player.h
--- common/player.h 23 Apr 2004 22:58:06 -0000 1.115
+++ common/player.h 7 May 2004 00:28:03 -0000
@@ -219,6 +219,9 @@
bool debug;
};
+#define SPECVEC_TAG player
+#include "specvec.h"
+
void player_init(struct player *plr);
struct player *find_player_by_name(const char *name);
struct player *find_player_by_name_prefix(const char *name,
Index: utility/specvec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/specvec.h,v
retrieving revision 1.4
diff -u -r1.4 specvec.h
--- utility/specvec.h 6 May 2004 22:57:36 -0000 1.4
+++ utility/specvec.h 7 May 2004 00:28:03 -0000
@@ -13,8 +13,7 @@
/* specvectors: "specific vectors".
- This file is used to implement type-checked vectors (variable size arrays).
- (Or, maybe, what you end up doing when you don't use C++ ?)
+ This file is used to implement resizable arrays.
Before including this file, you must define the following:
SPECVEC_TAG - this tag will be used to form names for functions etc.
@@ -34,10 +33,6 @@
void foo_vector_copy(struct foo_vector *to, struct foo_vector *from);
void foo_vector_free(struct foo_vector *tthis);
- Also, in a single .c file, you should include specvec_c.h,
- with the same SPECVEC_TAG and SPECVEC_TYPE defined, to
- provide the function implementations.
-
Note this is not protected against multiple inclusions; this is
so that you can have multiple different specvectors. For each
specvector, this file should be included _once_, inside a .h file
@@ -47,7 +42,7 @@
#include <assert.h>
#include <string.h> /* for memcpy */
-#include "astring.h"
+#include "mem.h"
#ifndef SPECVEC_TAG
#error Must define a SPECVEC_TAG to use this header
@@ -64,7 +59,8 @@
#define SPECVEC_FOO(suffix) SPECVEC_PASTE(SPECVEC_TAG, suffix)
SPECVEC_VECTOR {
- struct athing vector;
+ size_t size, size_alloc;
+ SPECVEC_TYPE *vec;
};
#ifndef SPECVEC_TAG
@@ -84,44 +80,50 @@
static inline void SPECVEC_FOO(_vector_init) (SPECVEC_VECTOR *tthis)
{
- ath_init(&tthis->vector, sizeof(SPECVEC_TYPE));
+ tthis->vec = NULL;
+ tthis->size = tthis->size_alloc = 0;
}
static inline void SPECVEC_FOO(_vector_reserve) (SPECVEC_VECTOR *tthis, int n)
{
- ath_minnum(&tthis->vector, n);
+ if (n > tthis->size_alloc) {
+ int new_size = MAX(n, tthis->size_alloc * 2);
+
+ tthis->vec = fc_realloc(tthis->vec, new_size * sizeof(*tthis->vec));
+ tthis->size_alloc = new_size;
+ }
+ tthis->size = n;
}
static inline size_t SPECVEC_FOO(_vector_size) (SPECVEC_VECTOR *tthis)
{
- return tthis->vector.n;
+ return tthis->size;
}
static inline SPECVEC_TYPE *SPECVEC_FOO(_vector_get) (SPECVEC_VECTOR *tthis,
int index)
{
- assert(index>=0 && index<tthis->vector.n);
-
- return ((SPECVEC_TYPE *)ath_get(&tthis->vector, index));
+ if (index < 0 || index >= tthis->size) {
+ assert(index >= 0 && index < tthis->size);
+ return NULL;
+ } else {
+ return tthis->vec + index;
+ }
}
-/* You must _init "*to" before using this function */
+/* "to" need not be initialized but cannot contain other data. */
static inline void SPECVEC_FOO(_vector_copy) (SPECVEC_VECTOR *to,
SPECVEC_VECTOR *from)
{
- int i;
- size_t size = SPECVEC_FOO(_vector_size) (from);
-
- SPECVEC_FOO(_vector_reserve) (to, size);
-
- for (i = 0; i < size; i++) {
- memcpy(SPECVEC_FOO(_vector_get) (to, i),
- SPECVEC_FOO(_vector_get) (from, i),
- sizeof(SPECVEC_TYPE));
- }
+ SPECVEC_FOO(_vector_init) (to);
+ SPECVEC_FOO(_vector_reserve) (to, from->size);
+ memcpy(to->vec, from->vec, from->size * sizeof(*to->vec));
}
static inline void SPECVEC_FOO(_vector_free) (SPECVEC_VECTOR *tthis)
{
- ath_free(&tthis->vector);
+ if (tthis->vec) {
+ free(tthis->vec);
+ }
+ SPECVEC_FOO(_vector_init)(tthis);
}
#undef SPECVEC_TAG
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Jason Short, 2004/05/05
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Mike Kaufman, 2004/05/05
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Jason Short, 2004/05/05
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Vasco Alexandre da Silva Costa, 2004/05/05
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Vasco Alexandre da Silva Costa, 2004/05/05
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Per Inge Mathisen, 2004/05/06
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Jason Short, 2004/05/06
- [Freeciv-Dev] Re: (PR#8683) remove specvec?,
Jason Short <=
- [Freeciv-Dev] Re: (PR#8683) remove specvec?, Mike Kaufman, 2004/05/06
- [Freeciv-Dev] (PR#8683) rewrite specvec so it doesn't use athing, Jason Short, 2004/05/12
- [Freeciv-Dev] (PR#8683) specvec iterator patch, Vasco Alexandre da Silva Costa, 2004/05/14
- [Freeciv-Dev] (PR#8683) specvec iterator patch v2, Vasco Alexandre da Silva Costa, 2004/05/14
- [Freeciv-Dev] (PR#8683) specvec patch v3, Vasco Alexandre da Silva Costa, 2004/05/14
|
|