Project

General

Profile

Download (2.1 KB) Statistics
| Branch: | Tag: | Revision:
7e8045d8 David Sorber
#ifndef __SIMPLEST_DEFS_H__
#define __SIMPLEST_DEFS_H__


#include <stddef.h>
#include <stdint.h>

#include "sparse.h"


/* FIXME [matteof 2017-06-16] The name of this type is wrong. */

/* BOOLINT intends to provide a type that can be stored in
structs without worrying about alignment, and is compatible
with C's rules, so that

boolint foo = (1 != 0);
foo && (...)

work.
*/
typedef ptrdiff_t boolint;
#define FMTboolint "%td"

#if defined(__clang__)
#define __enum64
#define ENUM_AS_UINT64(e) uint64_t
#else
#define __enum64 __attribute__((mode(DI)))
#define ENUM_AS_UINT64(e) e
#endif

#define UNUSED(x) ((void)(x))
#define STATIC_ASSERT(truth) \
extern char \
(*static_assert_test_array__(void))[sizeof(char[(2 * !!(truth)) - 1])]

// See
// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/cpp/Stringification.html
// for an explanation of why the extra level of macro expansion might
// be needed.
//
#define STRINGIFY(x) #x
#define XSTRINGIFY(x) STRINGIFY(x)

#define SAME_TYPE(a, b) (__builtin_types_compatible_p(typeof(a), typeof(b)))

#define POINTER_IS_ARRAY(a) (!SAME_TYPE((a), &(a)[0]))

// Statically calculate size of array
// Provide compile error if
// - a is not a pointer
// - a is not an array (e.g. regular pointer, "array" function parameter)
// Casting to ssize_t is necessary because y and z in (x?y:z) need to be the
// same type and we need the -1 to get the compile error
//
// ({STATIC_ASSERT(POINTER_IS_ARRAY(a)); sizeof(a)/sizeof((a)[0]);})
// does not work because our STATIC_ASSERT is not smart enough to be nested
// (NELEM is often used inside STATIC_ASSERT)
//
// The type of X in char[X] should be ptrdiff_t, but we want to avoid forcing
// the gratuitous inclusion of <stddef.h>. "long" is good enough for the
// purpose.
//
#define NELEM(a) \
(sizeof(char[POINTER_IS_ARRAY(a) ? \
(__force long)(sizeof(a) / sizeof((a)[0])) : \
(long)-1]))

#endif // !__SIMPLEST_DEFS_H__