writer.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // UTF-16 code points writer
  2. //
  3. // Platform: ISO C++ 98/11
  4. // $Id$
  5. //
  6. // (c) __vic 2017
  7. #ifndef __VIC_UTF16_WRITER_H
  8. #define __VIC_UTF16_WRITER_H
  9. #include<__vic/defs.h>
  10. #include<__vic/unicode.h>
  11. #include<__vic/utf16/defs.h>
  12. namespace __vic { namespace utf16 {
  13. //////////////////////////////////////////////////////////////////////////////
  14. template<class CodeUnitWriter>
  15. class writer
  16. {
  17. CodeUnitWriter w;
  18. void write_unit(code_unit_t u) { w.write(u); }
  19. public:
  20. typedef CodeUnitWriter code_unit_writer_type;
  21. CodeUnitWriter &get_code_unit_writer() { return w; }
  22. const CodeUnitWriter &get_code_unit_writer() const { return w; }
  23. #if __cpp_variadic_templates && __cpp_rvalue_references
  24. template<class... Args>
  25. explicit writer(Args&&... args) : w(std::forward<Args>(args)...) {}
  26. #else
  27. writer() {}
  28. explicit writer(CodeUnitWriter w) : w(w) {}
  29. #endif
  30. void write(unicode_t );
  31. };
  32. //////////////////////////////////////////////////////////////////////////////
  33. //----------------------------------------------------------------------------
  34. template<class CodeUnitWriter>
  35. void writer<CodeUnitWriter>::write(unicode_t cp)
  36. {
  37. if(cp <= 0xFFFF)
  38. write_unit(cp);
  39. else
  40. {
  41. cp -= 0x10000; // 20 bits
  42. write_unit(hi_surrogate_min | (cp >> 10)); // hi 10 bits: 110110xx xxxxxxxx
  43. write_unit(lo_surrogate_min | (cp & 0x3FF)); // lo 10 bits: 110111xx xxxxxxxx
  44. }
  45. }
  46. //----------------------------------------------------------------------------
  47. template<class CodeUnitWriter>
  48. inline writer<CodeUnitWriter> make_writer(CodeUnitWriter w)
  49. {
  50. return writer<CodeUnitWriter>(w);
  51. }
  52. //----------------------------------------------------------------------------
  53. }} // namespace
  54. #endif // header guard