2012-01-05 10 views
5

C++ 11 tiene dos nuevos tipos de datos integrales de caracteres, char16_t y char32_t. Me gustaría emularlos para los compiladores que no tienen un tipo diferenciado para sobrecargar las operaciones de E/S y verlos como caracteres en lugar de su valor entero.emulando por completo los distintos tipos integrados (específicamente: char16_t y char32_t)

Estos son los requisitos:

  • Distinct (sin typedef).
  • exacta de ancho en los sistemas normales (uint16_t ala y uint32_t)
  • otros C++ 11 características se permite (ver más abajo primer intento)
  • debe jugar agradable con literales; char16_t c16 = u"blabla unicode text blabla"; debe funcionar.
  • si char16_t se puede usar en operadores matemáticos, obviamente esto también necesita funcionar.

Mi primer intento, que falla en el departamento literal era una enumeración inflexible:

enum char16_t : uint16_t; 

Esto tiene otras desventajas también, que tal vez podría ser resuelto mediante el suministro de los operadores necesarios mí mismo (que es realmente bien por mi).

+0

No está muy claro por qué está intentando hacer esto o qué herramientas le gustaría usar. El "primer intento" usa C++ 11. No hay forma de obtener literales Unicode de un compilador sin soporte garantizado de Unicode, y no hay forma de manipular cadenas en tiempo de compilación sin un compilador reciente de C++ 11, punto. – Potatoswatter

Respuesta

1

No creo que consiga que la inicialización funcione porque no hay mucho margen para que funcione. El problema es que la inicialización está utilizando en su ejemplo no se supone que el trabajo: la cadena literal u"..." produce un char16_t const una serie de objetos y desea inicializar un puntero con ella:

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

También, sin implementación de char16_t en el compilador es poco probable que admita literales de cadena char16_t. Lo mejor que puedes lograr es jugar macro trucos con la intención de hacer lo correcto. Por ahora, usarías, por ejemplo, literales de caracteres anchos y cuando obtiene un compilador que admite char16_t, simplemente cambie la macro para usar literales char16_t. Incluso para que esto funcione, es posible que deba utilizar un tipo de registro que sea más grande que 16 bits porque wchar_t usa 32 bits en algunas plataformas.

#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("..."); 
} 

Obviamente, usted todavía tiene que proporcionar todo tipo de operadores, por ejemplo, para hacer funcionar la aritmética de enteros y las conversiones adecuadas.

Cuestiones relacionadas