root/kern/include/array.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. array_num
  2. array_get
  3. array_set
  4. array_add

   1 /*-
   2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
   3  * All rights reserved.
   4  *
   5  * This code is derived from software contributed to The NetBSD Foundation
   6  * by David A. Holland.
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions
  10  * are met:
  11  * 1. Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27  * POSSIBILITY OF SUCH DAMAGE.
  28  */
  29 
  30 #ifndef _ARRAY_H_
  31 #define _ARRAY_H_
  32 
  33 #ifdef UW
  34 #include <lib.h>
  35 #endif
  36 
  37 #define ARRAYS_CHECKED
  38 
  39 #ifdef ARRAYS_CHECKED
  40 #define ARRAYASSERT KASSERT
  41 #else
  42 #define ARRAYASSERT(x) ((void)(x))
  43 #endif
  44 
  45 /*
  46  * Base array type (resizeable array of void pointers) and operations.
  47  *
  48  * create - allocate an array.
  49  * destroy - destroy an allocated array.
  50  * init - initialize an array in space externally allocated.
  51  * cleanup - clean up an array in space exteranlly allocated.
  52  * num - return number of elements in array.
  53  * get - return element no. INDEX.
  54  * set - set element no. INDEX to VAL.
  55  * setsize - change size to NUM elements; may fail and return error.
  56  * add - append VAL to end of array; return its index in INDEX_RET if
  57  *       INDEX_RET isn't null; may fail and return error.
  58  * remove - excise entry INDEX and slide following entries down to
  59  *       close the resulting gap.
  60  *
  61  * Note that expanding an array with setsize doesn't initialize the new
  62  * elements. (Usually the caller is about to store into them anyway.)
  63  */
  64 
  65 struct array {
  66         void **v;
  67         unsigned num, max;
  68 };
  69 
  70 struct array *array_create(void);
  71 void array_destroy(struct array *);
  72 void array_init(struct array *);
  73 void array_cleanup(struct array *);
  74 unsigned array_num(const struct array *);
  75 void *array_get(const struct array *, unsigned index);
  76 void array_set(const struct array *, unsigned index, void *val);
  77 int array_setsize(struct array *, unsigned num);
  78 int array_add(struct array *, void *val, unsigned *index_ret);
  79 void array_remove(struct array *, unsigned index);
  80 
  81 /*
  82  * Inlining for base operations
  83  */
  84 
  85 #ifndef ARRAYINLINE
  86 #define ARRAYINLINE INLINE
  87 #endif
  88 
  89 ARRAYINLINE unsigned
  90 array_num(const struct array *a)
  91 {
  92         return a->num;
  93 }
  94 
  95 ARRAYINLINE void *
  96 array_get(const struct array *a, unsigned index)
  97 {
  98         ARRAYASSERT(index < a->num);
  99         return a->v[index];
 100 }
 101 
 102 ARRAYINLINE void
 103 array_set(const struct array *a, unsigned index, void *val)
 104 {
 105         ARRAYASSERT(index < a->num);
 106         a->v[index] = val;
 107 }
 108 
 109 ARRAYINLINE int
 110 array_add(struct array *a, void *val, unsigned *index_ret)
 111 {
 112         unsigned index;
 113         int ret;
 114 
 115         index = a->num;
 116         ret = array_setsize(a, index+1);
 117         if (ret) {
 118                 return ret;
 119         }
 120         a->v[index] = val;
 121         if (index_ret != NULL) {
 122                 *index_ret = index;
 123         }
 124         return 0;
 125 }
 126 
 127 /*
 128  * Bits for declaring and defining typed arrays.
 129  *
 130  * Usage:
 131  *
 132  * DECLARRAY_BYTYPE(foo, bar) declares "struct foo", which is
 133  * an array of pointers to "bar", plus the operations on it.
 134  *
 135  * DECLARRAY(foo) is equivalent to DECLARRAY_BYTYPE(fooarray, struct foo).
 136  *
 137  * DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that
 138  * they define the operations, and both take an extra argument INLINE.
 139  * For C99 this should be INLINE in header files and empty in the
 140  * master source file, the same as the usage of ARRAYINLINE above and
 141  * in array.c.
 142  *
 143  * Example usage in e.g. item.h of some game:
 144  * 
 145  * DECLARRAY_BYTYPE(stringarray, char);
 146  * DECLARRAY(potion);
 147  * DECLARRAY(sword);
 148  *
 149  * #ifndef ITEMINLINE
 150  * #define ITEMINLINE INLINE
 151  * #endif
 152  *
 153  * DEFARRAY_BYTYPE(stringarray, char, ITEMINLINE);
 154  * DEFARRAY(potion, ITEMINLINE);
 155  * DEFARRAY(sword, ITEMINLINE);
 156  *
 157  * Then item.c would do "#define ITEMINLINE" before including item.h.
 158  *
 159  * This creates types "struct stringarray", "struct potionarray",
 160  * and "struct swordarray", with operations such as "swordarray_num".
 161  *
 162  * The operations on typed arrays are the same as the operations on
 163  * the base array, except typed.
 164  */
 165 
 166 #define DECLARRAY_BYTYPE(ARRAY, T) \
 167         struct ARRAY {                                          \
 168                 struct array arr;                               \
 169         };                                                      \
 170                                                                 \
 171         struct ARRAY *ARRAY##_create(void);                     \
 172         void ARRAY##_destroy(struct ARRAY *a);                  \
 173         void ARRAY##_init(struct ARRAY *a);                     \
 174         void ARRAY##_cleanup(struct ARRAY *a);                  \
 175         unsigned ARRAY##_num(const struct ARRAY *a);            \
 176         T *ARRAY##_get(const struct ARRAY *a, unsigned index);  \
 177         void ARRAY##_set(struct ARRAY *a, unsigned index, T *val); \
 178         int ARRAY##_setsize(struct ARRAY *a, unsigned num);     \
 179         int ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret); \
 180         void ARRAY##_remove(struct ARRAY *a, unsigned index)
 181 
 182 #define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \
 183         INLINE struct ARRAY *                                   \
 184         ARRAY##_create(void)                                    \
 185         {                                                       \
 186                 struct ARRAY *a = kmalloc(sizeof(*a));          \
 187                 if (a == NULL) {                                \
 188                         return NULL;                            \
 189                 }                                               \
 190                 array_init(&a->arr);                            \
 191                 return a;                                       \
 192         }                                                       \
 193                                                                 \
 194         INLINE void                                             \
 195         ARRAY##_destroy(struct ARRAY *a)                        \
 196         {                                                       \
 197                 array_cleanup(&a->arr);                         \
 198                 kfree(a);                                       \
 199         }                                                       \
 200                                                                 \
 201         INLINE void                                             \
 202         ARRAY##_init(struct ARRAY *a)                           \
 203         {                                                       \
 204                 array_init(&a->arr);                            \
 205         }                                                       \
 206                                                                 \
 207         INLINE void                                             \
 208         ARRAY##_cleanup(struct ARRAY *a)                        \
 209         {                                                       \
 210                 array_cleanup(&a->arr);                         \
 211         }                                                       \
 212                                                                 \
 213         INLINE unsigned                                         \
 214         ARRAY##_num(const struct ARRAY *a)                      \
 215         {                                                       \
 216                 return array_num(&a->arr);                      \
 217         }                                                       \
 218                                                                 \
 219         INLINE T *                                              \
 220         ARRAY##_get(const struct ARRAY *a, unsigned index)      \
 221         {                                                       \
 222                 return (T *)array_get(&a->arr, index);          \
 223         }                                                       \
 224                                                                 \
 225         INLINE void                                             \
 226         ARRAY##_set(struct ARRAY *a, unsigned index, T *val)    \
 227         {                                                       \
 228                 array_set(&a->arr, index, (void *)val);         \
 229         }                                                       \
 230                                                                 \
 231         INLINE int                                              \
 232         ARRAY##_setsize(struct ARRAY *a, unsigned num)          \
 233         {                                                       \
 234                 return array_setsize(&a->arr, num);             \
 235         }                                                       \
 236                                                                 \
 237         INLINE int                                              \
 238         ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret) \
 239         {                                                       \
 240                 return array_add(&a->arr, (void *)val, index_ret); \
 241         }                                                       \
 242                                                                 \
 243         INLINE void                                             \
 244         ARRAY##_remove(struct ARRAY *a, unsigned index)         \
 245         {                                                       \
 246                 return array_remove(&a->arr, index);            \
 247         }
 248 
 249 #define DECLARRAY(T) DECLARRAY_BYTYPE(T##array, struct T)
 250 #define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE)
 251 
 252 /*
 253  * This is how you declare an array of strings; it works out as
 254  * an array of pointers to char.
 255  */
 256 DECLARRAY_BYTYPE(stringarray, char);
 257 DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
 258 
 259 
 260 #endif /* ARRAY_H */

/* [<][>][^][v][top][bottom][index][help] */