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