2019-05-03 17:49:57 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
General Macros
|
2020-04-02 16:58:38 -04:00
|
|
|
|
2023-01-03 08:26:44 +07:00
|
|
|
Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
|
2020-04-02 16:58:38 -04:00
|
|
|
Portions Copyright (c) 1994, Regents of the University of California
|
2019-05-03 17:49:57 -04:00
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#ifndef COMMON_MACRO_H
|
|
|
|
#define COMMON_MACRO_H
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Convert the parameter to a zero-terminated string
|
|
|
|
|
2019-05-13 18:05:54 -04:00
|
|
|
Useful for converting non-string types (e.g. int) to strings for inclusion in messages.
|
2019-05-03 17:49:57 -04:00
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define STRINGIFY_HELPER(param) #param
|
|
|
|
#define STRINGIFY(param) STRINGIFY_HELPER(param)
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Glue together a string/macro and another string//macro
|
|
|
|
|
|
|
|
Useful for creating function names when one or both of the macro parameter needs to be converted to a macro before concatenating.
|
2020-03-30 20:52:57 -04:00
|
|
|
common/type/object.h has numerous examples of this.
|
2019-05-03 17:49:57 -04:00
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define GLUE_HELPER(param1, param2) param1##param2
|
|
|
|
#define GLUE(param1, param2) GLUE_HELPER(param1, param2)
|
|
|
|
|
2019-05-13 18:05:54 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
If param2 > param1 then assign it to param1
|
|
|
|
|
2019-08-26 12:05:36 -04:00
|
|
|
Useful for ensuring coverage in cases where compared values may be always ascending or descending.
|
2019-05-13 18:05:54 -04:00
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define MAX_ASSIGN(param1, param2) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
if (param2 > param1) \
|
|
|
|
param1 = param2; \
|
|
|
|
} \
|
|
|
|
while (0)
|
|
|
|
|
2020-04-02 16:58:38 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
If the "condition" (a compile-time-constant expression) evaluates to false then throw a compile error using the "message" (a string
|
|
|
|
literal).
|
|
|
|
|
2023-05-02 12:57:12 +03:00
|
|
|
gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic placement restrictions. Macros STATIC_ASSERT_STMT() and
|
2020-04-02 16:58:38 -04:00
|
|
|
STATIC_ASSERT_EXP() make it safe to use as a statement or in an expression, respectively.
|
|
|
|
|
2023-05-02 12:57:12 +03:00
|
|
|
Otherwise we fall back on a kluge that assumes the compiler will complain about a negative width for a struct bit-field. This will
|
2020-04-02 16:58:38 -04:00
|
|
|
not include a helpful error message, but it beats not getting an error at all. Note that when std=c99 it looks like gcc is using the
|
|
|
|
same kluge.
|
|
|
|
|
|
|
|
Adapted from PostgreSQL src/include/c.h.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#ifdef HAVE_STATIC_ASSERT
|
|
|
|
|
|
|
|
#define STATIC_ASSERT_STMT(condition, message) \
|
2020-05-01 09:31:50 -04:00
|
|
|
do {_Static_assert(condition, message);} while (0)
|
2023-01-30 11:55:54 +07:00
|
|
|
|
2020-04-02 16:58:38 -04:00
|
|
|
#define STATIC_ASSERT_EXPR(condition, message) \
|
|
|
|
((void)({STATIC_ASSERT_STMT(condition, message); true;}))
|
2023-01-30 11:55:54 +07:00
|
|
|
|
2020-04-02 16:58:38 -04:00
|
|
|
#else
|
|
|
|
|
|
|
|
#define STATIC_ASSERT_STMT(condition, message) \
|
|
|
|
((void)sizeof(struct {int static_assert_failure : (condition) ? 1 : -1;}))
|
2023-01-30 11:55:54 +07:00
|
|
|
|
2020-04-02 16:58:38 -04:00
|
|
|
#define STATIC_ASSERT_EXPR(condition, message) \
|
|
|
|
STATIC_ASSERT_STMT(condition, message)
|
2023-01-30 11:55:54 +07:00
|
|
|
|
2020-04-02 16:58:38 -04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Allows casting const-ness away from an expression, but doesn't allow changing the type. Enforcement of the latter currently only
|
|
|
|
works for gcc-like compilers.
|
|
|
|
|
|
|
|
Note that it is not safe to cast const-ness away if the result will ever be modified (it would be undefined behavior). Doing so can
|
|
|
|
cause compiler mis-optimizations or runtime crashes (by modifying read-only memory). It is only safe to use when the result will not
|
|
|
|
be modified, but API design or language restrictions prevent you from declaring that (e.g. because a function returns both const and
|
|
|
|
non-const variables).
|
|
|
|
|
|
|
|
Note that this only works in function scope, not for global variables (it would be nice, but not trivial, to improve that).
|
|
|
|
|
|
|
|
Adapted from PostgreSQL src/include/c.h.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#ifdef HAVE_BUILTIN_TYPES_COMPATIBLE_P
|
|
|
|
#define UNCONSTIFY(type, expression) \
|
|
|
|
(STATIC_ASSERT_EXPR(__builtin_types_compatible_p(__typeof(expression), const type), "invalid cast"), (type)(expression))
|
|
|
|
#else
|
|
|
|
#define UNCONSTIFY(type, expression) \
|
|
|
|
((type)(expression))
|
|
|
|
#endif
|
|
|
|
|
2022-03-24 17:55:38 -06:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Determine the alignment of a data type
|
|
|
|
|
|
|
|
This macro reduces to a constant so it is safe to use anywhere a constant is allowed, e.g. a switch statement case.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define ALIGN_OF(type) ((size_t)&((struct {char c; type t;} *)0)->t)
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Determine the byte offset required to align a type after an arbitrary number of bytes
|
|
|
|
|
|
|
|
This is useful for determining how to correctly align a type in a buffer that is being dynamically built up like a struct.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define ALIGN_OFFSET(type, bytes) (ALIGN_OF(type) - ((bytes) % ALIGN_OF(type)))
|
|
|
|
|
2022-04-22 09:14:12 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Determine size of a type in a struct
|
|
|
|
|
|
|
|
Using sizeof() on a struct member requires additional syntax.
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define SIZE_OF_STRUCT_MEMBER(struct, member) sizeof(((struct){0}).member)
|
|
|
|
|
2022-04-07 19:00:15 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Determine the length of an array that can be determined at compile time
|
|
|
|
|
|
|
|
For this macro to work correctly the array must be declared like:
|
|
|
|
|
|
|
|
int intList[] = {0, 1};
|
|
|
|
|
|
|
|
It will not work for an array declared like:
|
|
|
|
|
|
|
|
int *intList;
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
#define LENGTH_OF(array) (sizeof(array) / sizeof((array)[0]))
|
|
|
|
|
2019-05-03 17:49:57 -04:00
|
|
|
#endif
|