1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
5 // created: 2017feb28 Markus W. Scherer
7 #ifndef __CHAR16PTR_H__
8 #define __CHAR16PTR_H__
11 #include "unicode/utypes.h"
15 * \brief C++ API: char16_t pointer wrappers with
16 * implicit conversion from bit-compatible raw pointer types.
17 * Also conversion functions from char16_t * to UChar * and OldUChar *.
20 #if U_SHOW_CPLUSPLUS_API
24 * \def U_ALIASING_BARRIER
25 * Barrier for pointer anti-aliasing optimizations even across function boundaries.
28 #ifdef U_ALIASING_BARRIER
29 // Use the predefined value.
30 #elif (defined(__clang__) || defined(__GNUC__)) && U_PLATFORM != U_PF_BROWSER_NATIVE_CLIENT
31 # define U_ALIASING_BARRIER(ptr) asm volatile("" : : "rm"(ptr) : "memory")
35 * char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
38 class U_COMMON_API Char16Ptr U_FINAL
{
45 inline Char16Ptr(char16_t *p
);
46 #if !U_CHAR16_IS_TYPEDEF
48 * Converts the pointer to char16_t *.
49 * @param p pointer to be converted
52 inline Char16Ptr(uint16_t *p
);
54 #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
56 * Converts the pointer to char16_t *.
57 * (Only defined if U_SIZEOF_WCHAR_T==2.)
58 * @param p pointer to be converted
61 inline Char16Ptr(wchar_t *p
);
64 * nullptr constructor.
68 inline Char16Ptr(std::nullptr_t p
);
77 * @return the wrapped pointer
80 inline char16_t *get() const;
82 * char16_t pointer access via type conversion (e.g., static_cast).
83 * @return the wrapped pointer
86 inline operator char16_t *() const { return get(); }
91 #ifdef U_ALIASING_BARRIER
92 template<typename T
> static char16_t *cast(T
*t
) {
93 U_ALIASING_BARRIER(t
);
94 return reinterpret_cast<char16_t *>(t
);
107 #ifdef U_ALIASING_BARRIER
109 Char16Ptr::Char16Ptr(char16_t *p
) : p_(p
) {}
110 #if !U_CHAR16_IS_TYPEDEF
111 Char16Ptr::Char16Ptr(uint16_t *p
) : p_(cast(p
)) {}
113 #if U_SIZEOF_WCHAR_T==2
114 Char16Ptr::Char16Ptr(wchar_t *p
) : p_(cast(p
)) {}
116 Char16Ptr::Char16Ptr(std::nullptr_t p
) : p_(p
) {}
117 Char16Ptr::~Char16Ptr() {
118 U_ALIASING_BARRIER(p_
);
121 char16_t *Char16Ptr::get() const { return p_
; }
125 Char16Ptr::Char16Ptr(char16_t *p
) { u_
.cp
= p
; }
126 #if !U_CHAR16_IS_TYPEDEF
127 Char16Ptr::Char16Ptr(uint16_t *p
) { u_
.up
= p
; }
129 #if U_SIZEOF_WCHAR_T==2
130 Char16Ptr::Char16Ptr(wchar_t *p
) { u_
.wp
= p
; }
132 Char16Ptr::Char16Ptr(std::nullptr_t p
) { u_
.cp
= p
; }
133 Char16Ptr::~Char16Ptr() {}
135 char16_t *Char16Ptr::get() const { return u_
.cp
; }
140 * const char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
143 class U_COMMON_API ConstChar16Ptr U_FINAL
{
146 * Copies the pointer.
150 inline ConstChar16Ptr(const char16_t *p
);
151 #if !U_CHAR16_IS_TYPEDEF
153 * Converts the pointer to char16_t *.
154 * @param p pointer to be converted
157 inline ConstChar16Ptr(const uint16_t *p
);
159 #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
161 * Converts the pointer to char16_t *.
162 * (Only defined if U_SIZEOF_WCHAR_T==2.)
163 * @param p pointer to be converted
166 inline ConstChar16Ptr(const wchar_t *p
);
169 * nullptr constructor.
173 inline ConstChar16Ptr(const std::nullptr_t p
);
179 inline ~ConstChar16Ptr();
183 * @return the wrapped pointer
186 inline const char16_t *get() const;
188 * char16_t pointer access via type conversion (e.g., static_cast).
189 * @return the wrapped pointer
192 inline operator const char16_t *() const { return get(); }
195 ConstChar16Ptr() = delete;
197 #ifdef U_ALIASING_BARRIER
198 template<typename T
> static const char16_t *cast(const T
*t
) {
199 U_ALIASING_BARRIER(t
);
200 return reinterpret_cast<const char16_t *>(t
);
213 #ifdef U_ALIASING_BARRIER
215 ConstChar16Ptr::ConstChar16Ptr(const char16_t *p
) : p_(p
) {}
216 #if !U_CHAR16_IS_TYPEDEF
217 ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p
) : p_(cast(p
)) {}
219 #if U_SIZEOF_WCHAR_T==2
220 ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p
) : p_(cast(p
)) {}
222 ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p
) : p_(p
) {}
223 ConstChar16Ptr::~ConstChar16Ptr() {
224 U_ALIASING_BARRIER(p_
);
227 const char16_t *ConstChar16Ptr::get() const { return p_
; }
231 ConstChar16Ptr::ConstChar16Ptr(const char16_t *p
) { u_
.cp
= p
; }
232 #if !U_CHAR16_IS_TYPEDEF
233 ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p
) { u_
.up
= p
; }
235 #if U_SIZEOF_WCHAR_T==2
236 ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p
) { u_
.wp
= p
; }
238 ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p
) { u_
.cp
= p
; }
239 ConstChar16Ptr::~ConstChar16Ptr() {}
241 const char16_t *ConstChar16Ptr::get() const { return u_
.cp
; }
246 * Converts from const char16_t * to const UChar *.
247 * Includes an aliasing barrier if available.
249 * @return p as const UChar *
252 inline const UChar
*toUCharPtr(const char16_t *p
) {
253 #ifdef U_ALIASING_BARRIER
254 U_ALIASING_BARRIER(p
);
256 return reinterpret_cast<const UChar
*>(p
);
260 * Converts from char16_t * to UChar *.
261 * Includes an aliasing barrier if available.
263 * @return p as UChar *
266 inline UChar
*toUCharPtr(char16_t *p
) {
267 #ifdef U_ALIASING_BARRIER
268 U_ALIASING_BARRIER(p
);
270 return reinterpret_cast<UChar
*>(p
);
274 * Converts from const char16_t * to const OldUChar *.
275 * Includes an aliasing barrier if available.
277 * @return p as const OldUChar *
280 inline const OldUChar
*toOldUCharPtr(const char16_t *p
) {
281 #ifdef U_ALIASING_BARRIER
282 U_ALIASING_BARRIER(p
);
284 return reinterpret_cast<const OldUChar
*>(p
);
288 * Converts from char16_t * to OldUChar *.
289 * Includes an aliasing barrier if available.
291 * @return p as OldUChar *
294 inline OldUChar
*toOldUCharPtr(char16_t *p
) {
295 #ifdef U_ALIASING_BARRIER
296 U_ALIASING_BARRIER(p
);
298 return reinterpret_cast<OldUChar
*>(p
);
302 #endif // U_SHOW_CPLUSPLUS_API
304 #endif // __CHAR16PTR_H__