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