РЕДАКТИРОВАТЬ: Этот ответ может быть полезным, поэтому я не удаляю его, но конкретно не отвечаю на вопрос.Он конвертирует строки в числа, но не может быть помещен в перечисление, потому что не вычисляет число во время компиляции.
Что ж, поскольку ваши целые числа 64-битные, у вас есть только первые 8 символовлюбая строка для беспокойства.Таким образом, вы можете написать вещь 8 раз, убедившись, что вы не выходите за пределы строки:
#define GET_NTH_BYTE(x, n) (sizeof(x) <= n?0:((uint64_t)x[n] << (n*8)))
#define INSN_TO_ENUM(x) GET_NTH_BYTE(x, 0)\
|GET_NTH_BYTE(x, 1)\
|GET_NTH_BYTE(x, 2)\
|GET_NTH_BYTE(x, 3)\
|GET_NTH_BYTE(x, 4)\
|GET_NTH_BYTE(x, 5)\
|GET_NTH_BYTE(x, 6)\
|GET_NTH_BYTE(x, 7)
Что в основном делает для проверки на каждом байте, находится ли он в пределеstring и, если это так, то выдает соответствующий байт.
Обратите внимание: , что это работает только для литеральных строк.
Если вы хотите иметь возможность преобразовывать любыеstring, вы можете указать длину строки:
#define GET_NTH_BYTE(x, n, l) (l < n?0:((uint64_t)x[n] << (n*8)))
#define INSN_TO_ENUM(x, l) GET_NTH_BYTE(x, 0, l)\
|GET_NTH_BYTE(x, 1, l)\
|GET_NTH_BYTE(x, 2, l)\
|GET_NTH_BYTE(x, 3, l)\
|GET_NTH_BYTE(x, 4, l)\
|GET_NTH_BYTE(x, 5, l)\
|GET_NTH_BYTE(x, 6, l)\
|GET_NTH_BYTE(x, 7, l)
Так, например:
int length = strlen(your_string);
int num = INSN_TO_ENUM(your_string, length);
Наконец, есть способ избежать указания длины, но это требуеткомпилятор фактически вычисляет фразы INSN_TO_ENUM
слева направо. Я не уверен, стандартно ли это:
static int _nul_seen;
#define GET_NTH_BYTE(x, n) ((_nul_seen || x[n] == '\0')?(_nul_seen=1)&0:((uint64_t)x[n] << (n*8)))
#define INSN_TO_ENUM(x) (_nul_seen=0)|
(GET_NTH_BYTE(x, 0)\
|GET_NTH_BYTE(x, 1)\
|GET_NTH_BYTE(x, 2)\
|GET_NTH_BYTE(x, 3)\
|GET_NTH_BYTE(x, 4)\
|GET_NTH_BYTE(x, 5)\
|GET_NTH_BYTE(x, 6)\
|GET_NTH_BYTE(x, 7))