]> git.saurik.com Git - apple/icu.git/blob - icuSources/common/unicode/char16ptr.h
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / common / unicode / char16ptr.h
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")
32 #endif
33
34 /**
35 * char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
36 * @stable ICU 59
37 */
38 class U_COMMON_API Char16Ptr U_FINAL {
39 public:
40 /**
41 * Copies the pointer.
42 * @param p pointer
43 * @stable ICU 59
44 */
45 inline Char16Ptr(char16_t *p);
46 #if !U_CHAR16_IS_TYPEDEF
47 /**
48 * Converts the pointer to char16_t *.
49 * @param p pointer to be converted
50 * @stable ICU 59
51 */
52 inline Char16Ptr(uint16_t *p);
53 #endif
54 #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
55 /**
56 * Converts the pointer to char16_t *.
57 * (Only defined if U_SIZEOF_WCHAR_T==2.)
58 * @param p pointer to be converted
59 * @stable ICU 59
60 */
61 inline Char16Ptr(wchar_t *p);
62 #endif
63 /**
64 * nullptr constructor.
65 * @param p nullptr
66 * @stable ICU 59
67 */
68 inline Char16Ptr(std::nullptr_t p);
69 /**
70 * Destructor.
71 * @stable ICU 59
72 */
73 inline ~Char16Ptr();
74
75 /**
76 * Pointer access.
77 * @return the wrapped pointer
78 * @stable ICU 59
79 */
80 inline char16_t *get() const;
81 /**
82 * char16_t pointer access via type conversion (e.g., static_cast).
83 * @return the wrapped pointer
84 * @stable ICU 59
85 */
86 inline operator char16_t *() const { return get(); }
87
88 private:
89 Char16Ptr() = delete;
90
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);
95 }
96
97 char16_t *p_;
98 #else
99 union {
100 char16_t *cp;
101 uint16_t *up;
102 wchar_t *wp;
103 } u_;
104 #endif
105 };
106
107 #ifdef U_ALIASING_BARRIER
108
109 Char16Ptr::Char16Ptr(char16_t *p) : p_(p) {}
110 #if !U_CHAR16_IS_TYPEDEF
111 Char16Ptr::Char16Ptr(uint16_t *p) : p_(cast(p)) {}
112 #endif
113 #if U_SIZEOF_WCHAR_T==2
114 Char16Ptr::Char16Ptr(wchar_t *p) : p_(cast(p)) {}
115 #endif
116 Char16Ptr::Char16Ptr(std::nullptr_t p) : p_(p) {}
117 Char16Ptr::~Char16Ptr() {
118 U_ALIASING_BARRIER(p_);
119 }
120
121 char16_t *Char16Ptr::get() const { return p_; }
122
123 #else
124
125 Char16Ptr::Char16Ptr(char16_t *p) { u_.cp = p; }
126 #if !U_CHAR16_IS_TYPEDEF
127 Char16Ptr::Char16Ptr(uint16_t *p) { u_.up = p; }
128 #endif
129 #if U_SIZEOF_WCHAR_T==2
130 Char16Ptr::Char16Ptr(wchar_t *p) { u_.wp = p; }
131 #endif
132 Char16Ptr::Char16Ptr(std::nullptr_t p) { u_.cp = p; }
133 Char16Ptr::~Char16Ptr() {}
134
135 char16_t *Char16Ptr::get() const { return u_.cp; }
136
137 #endif
138
139 /**
140 * const char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types.
141 * @stable ICU 59
142 */
143 class U_COMMON_API ConstChar16Ptr U_FINAL {
144 public:
145 /**
146 * Copies the pointer.
147 * @param p pointer
148 * @stable ICU 59
149 */
150 inline ConstChar16Ptr(const char16_t *p);
151 #if !U_CHAR16_IS_TYPEDEF
152 /**
153 * Converts the pointer to char16_t *.
154 * @param p pointer to be converted
155 * @stable ICU 59
156 */
157 inline ConstChar16Ptr(const uint16_t *p);
158 #endif
159 #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
160 /**
161 * Converts the pointer to char16_t *.
162 * (Only defined if U_SIZEOF_WCHAR_T==2.)
163 * @param p pointer to be converted
164 * @stable ICU 59
165 */
166 inline ConstChar16Ptr(const wchar_t *p);
167 #endif
168 /**
169 * nullptr constructor.
170 * @param p nullptr
171 * @stable ICU 59
172 */
173 inline ConstChar16Ptr(const std::nullptr_t p);
174
175 /**
176 * Destructor.
177 * @stable ICU 59
178 */
179 inline ~ConstChar16Ptr();
180
181 /**
182 * Pointer access.
183 * @return the wrapped pointer
184 * @stable ICU 59
185 */
186 inline const char16_t *get() const;
187 /**
188 * char16_t pointer access via type conversion (e.g., static_cast).
189 * @return the wrapped pointer
190 * @stable ICU 59
191 */
192 inline operator const char16_t *() const { return get(); }
193
194 private:
195 ConstChar16Ptr() = delete;
196
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);
201 }
202
203 const char16_t *p_;
204 #else
205 union {
206 const char16_t *cp;
207 const uint16_t *up;
208 const wchar_t *wp;
209 } u_;
210 #endif
211 };
212
213 #ifdef U_ALIASING_BARRIER
214
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)) {}
218 #endif
219 #if U_SIZEOF_WCHAR_T==2
220 ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p_(cast(p)) {}
221 #endif
222 ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p_(p) {}
223 ConstChar16Ptr::~ConstChar16Ptr() {
224 U_ALIASING_BARRIER(p_);
225 }
226
227 const char16_t *ConstChar16Ptr::get() const { return p_; }
228
229 #else
230
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; }
234 #endif
235 #if U_SIZEOF_WCHAR_T==2
236 ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u_.wp = p; }
237 #endif
238 ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u_.cp = p; }
239 ConstChar16Ptr::~ConstChar16Ptr() {}
240
241 const char16_t *ConstChar16Ptr::get() const { return u_.cp; }
242
243 #endif
244
245 /**
246 * Converts from const char16_t * to const UChar *.
247 * Includes an aliasing barrier if available.
248 * @param p pointer
249 * @return p as const UChar *
250 * @stable ICU 59
251 */
252 inline const UChar *toUCharPtr(const char16_t *p) {
253 #ifdef U_ALIASING_BARRIER
254 U_ALIASING_BARRIER(p);
255 #endif
256 return reinterpret_cast<const UChar *>(p);
257 }
258
259 /**
260 * Converts from char16_t * to UChar *.
261 * Includes an aliasing barrier if available.
262 * @param p pointer
263 * @return p as UChar *
264 * @stable ICU 59
265 */
266 inline UChar *toUCharPtr(char16_t *p) {
267 #ifdef U_ALIASING_BARRIER
268 U_ALIASING_BARRIER(p);
269 #endif
270 return reinterpret_cast<UChar *>(p);
271 }
272
273 /**
274 * Converts from const char16_t * to const OldUChar *.
275 * Includes an aliasing barrier if available.
276 * @param p pointer
277 * @return p as const OldUChar *
278 * @stable ICU 59
279 */
280 inline const OldUChar *toOldUCharPtr(const char16_t *p) {
281 #ifdef U_ALIASING_BARRIER
282 U_ALIASING_BARRIER(p);
283 #endif
284 return reinterpret_cast<const OldUChar *>(p);
285 }
286
287 /**
288 * Converts from char16_t * to OldUChar *.
289 * Includes an aliasing barrier if available.
290 * @param p pointer
291 * @return p as OldUChar *
292 * @stable ICU 59
293 */
294 inline OldUChar *toOldUCharPtr(char16_t *p) {
295 #ifdef U_ALIASING_BARRIER
296 U_ALIASING_BARRIER(p);
297 #endif
298 return reinterpret_cast<OldUChar *>(p);
299 }
300
301 U_NAMESPACE_END
302 #endif // U_SHOW_CPLUSPLUS_API
303
304 #endif // __CHAR16PTR_H__