utf16.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #ifndef __VIC_USE_MODULES
  2. #include<__vic/utf16/reader.h>
  3. #include<__vic/utf16/writer.h>
  4. #include<__vic/sreaders/string.h>
  5. #include<__vic/swriters/string.h>
  6. #include<__vic/iterator.h>
  7. #include<string>
  8. #include<iostream>
  9. #include<exception>
  10. #include<cstddef>
  11. #include<cstring>
  12. #endif
  13. #include<cassert>
  14. #ifdef __VIC_USE_MODULES
  15. import std;
  16. import __vic;
  17. #define __VIC_SREAD_RESULT(T) auto
  18. #endif
  19. namespace tests {
  20. using __vic::unicode_t;
  21. using std::size_t;
  22. #if __cpp_unicode_characters
  23. using std::u16string;
  24. #else
  25. // std::char_traits<uint_least16_t> may not be supported
  26. struct utf16_char_traits
  27. {
  28. typedef __vic::utf16::code_unit_t char_type;
  29. typedef __vic::utf16::code_unit_t int_type;
  30. typedef std::streamoff off_type;
  31. typedef std::wstreampos pos_type;
  32. typedef std::mbstate_t state_type;
  33. static void assign(char_type &c1, const char_type &c2) { c1 = c2; }
  34. static bool eq(char_type c1, char_type c2) { return c1 == c2; }
  35. static bool lt(char_type c1, char_type c2) { return c1 < c2; }
  36. static int compare(const char_type *s1, const char_type *s2, std::size_t n)
  37. {
  38. return std::memcmp(s1, s2, n * sizeof(char_type));
  39. }
  40. static std::size_t length(const char_type *s)
  41. {
  42. std::size_t n = 0;
  43. for(; *s; s++) n++;
  44. return n;
  45. }
  46. static const char_type *find(
  47. const char_type *s, std::size_t n, const char_type &a)
  48. {
  49. for(; n; n--, s++)
  50. if(*s == a) return s;
  51. return 0;
  52. }
  53. static char_type *move(char_type *s1, const char_type *s2, std::size_t n)
  54. {
  55. std::memmove(s1, s2, n * sizeof(char_type));
  56. return s1;
  57. }
  58. static char_type *copy(char_type *s1, const char_type *s2, std::size_t n)
  59. {
  60. std::memcpy(s1, s2, n * sizeof(char_type));
  61. return s1;
  62. }
  63. static char_type *assign(char_type *s, std::size_t n, char_type a)
  64. {
  65. for(char_type *p = s; n; n--) *p++ = a;
  66. return s;
  67. }
  68. static int_type not_eof(int_type c) { return c != eof() ? c : 0; }
  69. static char_type to_char_type(int_type c) { return c; }
  70. static int_type to_int_type(char_type c) { return c; }
  71. static bool eq_int_type(int_type c1, int_type c2) { return c1 == c2; }
  72. static int_type eof() { return static_cast<int_type>(-1); }
  73. };
  74. typedef std::basic_string<__vic::utf16::code_unit_t,
  75. utf16_char_traits> u16string;
  76. #endif
  77. //////////////////////////////////////////////////////////////////////////////
  78. class u16string_code_unit_reader
  79. {
  80. __vic::basic_string_sreader<__vic::utf16::code_unit_t> r;
  81. public:
  82. explicit u16string_code_unit_reader(const u16string &s) : r(s) {}
  83. __vic::utf16::read_unit_result operator()()
  84. {
  85. if(__vic::sread_result<__vic::utf16::code_unit_t> u = r())
  86. return u.value();
  87. return __vic::utf16::status::eof;
  88. }
  89. };
  90. //////////////////////////////////////////////////////////////////////////////
  91. #if __cpp_variadic_templates && __cpp_rvalue_references
  92. typedef __vic::utf16::reader<u16string_code_unit_reader> utf16_string_reader;
  93. typedef __vic::utf16::writer<
  94. __vic::push_back_swriter<u16string>
  95. > utf16_string_writer;
  96. #else
  97. struct utf16_string_reader : __vic::utf16::reader<u16string_code_unit_reader>
  98. {
  99. explicit utf16_string_reader(const u16string &s) :
  100. __vic::utf16::reader<u16string_code_unit_reader>(
  101. u16string_code_unit_reader(s)) {}
  102. };
  103. struct utf16_string_writer :
  104. __vic::utf16::writer<__vic::push_back_swriter<u16string> >
  105. {
  106. explicit utf16_string_writer(u16string &s) :
  107. __vic::utf16::writer<__vic::push_back_swriter<u16string> >(
  108. __vic::push_back_swriter<u16string>(s)) {}
  109. };
  110. #endif
  111. //----------------------------------------------------------------------------
  112. void read_write()
  113. {
  114. // Unicode code points for u8"Я ненавижу UTF-16"
  115. const unicode_t str[] = { 0x042F, 0x20,
  116. 0x043D, 0x0435, 0x043D, 0x0430, 0x0432, 0x0438, 0x0436, 0x0443, 0x20,
  117. 0x55, 0x54, 0x46, 0x2D, 0x31, 0x36
  118. };
  119. // The same string in UTF-16LE
  120. const __vic::utf16::code_unit_t check[] = { 0x042F, 0x20,
  121. 0x043D, 0x0435, 0x043D, 0x0430, 0x0432, 0x0438, 0x0436, 0x0443,
  122. 0x20, 0x55, 0x54, 0x46, 0x2D, 0x31, 0x36, 0 };
  123. u16string s;
  124. utf16_string_writer w(s);
  125. for(const unicode_t *p = str; p != __vic::end(str); p++)
  126. w.write(*p);
  127. assert(s == check);
  128. utf16_string_reader r(s);
  129. const unicode_t *p = str;
  130. size_t n = __vic::array_size(str);
  131. for(; __VIC_SREAD_RESULT(unicode_t) ch = r(); p++, n--)
  132. {
  133. assert(n != 0);
  134. assert(ch.value() == *p);
  135. }
  136. assert(n == 0); // all str elements are read
  137. }
  138. //----------------------------------------------------------------------------
  139. void run()
  140. {
  141. read_write();
  142. }
  143. //----------------------------------------------------------------------------
  144. } // namespace
  145. int main()
  146. {
  147. try
  148. {
  149. tests::run();
  150. return 0;
  151. }
  152. catch(const std::exception &ex)
  153. {
  154. std::cerr << ex.what() << '\n';
  155. }
  156. return 1;
  157. }