char16ptr.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // © 2017 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. // char16ptr.h
  4. // created: 2017feb28 Markus W. Scherer
  5. #ifndef __CHAR16PTR_H__
  6. #define __CHAR16PTR_H__
  7. #include "unicode/utypes.h"
  8. #if U_SHOW_CPLUSPLUS_API
  9. #include <cstddef>
  10. /**
  11. * \file
  12. * \brief C++ API: char16_t pointer wrappers with
  13. * implicit conversion from bit-compatible raw pointer types.
  14. * Also conversion functions from char16_t * to UChar * and OldUChar *.
  15. */
  16. U_NAMESPACE_BEGIN
  17. /**
  18. * \def U_ALIASING_BARRIER
  19. * Barrier for pointer anti-aliasing optimizations even across function boundaries.
  20. * @internal
  21. */
  22. #ifdef U_ALIASING_BARRIER
  23. // Use the predefined value.
  24. #elif (defined(__clang__) || defined(__GNUC__)) && U_PLATFORM != U_PF_BROWSER_NATIVE_CLIENT
  25. # define U_ALIASING_BARRIER(ptr) asm volatile("" : : "rm"(ptr) : "memory")
  26. #elif defined(U_IN_DOXYGEN)
  27. # define U_ALIASING_BARRIER(ptr)
  28. #endif
  29. /**
  30. * char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
  31. * @stable ICU 59
  32. */
  33. class U_COMMON_API Char16Ptr final {
  34. public:
  35. /**
  36. * Copies the pointer.
  37. * @param p pointer
  38. * @stable ICU 59
  39. */
  40. inline Char16Ptr(char16_t *p);
  41. #if !U_CHAR16_IS_TYPEDEF
  42. /**
  43. * Converts the pointer to char16_t *.
  44. * @param p pointer to be converted
  45. * @stable ICU 59
  46. */
  47. inline Char16Ptr(uint16_t *p);
  48. #endif
  49. #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
  50. /**
  51. * Converts the pointer to char16_t *.
  52. * (Only defined if U_SIZEOF_WCHAR_T==2.)
  53. * @param p pointer to be converted
  54. * @stable ICU 59
  55. */
  56. inline Char16Ptr(wchar_t *p);
  57. #endif
  58. /**
  59. * nullptr constructor.
  60. * @param p nullptr
  61. * @stable ICU 59
  62. */
  63. inline Char16Ptr(std::nullptr_t p);
  64. /**
  65. * Destructor.
  66. * @stable ICU 59
  67. */
  68. inline ~Char16Ptr();
  69. /**
  70. * Pointer access.
  71. * @return the wrapped pointer
  72. * @stable ICU 59
  73. */
  74. inline char16_t *get() const;
  75. /**
  76. * char16_t pointer access via type conversion (e.g., static_cast).
  77. * @return the wrapped pointer
  78. * @stable ICU 59
  79. */
  80. inline operator char16_t *() const { return get(); }
  81. private:
  82. Char16Ptr() = delete;
  83. #ifdef U_ALIASING_BARRIER
  84. template<typename T> static char16_t *cast(T *t) {
  85. U_ALIASING_BARRIER(t);
  86. return reinterpret_cast<char16_t *>(t);
  87. }
  88. char16_t *p_;
  89. #else
  90. union {
  91. char16_t *cp;
  92. uint16_t *up;
  93. wchar_t *wp;
  94. } u_;
  95. #endif
  96. };
  97. /// \cond
  98. #ifdef U_ALIASING_BARRIER
  99. Char16Ptr::Char16Ptr(char16_t *p) : p_(p) {}
  100. #if !U_CHAR16_IS_TYPEDEF
  101. Char16Ptr::Char16Ptr(uint16_t *p) : p_(cast(p)) {}
  102. #endif
  103. #if U_SIZEOF_WCHAR_T==2
  104. Char16Ptr::Char16Ptr(wchar_t *p) : p_(cast(p)) {}
  105. #endif
  106. Char16Ptr::Char16Ptr(std::nullptr_t p) : p_(p) {}
  107. Char16Ptr::~Char16Ptr() {
  108. U_ALIASING_BARRIER(p_);
  109. }
  110. char16_t *Char16Ptr::get() const { return p_; }
  111. #else
  112. Char16Ptr::Char16Ptr(char16_t *p) { u_.cp = p; }
  113. #if !U_CHAR16_IS_TYPEDEF
  114. Char16Ptr::Char16Ptr(uint16_t *p) { u_.up = p; }
  115. #endif
  116. #if U_SIZEOF_WCHAR_T==2
  117. Char16Ptr::Char16Ptr(wchar_t *p) { u_.wp = p; }
  118. #endif
  119. Char16Ptr::Char16Ptr(std::nullptr_t p) { u_.cp = p; }
  120. Char16Ptr::~Char16Ptr() {}
  121. char16_t *Char16Ptr::get() const { return u_.cp; }
  122. #endif
  123. /// \endcond
  124. /**
  125. * const char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
  126. * @stable ICU 59
  127. */
  128. class U_COMMON_API ConstChar16Ptr final {
  129. public:
  130. /**
  131. * Copies the pointer.
  132. * @param p pointer
  133. * @stable ICU 59
  134. */
  135. inline ConstChar16Ptr(const char16_t *p);
  136. #if !U_CHAR16_IS_TYPEDEF
  137. /**
  138. * Converts the pointer to char16_t *.
  139. * @param p pointer to be converted
  140. * @stable ICU 59
  141. */
  142. inline ConstChar16Ptr(const uint16_t *p);
  143. #endif
  144. #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
  145. /**
  146. * Converts the pointer to char16_t *.
  147. * (Only defined if U_SIZEOF_WCHAR_T==2.)
  148. * @param p pointer to be converted
  149. * @stable ICU 59
  150. */
  151. inline ConstChar16Ptr(const wchar_t *p);
  152. #endif
  153. /**
  154. * nullptr constructor.
  155. * @param p nullptr
  156. * @stable ICU 59
  157. */
  158. inline ConstChar16Ptr(const std::nullptr_t p);
  159. /**
  160. * Destructor.
  161. * @stable ICU 59
  162. */
  163. inline ~ConstChar16Ptr();
  164. /**
  165. * Pointer access.
  166. * @return the wrapped pointer
  167. * @stable ICU 59
  168. */
  169. inline const char16_t *get() const;
  170. /**
  171. * char16_t pointer access via type conversion (e.g., static_cast).
  172. * @return the wrapped pointer
  173. * @stable ICU 59
  174. */
  175. inline operator const char16_t *() const { return get(); }
  176. private:
  177. ConstChar16Ptr() = delete;
  178. #ifdef U_ALIASING_BARRIER
  179. template<typename T> static const char16_t *cast(const T *t) {
  180. U_ALIASING_BARRIER(t);
  181. return reinterpret_cast<const char16_t *>(t);
  182. }
  183. const char16_t *p_;
  184. #else
  185. union {
  186. const char16_t *cp;
  187. const uint16_t *up;
  188. const wchar_t *wp;
  189. } u_;
  190. #endif
  191. };
  192. /// \cond
  193. #ifdef U_ALIASING_BARRIER
  194. ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) : p_(p) {}
  195. #if !U_CHAR16_IS_TYPEDEF
  196. ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) : p_(cast(p)) {}
  197. #endif
  198. #if U_SIZEOF_WCHAR_T==2
  199. ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p_(cast(p)) {}
  200. #endif
  201. ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p_(p) {}
  202. ConstChar16Ptr::~ConstChar16Ptr() {
  203. U_ALIASING_BARRIER(p_);
  204. }
  205. const char16_t *ConstChar16Ptr::get() const { return p_; }
  206. #else
  207. ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) { u_.cp = p; }
  208. #if !U_CHAR16_IS_TYPEDEF
  209. ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) { u_.up = p; }
  210. #endif
  211. #if U_SIZEOF_WCHAR_T==2
  212. ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u_.wp = p; }
  213. #endif
  214. ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u_.cp = p; }
  215. ConstChar16Ptr::~ConstChar16Ptr() {}
  216. const char16_t *ConstChar16Ptr::get() const { return u_.cp; }
  217. #endif
  218. /// \endcond
  219. /**
  220. * Converts from const char16_t * to const UChar *.
  221. * Includes an aliasing barrier if available.
  222. * @param p pointer
  223. * @return p as const UChar *
  224. * @stable ICU 59
  225. */
  226. inline const UChar *toUCharPtr(const char16_t *p) {
  227. #ifdef U_ALIASING_BARRIER
  228. U_ALIASING_BARRIER(p);
  229. #endif
  230. return reinterpret_cast<const UChar *>(p);
  231. }
  232. /**
  233. * Converts from char16_t * to UChar *.
  234. * Includes an aliasing barrier if available.
  235. * @param p pointer
  236. * @return p as UChar *
  237. * @stable ICU 59
  238. */
  239. inline UChar *toUCharPtr(char16_t *p) {
  240. #ifdef U_ALIASING_BARRIER
  241. U_ALIASING_BARRIER(p);
  242. #endif
  243. return reinterpret_cast<UChar *>(p);
  244. }
  245. /**
  246. * Converts from const char16_t * to const OldUChar *.
  247. * Includes an aliasing barrier if available.
  248. * @param p pointer
  249. * @return p as const OldUChar *
  250. * @stable ICU 59
  251. */
  252. inline const OldUChar *toOldUCharPtr(const char16_t *p) {
  253. #ifdef U_ALIASING_BARRIER
  254. U_ALIASING_BARRIER(p);
  255. #endif
  256. return reinterpret_cast<const OldUChar *>(p);
  257. }
  258. /**
  259. * Converts from char16_t * to OldUChar *.
  260. * Includes an aliasing barrier if available.
  261. * @param p pointer
  262. * @return p as OldUChar *
  263. * @stable ICU 59
  264. */
  265. inline OldUChar *toOldUCharPtr(char16_t *p) {
  266. #ifdef U_ALIASING_BARRIER
  267. U_ALIASING_BARRIER(p);
  268. #endif
  269. return reinterpret_cast<OldUChar *>(p);
  270. }
  271. U_NAMESPACE_END
  272. #endif /* U_SHOW_CPLUSPLUS_API */
  273. #endif // __CHAR16PTR_H__