полная эмуляция пропущенных различных встроенных типов (в частности: char16_t и char32_t) - PullRequest
5 голосов
/ 05 января 2012

C ++ 11 имеет два новых символьных типа данных: char16_t и char32_t.Я хотел бы эмулировать их для компиляторов, у которых нет определенного типа, чтобы перегружать операции ввода-вывода, чтобы видеть их символы вместо их целочисленного значения.

Это требования:

  • Отличительный (нет typedef).
  • точная ширина в обычных системах (ala uint16_t и uint32_t)
  • разрешены другие функции C ++ 11 (см. Первую попытку ниже))
  • Должен хорошо играть с литералами;char16_t c16 = u"blabla unicode text blabla"; должно работать.
  • , если char16_t может использоваться в математических операторах, очевидно, это должно также работать.

Моя первая попытка, которая не удалась в буквальном отделе, была решительнонабрал enum:

enum char16_t : uint16_t;

У этого есть и другие недостатки, которые, возможно, могут быть устранены путем предоставления необходимых операторов самостоятельно (что мне действительно хорошо).

1 Ответ

1 голос
/ 06 января 2012

Не думаю, что инициализация сработает, потому что не так много возможностей, чтобы заставить ее работать. Проблема в том, что инициализация, которую вы используете в своем примере, не должна работать: строковый литерал u"..." дает массив из char16_t const объектов, и вы хотите инициализировать указатель с ним:

char16_t const* c16 = u"...";

Кроме того, без реализации char16_t в компиляторе очень маловероятно, чтобы поддерживать char16_t строковые литералы. Лучшее, чего вы можете достичь, это сыграть макро-трюки, которые предназначены для того, чтобы делать все правильно. Сейчас вы бы использовали, например, широкие символьные литералы и когда вы получаете компилятор, который поддерживает char16_t, вы просто меняете макрос, чтобы использовать char16_t литералы. Даже для того, чтобы это работало, вам может понадобиться использовать тип записи, который больше 16 бит, потому что wchar_t использует 32 бита на некоторых платформах.

#define CONCAT(a,b) a##b

#if defined(HAS_C16)
#  define C16S(s) CONCAT(u,s)
#else
#  define C16S(s) reinterpret_cast<char16_t const*>(CONCAT(L,s));
struct char16_t
{
    unsigned short value;
};
#endif


int main()
{
    char16_t const* c16 = C16S("...");
}

Очевидно, что вам все еще нужно предоставить все виды операторов, например, заставить целочисленную арифметику и подходящие преобразования работать.

...