Char16.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /* Implements a UTF-16 character type. */
  6. #ifndef mozilla_Char16_h
  7. #define mozilla_Char16_h
  8. #ifdef __cplusplus
  9. /*
  10. * C++11 introduces a char16_t type and support for UTF-16 string and character
  11. * literals. C++11's char16_t is a distinct builtin type. Technically, char16_t
  12. * is a 16-bit code unit of a Unicode code point, not a "character".
  13. */
  14. #ifdef WIN32
  15. # define MOZ_USE_CHAR16_WRAPPER
  16. # include <cstdint>
  17. /**
  18. * Win32 API extensively uses wchar_t, which is represented by a separated
  19. * builtin type than char16_t per spec. It's not the case for MSVC prior to
  20. * MSVC 2015, but other compilers follow the spec. We want to mix wchar_t and
  21. * char16_t on Windows builds. This class is supposed to make it easier. It
  22. * stores char16_t const pointer, but provides implicit casts for wchar_t as
  23. * well. On other platforms, we simply use
  24. * |typedef const char16_t* char16ptr_t|. Here, we want to make the class as
  25. * similar to this typedef, including providing some casts that are allowed
  26. * by the typedef.
  27. */
  28. class char16ptr_t
  29. {
  30. private:
  31. const char16_t* mPtr;
  32. static_assert(sizeof(char16_t) == sizeof(wchar_t),
  33. "char16_t and wchar_t sizes differ");
  34. public:
  35. char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {}
  36. char16ptr_t(const wchar_t* aPtr) :
  37. mPtr(reinterpret_cast<const char16_t*>(aPtr))
  38. {}
  39. /* Without this, nullptr assignment would be ambiguous. */
  40. constexpr char16ptr_t(decltype(nullptr)) : mPtr(nullptr) {}
  41. operator const char16_t*() const
  42. {
  43. return mPtr;
  44. }
  45. operator const wchar_t*() const
  46. {
  47. return reinterpret_cast<const wchar_t*>(mPtr);
  48. }
  49. operator const void*() const
  50. {
  51. return mPtr;
  52. }
  53. operator bool() const
  54. {
  55. return mPtr != nullptr;
  56. }
  57. /* Explicit cast operators to allow things like (char16_t*)str. */
  58. explicit operator char16_t*() const
  59. {
  60. return const_cast<char16_t*>(mPtr);
  61. }
  62. explicit operator wchar_t*() const
  63. {
  64. return const_cast<wchar_t*>(static_cast<const wchar_t*>(*this));
  65. }
  66. explicit operator int() const
  67. {
  68. return reinterpret_cast<intptr_t>(mPtr);
  69. }
  70. explicit operator unsigned int() const
  71. {
  72. return reinterpret_cast<uintptr_t>(mPtr);
  73. }
  74. explicit operator long() const
  75. {
  76. return reinterpret_cast<intptr_t>(mPtr);
  77. }
  78. explicit operator unsigned long() const
  79. {
  80. return reinterpret_cast<uintptr_t>(mPtr);
  81. }
  82. explicit operator long long() const
  83. {
  84. return reinterpret_cast<intptr_t>(mPtr);
  85. }
  86. explicit operator unsigned long long() const
  87. {
  88. return reinterpret_cast<uintptr_t>(mPtr);
  89. }
  90. /**
  91. * Some Windows API calls accept BYTE* but require that data actually be
  92. * WCHAR*. Supporting this requires explicit operators to support the
  93. * requisite explicit casts.
  94. */
  95. explicit operator const char*() const
  96. {
  97. return reinterpret_cast<const char*>(mPtr);
  98. }
  99. explicit operator const unsigned char*() const
  100. {
  101. return reinterpret_cast<const unsigned char*>(mPtr);
  102. }
  103. explicit operator unsigned char*() const
  104. {
  105. return
  106. const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(mPtr));
  107. }
  108. explicit operator void*() const
  109. {
  110. return const_cast<char16_t*>(mPtr);
  111. }
  112. /* Some operators used on pointers. */
  113. char16_t operator[](size_t aIndex) const
  114. {
  115. return mPtr[aIndex];
  116. }
  117. bool operator==(const char16ptr_t& aOther) const
  118. {
  119. return mPtr == aOther.mPtr;
  120. }
  121. bool operator==(decltype(nullptr)) const
  122. {
  123. return mPtr == nullptr;
  124. }
  125. bool operator!=(const char16ptr_t& aOther) const
  126. {
  127. return mPtr != aOther.mPtr;
  128. }
  129. bool operator!=(decltype(nullptr)) const
  130. {
  131. return mPtr != nullptr;
  132. }
  133. char16ptr_t operator+(int aValue) const
  134. {
  135. return char16ptr_t(mPtr + aValue);
  136. }
  137. char16ptr_t operator+(unsigned int aValue) const
  138. {
  139. return char16ptr_t(mPtr + aValue);
  140. }
  141. char16ptr_t operator+(long aValue) const
  142. {
  143. return char16ptr_t(mPtr + aValue);
  144. }
  145. char16ptr_t operator+(unsigned long aValue) const
  146. {
  147. return char16ptr_t(mPtr + aValue);
  148. }
  149. char16ptr_t operator+(long long aValue) const
  150. {
  151. return char16ptr_t(mPtr + aValue);
  152. }
  153. char16ptr_t operator+(unsigned long long aValue) const
  154. {
  155. return char16ptr_t(mPtr + aValue);
  156. }
  157. ptrdiff_t operator-(const char16ptr_t& aOther) const
  158. {
  159. return mPtr - aOther.mPtr;
  160. }
  161. };
  162. inline decltype((char*)0-(char*)0)
  163. operator-(const char16_t* aX, const char16ptr_t aY)
  164. {
  165. return aX - static_cast<const char16_t*>(aY);
  166. }
  167. #else
  168. typedef const char16_t* char16ptr_t;
  169. #endif
  170. static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?");
  171. static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?");
  172. static_assert(sizeof(u'A') == 2, "Is unicode char literal 16 bits?");
  173. static_assert(sizeof(u""[0]) == 2, "Is unicode string char 16 bits?");
  174. #endif
  175. #endif /* mozilla_Char16_h */