2012-02-17 4 views
2

Я прочитал это related question, но это не совсем мне помогает.xcode ENUM с использованием символьного символа UTF8

Цель Enum состоит в том, чтобы содержать необработанный код UTF-8 (а не кодовую точку Юникода) одиночных символов UTF-8 в пределах 4 байтов.

Следующий пример работает, потому что исходный файл xcode находится в формате UTF-8 (который является рекомендуемой кодировкой для xcode). Он компилируется и запускается с правильными ожидаемыми значениями. Но я также получаю сообщение «warning» слишком долго для этого типа ». Могу я его подавить? .. или плохая идея?

typedef enum { 
    TEST_VAL_1BYTE = ',', // 0x2C 
    TEST_VAL_2BYTE = '§', // 0xC2A7  (the warning) 
    TEST_VAL_3BYTE = '✓', // 0xE29C93 (the warning) 
    TEST_VAL_4BYTE = '', // 0xF09D8DA5 (the warning) 
} TEST_VALUES_UTF8; 

Safest способом и без предупреждения, но это более утомительно код:

typedef enum { 
    NUM_VAL_1BYTE = 0x2C,  // , 
    NUM_VAL_2BYTE = 0xC2A7,  // § 
    NUM_VAL_3BYTE = 0xE29C93, // ✓ 
    NUM_VAL_4BYTE = 0xF09D8DA5, // 
} TEST_VALUES_UTF8; 

Наконец обратите внимание, что регистрация с 1 или 4 ASCII символов действует и без предупреждений:

enum { 
    ENUM_TEST_1  = '1',  // 0x31  (no warning) 
    ENUM_TEST_12 = '12', // 0x3132  (w: multi-character character constant) 
    ENUM_TEST_123 = '123', // 0x313233 (w: multi-character character constant) 
    ENUM_TEST_1234 = '1234', // 0x31323334 (no warning) 
}; 

Может быть, макрос препроцессора, который является генератором исходного кода, который может вернуть код UTF-8:

enum { 
    TEST_VAL_2BYTE = AWESOME_UTF8CODE_MACRO('§'), // 0xC2A7 
}; 

Thanks;

+0

Попытка содержать определенную последовательность нескольких байтов внутри перечисления - плохая идея. По крайней мере, у вас будут проблемы со здоровьем. –

+0

Endianness уже учтен, так что это не проблема. –

ответ

1

Используйте C++ 11 constexpr и u8 префикс, a'la http://liveworkspace.org/code/3EtxVE:

#include <iostream> 
#include <cstdint> 

constexpr uint32_t utf8(const char (&c)[2]) { 
    return uint8_t(c[0]); 
} 
constexpr uint32_t utf8(const char (&c)[3]) { 
    return uint8_t(c[1]) | (uint8_t(c[0])<<8); 
} 
constexpr uint32_t utf8(const char (&c)[4]) { 
    return uint8_t(c[2]) | (uint8_t(c[1])<<8) | (uint8_t(c[0])<<16); 
} 
constexpr uint32_t utf8(const char (&c)[5]) { 
    return uint8_t(c[3]) | (uint8_t(c[2])<<8) | (uint8_t(c[1])<<16) | (uint8_t(c[0])<<24); 
} 

typedef enum { 
    TEST_VAL_1BYTE = utf8(u8","), 
    TEST_VAL_2BYTE = utf8(u8"§"), 
    TEST_VAL_3BYTE = utf8(u8"✓"), 
    TEST_VAL_4BYTE = utf8(u8""), 
} TEST_VALUES_UTF8; 

int main() { 
    std::cout << std::hex << TEST_VAL_1BYTE << std::endl; 
    std::cout << std::hex << TEST_VAL_2BYTE << std::endl; 
    std::cout << std::hex << TEST_VAL_3BYTE << std::endl; 
    std::cout << std::hex << TEST_VAL_4BYTE << std::endl; 
} 

, который выводит

2c 
c2a7 
e29c93 
f09d8da5

Если у вас нет доступа к префиксу u8 вы можете просто обеспечить исходный файл закодирован в UTF-8, и я думаю, вы можете превратить constexpr в макросы, если это необходимо ... но показано, что это чистый путь.