diff options
Diffstat (limited to 'libmisc/include')
-rw-r--r-- | libmisc/include/libmisc/macro.h | 41 | ||||
-rw-r--r-- | libmisc/include/libmisc/vcall.h | 28 |
2 files changed, 40 insertions, 29 deletions
diff --git a/libmisc/include/libmisc/macro.h b/libmisc/include/libmisc/macro.h index 9bb068f..d11b99f 100644 --- a/libmisc/include/libmisc/macro.h +++ b/libmisc/include/libmisc/macro.h @@ -1,6 +1,6 @@ /* libmisc/macro.h - Useful C preprocessor macros * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -36,6 +36,7 @@ /* macro arguments */ +#define LM_FIRST(a, ...) a #define LM_SECOND(a, b, ...) b #define LM_EAT(...) #define LM_EXPAND(...) __VA_ARGS__ @@ -52,4 +53,42 @@ #define _LM_IF__xxTxx(...) __VA_ARGS__ LM_EAT #define _LM_IF__xxFxx(...) LM_EXPAND +/* tuples */ + +#define LM_IS_TUPLE(x) LM_IS_SENTINEL(_LM_IS_TUPLE x) +#define _LM_IS_TUPLE(...) LM_SENTINEL() + +/* `tuples` is a sequence of `(tuple1)(tuple2)(tuple3)` */ +#define _LM_TUPLES_COMMA(tuple...) (tuple), +#define LM_TUPLES_NONEMPTY(tuples) LM_IS_TUPLE(_LM_TUPLES_COMMA tuples) +#define LM_TUPLES_HEAD(tuples) LM_EXPAND(LM_FIRST LM_EAT() (_LM_TUPLES_COMMA tuples)) +#define LM_TUPLES_TAIL(tuples) LM_EAT tuples + +/* iteration */ + +/* BUG: LM_FOREACH_TUPLE maxes out at 1024 tuples. */ +#define LM_FOREACH_TUPLE(tuples, func, ...) \ + _LM_EVAL(_LM_FOREACH_TUPLE(tuples, func, __VA_ARGS__)) +#define _LM_FOREACH_TUPLE(tuples, func, ...) \ + LM_IF(LM_TUPLES_NONEMPTY(tuples))( \ + _LM_DEFER2(func)(__VA_ARGS__ __VA_OPT__(,) LM_EXPAND LM_TUPLES_HEAD(tuples)) \ + _LM_DEFER2(_LM_FOREACH_TUPLE_indirect)()(LM_TUPLES_TAIL(tuples), func, __VA_ARGS__) \ + )() +#define _LM_FOREACH_TUPLE_indirect() _LM_FOREACH_TUPLE + +#define _LM_DEFER2(macro) macro LM_EAT LM_EAT()() + +#define _LM_EVAL(...) _LM_EVAL__1024(__VA_ARGS__) /* 1024 iterations aught to be enough for anybody */ +#define _LM_EVAL__1024(...) _LM_EVAL__512(_LM_EVAL__512(__VA_ARGS__)) +#define _LM_EVAL__512(...) _LM_EVAL__256(_LM_EVAL__256(__VA_ARGS__)) +#define _LM_EVAL__256(...) _LM_EVAL__128(_LM_EVAL__128(__VA_ARGS__)) +#define _LM_EVAL__128(...) _LM_EVAL__64(_LM_EVAL__64(__VA_ARGS__)) +#define _LM_EVAL__64(...) _LM_EVAL__32(_LM_EVAL__32(__VA_ARGS__)) +#define _LM_EVAL__32(...) _LM_EVAL__16(_LM_EVAL__16(__VA_ARGS__)) +#define _LM_EVAL__16(...) _LM_EVAL__8(_LM_EVAL__8(__VA_ARGS__)) +#define _LM_EVAL__8(...) _LM_EVAL__4(_LM_EVAL__4(__VA_ARGS__)) +#define _LM_EVAL__4(...) _LM_EVAL__2(_LM_EVAL__2(__VA_ARGS__)) +#define _LM_EVAL__2(...) _LM_EVAL__1(_LM_EVAL__1(__VA_ARGS__)) +#define _LM_EVAL__1(...) __VA_ARGS__ + #endif /* _LIBMISC_MACRO_H_ */ diff --git a/libmisc/include/libmisc/vcall.h b/libmisc/include/libmisc/vcall.h deleted file mode 100644 index 31a8c7e..0000000 --- a/libmisc/include/libmisc/vcall.h +++ /dev/null @@ -1,28 +0,0 @@ -/* libmisc/vcall.h - A simple Go-ish object system built on GCC -fplan9-extensions - * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _LIBMISC_VCALL_H_ -#define _LIBMISC_VCALL_H_ - -#include <stddef.h> /* for offsetof() */ - -#include <libmisc/assert.h> - -#define VCALL(o, m, ...) \ - ({ \ - assert(o); \ - (o)->vtable->m(o __VA_OPT__(,) __VA_ARGS__); \ - }) - -#define VCALL_SELF(obj_typ, iface_typ, iface_ptr) \ - ({ \ - static_assert(_Generic(iface_ptr, iface_typ *: 1, default: 0), \ - "typeof("#iface_ptr") != "#iface_typ" *"); \ - assert(iface_ptr); \ - ((obj_typ*)(((void*)iface_ptr)-offsetof(obj_typ,iface_typ))); \ - }) - -#endif /* _LIBMISC_VCALL_H_ */ |