Вы всегда можете сделать это в C.: -)
Если вы используете компилятор, совместимый с C99, и, учитывая, что это 2019, я предполагаю, что вы можете использовать макросы с переменным числом, чтобы сделать эторабота, а более конкретно, P99 .
У меня был пример, когда я извлекал соответствующие компоненты P99, но он становился грязным, потому что это серьезное использование препроцессора Cкак полный по Тьюрингу язык.
Это также нарушает скобки;в частности, EXTRACT_VALUE x
расширяется до EXTRACT_VALUE (a, b)
, поскольку мы передаем список кортежей.
#include "p99.h"
#define EXTRACT_SHIFT(shift, value) (shift)
#define EXTRACT_VALUE(shift, value) (value)
#define MERGE(NAME, I, A, B) (A), (B)
#define SET_OR_CLEAR(target, x, i) \
((EXTRACT_VALUE x) ? \
((target) |= (1 << EXTRACT_SHIFT x)) : \
((target) &= ~(1 << EXTRACT_SHIFT x)))
#define SET_AND_CLEAR(target, pairs...) \
P99_FOR(target, P99_NARG(pairs), MERGE, SET_OR_CLEAR, pairs)
// ...
reg1 = BIT_SET(reg3, 3); //set bit 3
// ...
SET_AND_CLEAR(reg3, (7, 1), (6, 1), (5, 0)); // set bits 6 and 7, clear bit 5
Возможно, вам придется скомпилировать с -std=c99
.Обратите внимание, что я использовал переменное слово pairs
вместо __VA_ARGS__
, чтобы попытаться прояснить, что мы хотим использовать 2-кортежа в качестве аргументов.
Обратите внимание, что это не маскирует входной регистр, которыйне устанавливается или не очищается.