summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu/defs.h
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2012-01-20 13:41:10 +0000
committerkr.angelov <kr.angelov@gmail.com>2012-01-20 13:41:10 +0000
commit2eee382a62a909d5a3f2f5eda94f30fe68fd5335 (patch)
treeb0b0d513535895f244214aebf6358e172b8dce6d /src/runtime/c/gu/defs.h
parentb9728357126f8b9a6311cca17d9f0dcc2a7bfb9b (diff)
initial import of the C runtime
Diffstat (limited to 'src/runtime/c/gu/defs.h')
-rw-r--r--src/runtime/c/gu/defs.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/runtime/c/gu/defs.h b/src/runtime/c/gu/defs.h
new file mode 100644
index 000000000..9fa62b39b
--- /dev/null
+++ b/src/runtime/c/gu/defs.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2010 University of Helsinki.
+ *
+ * This file is part of libgu.
+ *
+ * Libgu is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * Libgu is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with libgu. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ *
+ * Miscellaneous macros.
+ */
+
+#ifndef GU_DEFS_H_
+#define GU_DEFS_H_
+
+#include <stddef.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <gu/sysdeps.h>
+
+#define gu_container(mem_p, container_type, member) \
+ ((container_type*)(((uint8_t*) (mem_p)) - offsetof(container_type, member)))
+/**< Find the address of a containing structure.
+ *
+ * If @c s has type @c t*, where @c t is a struct or union type with a
+ * member @m, then <tt>GU_CONTAINER_P(&s->m, t, m) == s</tt>.
+ *
+ * @param mem_p Pointer to the member of a structure.
+ * @param container_type The type of the containing structure.
+ * @param member The name of the member of @a container_type
+ * @return The address of the containing structure.
+ *
+ * @hideinitializer */
+
+
+#define gu_member_p(struct_p_, offset_) \
+ ((void*)&((uint8_t*)(struct_p_))[offset_])
+
+#define gu_member(t_, struct_p_, offset_) \
+ (*(t_*)gu_member_p(struct_p_, offset_))
+
+#ifdef GU_ALIGNOF
+# define gu_alignof GU_ALIGNOF
+# define GU_ALIGNOF_WORKS_ON_FAM_STRUCTS
+#else
+# define gu_alignof(t_) \
+ ((size_t)(offsetof(struct { char c_; t_ e_; }, e_)))
+# ifdef GU_CAN_HAVE_FAM_IN_MEMBER
+# define GU_ALIGNOF_WORKS_ON_FAM_STRUCTS
+# endif
+#endif
+
+#define GU_PLIT(type, expr) \
+ ((type[1]){ expr })
+
+#define GU_LVALUE(type, expr) \
+ (*((type[1]){ expr }))
+
+#define GU_COMMA ,
+
+#define GU_ARRAY_LEN(t,a) (sizeof((const t[])a) / sizeof(t))
+
+#define GU_ID(...) __VA_ARGS__
+
+// This trick is by Laurent Deniau <laurent.deniau@cern.ch>
+#define GU_N_ARGS(...) \
+ GU_N_ARGS_(__VA_ARGS__, \
+ 31,30,29,28,27,26,25,24, \
+ 23,22,21,20,19,18,17,16, \
+ 15,14,13,12,11,10,9,8, \
+ 7,6,5,4,3,2,1,0)
+#define GU_N_ARGS_(...) GU_N_ARGS__(__VA_ARGS__)
+#define GU_N_ARGS__(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p, \
+ q,r,s,t,u,v,w,x,y,z,aa,ab,ac,ad,ae,N,...) \
+ N
+
+#define GU_ARG1(a1, ...) a1
+#define GU_ARG2(a1, a2, ...) a2
+
+#define GU_BEGIN do {
+#define GU_END } while (false)
+
+#define GU_NOP GU_BEGIN (void) 0; GU_END
+
+/**< @hideinitializer */
+
+//
+// Assert
+//
+
+#define GU_MAX(a_, b_) ((a_) > (b_) ? (a_) : (b_))
+#define GU_MIN(a_, b_) ((a_) < (b_) ? (a_) : (b_))
+
+static inline int
+gu_max(int a, int b) {
+ return GU_MAX(a, b);
+}
+
+static inline int
+gu_min(int a, int b) {
+ return GU_MIN(a, b);
+}
+
+#ifdef GU_ALIGNOF_WORKS_ON_FAM_STRUCTS
+#define gu_flex_alignof gu_alignof
+#else
+#define gu_flex_alignof(t) 0
+#endif
+
+static inline size_t
+gu_flex_size(size_t ssize, size_t offset, int n_elems, size_t e_size)
+{
+ return GU_MAX(ssize, offset + n_elems * e_size);
+}
+
+#define GU_FLEX_SIZE(type, flex_member, n_elems) \
+ gu_flex_size(sizeof(type), offsetof(type, flex_member), \
+ n_elems, sizeof(((type*)NULL)->flex_member[0]))
+
+
+// The following are directly from gmacros.h in GLib
+
+#define GU_PASTE_ARGS(id1_,id2_) \
+ id1_ ## id2_
+
+#define GU_PASTE(id1_, id2_) \
+ GU_PASTE_ARGS(id1_, id2_)
+
+#define GU_STATIC_ASSERT(expr_) \
+ typedef struct { \
+ char static_assert[(expr_) ? 1 : -1]; \
+ } GU_PASTE(GuStaticAssert_, __LINE__)
+
+
+#define GU_ENSURE_TYPE(T, EXPR) \
+ ((void)(sizeof(*(T*)NULL=(EXPR))),(EXPR))
+
+#define GU_END_DECLS \
+ extern void gu_dummy_(void)
+
+extern void* const gu_null;
+
+// Dummy struct used for generic struct pointers
+typedef struct GuStruct GuStruct;
+
+extern GuStruct* const gu_null_struct;
+
+typedef uintptr_t GuWord;
+
+#define GU_WORD_MAX UINTPTR_MAX
+
+// TODO: use max_align_t once C1X is supported
+typedef union {
+ char c;
+ short s;
+ int i;
+ long l;
+ long long ll;
+ intmax_t im;
+ float f;
+ double d;
+ long double ld;
+ void* p;
+ void (*fp)();
+} GuMaxAlign;
+
+#define gu_alloca(N) \
+ (((union { GuMaxAlign align_; uint8_t buf_[N]; }){{0}}).buf_)
+
+
+// For Doxygen
+#define GU_PRIVATE /** @private */
+
+#ifdef GU_GNUC
+# define GU_LIKELY(EXPR) __builtin_expect(EXPR, 1)
+# define GU_UNLIKELY(EXPR) __builtin_expect(EXPR, 0)
+# define GU_IS_CONSTANT(EXPR) __builtin_constant_p(EXPR)
+#else
+# define GU_LIKELY(EXPR) (EXPR)
+# define GU_UNLIKELY(EXPR) (EXPR)
+# ifdef GU_OPTIMIZE_SIZE
+# define GU_IS_CONSTANT(EXPR) false
+# else
+# define GU_IS_CONSTANT(EXPR) true
+# endif
+#endif
+
+// Splint annotations
+#define GU_ONLY GU_SPLINT(only)
+#define GU_NULL GU_SPLINT(null)
+#define GU_NOTNULL GU_SPLINT(notnull)
+#define GU_RETURNED GU_SPLINT(returned)
+#define GU_ABSTRACT GU_SPLINT(abstract)
+#define GU_IMMUTABLE GU_SPLINT(immutable)
+#define GU_NOTREACHED GU_SPLINT(notreached)
+#define GU_UNUSED GU_SPLINT(unused) GU_GNUC_ATTR(unused)
+#define GU_OUT GU_SPLINT(out)
+#define GU_IN GU_SPLINT(in)
+#define GU_NORETURN GU_SPLINT(noreturn) GU_GNUC_ATTR(noreturn)
+#define GU_MODIFIES(x) GU_SPLINT(modifies x)
+
+#endif // GU_DEFS_H_