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