diff array.h @ 47:2e25e55dba6b

Fix inline usage as per the version in dholland-make2.
author David A. Holland
date Sat, 30 Mar 2013 23:05:59 -0400
parents 337110e7240a
children 0921c47b4f22
line wrap: on
line diff
--- a/array.h	Sat Mar 30 22:35:06 2013 -0400
+++ b/array.h	Sat Mar 30 23:05:59 2013 -0400
@@ -42,6 +42,10 @@
 #define arrayassert(x) ((void)(x))
 #endif
 
+#ifndef ARRAYINLINE
+#define ARRAYINLINE __c99inline
+#endif
+
 ////////////////////////////////////////////////////////////
 // type and base operations
 
@@ -54,21 +58,17 @@
 void array_destroy(struct array *);
 void array_init(struct array *);
 void array_cleanup(struct array *);
-unsigned array_num(const struct array *);
-void *array_get(const struct array *, unsigned index_);
-void array_set(const struct array *, unsigned index_, void *val);
+ARRAYINLINE unsigned array_num(const struct array *);
+ARRAYINLINE void *array_get(const struct array *, unsigned index_);
+ARRAYINLINE void array_set(const struct array *, unsigned index_, void *val);
 void array_setsize(struct array *, unsigned num);
-void array_add(struct array *, void *val, unsigned *index_ret);
+ARRAYINLINE void array_add(struct array *, void *val, unsigned *index_ret);
 void array_insert(struct array *a, unsigned index_);
 void array_remove(struct array *a, unsigned index_);
 
 ////////////////////////////////////////////////////////////
 // inlining for base operations
 
-#ifndef ARRAYINLINE
-#define ARRAYINLINE __c99inline
-#endif
-
 ARRAYINLINE unsigned
 array_num(const struct array *a)
 {
@@ -106,50 +106,75 @@
 /*
  * Usage:
  *
- * DECLARRAY_BYTYPE(foo, bar) declares "struct foo", which is
+ * DECLARRAY_BYTYPE(foo, bar, INLINE) declares "struct foo", which is
  * an array of pointers to "bar", plus the operations on it.
  *
- * DECLARRAY(foo) is equivalent to DECLARRAY_BYTYPE(fooarray, struct foo).
+ * DECLARRAY(foo, INLINE) is equivalent to
+ * DECLARRAY_BYTYPE(fooarray, struct foo, INLINE).
  *
  * DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that
- * they define the operations, and both take an extra argument INLINE.
- * For C99 this should be INLINE in header files and empty in the
- * master source file, the same as the usage of ARRAYINLINE above and
- * in array.c.
+ * they define the operations.
+ *
+ * The argument INLINE can be used as follows:
+ *
+ * 1. For no inlining:
+ *    In foo.h:
+ *           DECLARRAY(foo, );
+ *    In foo.c:
+ *           DEFARRAY(foo, );
+ *
+ * 2. To be file-static:
+ *    In foo.c:
+ *           DECLARRAY(foo, static);
+ *           DEFARRAY(foo, static);
+ *
+ * 3. To inline using C99:
+ *    In foo.h:
+ *           DECLARRAY(foo, inline);
+ *           DEFARRAY(foo, inline);
  *
- * Example usage in e.g. item.h of some game:
- * 
- * DECLARRAY_BYTYPE(stringarray, char);
- * DECLARRAY(potion);
- * DECLARRAY(sword);
+ * 4. To inline with old gcc:
+ *    In foo.h:
+ *           #ifndef FOO_INLINE
+ *           #define FOO_INLINE extern inline
+ *           #endif
+ *           DECLARRAY(foo, );
+ *           DEFARRAY(foo, FOO_INLINE);
+ *    In foo.c:
+ *           #define FOO_INLINE
+ *           #include "foo.h"
  *
- * #ifndef ITEMINLINE
- * #define ITEMINLINE INLINE
- * #endif
+ * 5. To inline such that it works both with old gcc and C99:
+ *    In foo.h:
+ *           #ifndef FOO_INLINE
+ *           #define FOO_INLINE extern inline
+ *           #endif
+ *           DECLARRAY(foo, FOO_INLINE);
+ *           DEFARRAY(foo, FOO_INLINE);
+ *    In foo.c:
+ *           #define FOO_INLINE
+ *           #include "foo.h"
  *
- * DEFARRAY_BYTYPE(stringarray, char, ITEMINLINE);
- * DEFARRAY(potion, ITEMINLINE);
- * DEFARRAY(sword, ITEMINLINE);
- *
- * Then item.c would do "#define ITEMINLINE" before including item.h.
+ * The mechanism in case (4) ensures that an externally linkable
+ * definition exists.
  */
 
-#define DECLARRAY_BYTYPE(ARRAY, T) \
-	struct ARRAY {						\
-		struct array arr;				\
-	};							\
-								\
-	struct ARRAY *ARRAY##_create(void);			\
-	void ARRAY##_destroy(struct ARRAY *a);			\
-	void ARRAY##_init(struct ARRAY *a);			\
-	void ARRAY##_cleanup(struct ARRAY *a);			\
-	unsigned ARRAY##_num(const struct ARRAY *a);		\
-	T *ARRAY##_get(const struct ARRAY *a, unsigned index_);	\
-	void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \
-	void ARRAY##_setsize(struct ARRAY *a, unsigned num);	\
-	void ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret); \
-	void ARRAY##_insert(struct ARRAY *a, unsigned index_);	\
-	void ARRAY##_remove(struct ARRAY *a, unsigned index_)
+#define DECLARRAY_BYTYPE(ARRAY, T, INLINE) \
+	struct ARRAY {							\
+		struct array arr;					\
+	};								\
+									\
+	INLINE struct ARRAY *ARRAY##_create(void);			\
+	INLINE void ARRAY##_destroy(struct ARRAY *a);			\
+	INLINE void ARRAY##_init(struct ARRAY *a);			\
+	INLINE void ARRAY##_cleanup(struct ARRAY *a);			\
+	INLINE unsigned ARRAY##_num(const struct ARRAY *a);		\
+	INLINE T *ARRAY##_get(const struct ARRAY *a, unsigned index_);	\
+	INLINE void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \
+	INLINE void ARRAY##_setsize(struct ARRAY *a, unsigned num);	\
+	INLINE void ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret);\
+	INLINE void ARRAY##_insert(struct ARRAY *a, unsigned index_);	\
+	INLINE void ARRAY##_remove(struct ARRAY *a, unsigned index_)
 
 
 #define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \
@@ -224,7 +249,7 @@
 		array_remove(&a->arr, index_);			\
 	}
 
-#define DECLARRAY(T) DECLARRAY_BYTYPE(T##array, struct T)
+#define DECLARRAY(T, INLINE) DECLARRAY_BYTYPE(T##array, struct T, INLINE)
 #define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE)
 
 #define DESTROYALL_ARRAY(T, INLINE) \
@@ -248,7 +273,7 @@
 ////////////////////////////////////////////////////////////
 // basic array types
 
-DECLARRAY_BYTYPE(stringarray, char);
+DECLARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
 DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
 
 #endif /* ARRAY_H */