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