ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/vector.h
(Generate patch)

Comparing projects/libstatgrab/src/libstatgrab/vector.h (file contents):
Revision 1.1 by ats, Sun Apr 4 21:17:58 2004 UTC vs.
Revision 1.4 by ats, Mon Apr 5 00:45:17 2004 UTC

# Line 12 | Line 12 | typedef struct {
12          vector_destroy_function destroy_fn;
13   } vector_header;
14  
15 < int statgrab_vector_resize(void **vector, vector_header *h, int count);
16 <
17 < /* Declare a vector. Specify the init/destroy functions as NULL if you don't
18 < * need them. The block size is how many items to allocate at once. */
19 < #define VECTOR_DECLARE(name, item_type, block_size, init_fn, destroy_fn) \
20 <        item_type * name = NULL; \
15 > #define VECTOR_HEADER(name, item_type, block_size, init_fn, destroy_fn) \
16          vector_header name##_header = { \
17                  sizeof(item_type), \
18                  0, \
# Line 27 | Line 22 | int statgrab_vector_resize(void **vector, vector_heade
22                  (vector_destroy_function) destroy_fn \
23          }
24  
25 + /* A pointer value that won't be returned by malloc, and isn't NULL, so can be
26 + * used as a sentinel by allocation routines that need to return NULL
27 + * sometimes. */
28 + extern char statgrab_vector_sentinel_value;
29 + static void *statgrab_vector_sentinel = &statgrab_vector_sentinel_value;
30 +
31 + /* Internal function to resize the vector. Ideally it would take void ** as the
32 + * first parameter, but ANSI strict-aliasing rules would then prevent it from
33 + * doing anything with it, so we return a sentinel value as above instead if
34 + * allocation fails. */
35 + void *statgrab_vector_resize(void *vector, vector_header *h, int count);
36 +
37 + /* Declare a vector. Specify the init/destroy functions as NULL if you don't
38 + * need them. The block size is how many items to allocate at once. */
39 + #define VECTOR_DECLARE(name, item_type, block_size, init_fn, destroy_fn) \
40 +        item_type *name = NULL; \
41 +        VECTOR_HEADER(name, item_type, block_size, init_fn, destroy_fn)
42 +
43 + /* As VECTOR_DECLARE, but for a static vector. */
44 + #define VECTOR_DECLARE_STATIC(name, item_type, block_size, init_fn, destroy_fn) \
45 +        static item_type *name = NULL; \
46 +        static VECTOR_HEADER(name, item_type, block_size, init_fn, destroy_fn)
47 +
48   /* Return the current size of a vector. */
49   #define VECTOR_SIZE(name) \
50          name##_header.used_count
51  
52   /* Resize a vector. Returns 0 on success, -1 on out-of-memory. On
53   * out-of-memory, the old contents of the vector will be destroyed and the old
54 < * vector will be freed. */
54 > * vector will be freed.
55 > *
56 > * This is ugly because it needs to check for the sentinel value.
57 > */
58   #define VECTOR_RESIZE(name, num_items) \
59 <        statgrab_vector_resize((void **) &name, &name##_header, num_items)
59 >        (((name = statgrab_vector_resize((char *) name, &name##_header, num_items)) \
60 >          == statgrab_vector_sentinel) ? -1 : 0)
61  
62   /* Free a vector, destroying its contents. */
63   #define VECTOR_FREE(name) \
64          VECTOR_RESIZE(name, 0)
43
65  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines