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)116Char16Ptr::Char16Ptr(char16_t *p) : p_(p) {} 117 #if !U_CHAR16_IS_TYPEDEF Char16Ptr(uint16_t * p)118Char16Ptr::Char16Ptr(uint16_t *p) : p_(cast(p)) {} 119 #endif 120 #if U_SIZEOF_WCHAR_T==2 Char16Ptr(wchar_t * p)121Char16Ptr::Char16Ptr(wchar_t *p) : p_(cast(p)) {} 122 #endif Char16Ptr(std::nullptr_t p)123Char16Ptr::Char16Ptr(std::nullptr_t p) : p_(p) {} ~Char16Ptr()124Char16Ptr::~Char16Ptr() { 125 U_ALIASING_BARRIER(p_); 126 } 127 get()128char16_t *Char16Ptr::get() const { return p_; } 129 130 #else 131 Char16Ptr(char16_t * p)132Char16Ptr::Char16Ptr(char16_t *p) { u_.cp = p; } 133 #if !U_CHAR16_IS_TYPEDEF Char16Ptr(uint16_t * p)134Char16Ptr::Char16Ptr(uint16_t *p) { u_.up = p; } 135 #endif 136 #if U_SIZEOF_WCHAR_T==2 Char16Ptr(wchar_t * p)137Char16Ptr::Char16Ptr(wchar_t *p) { u_.wp = p; } 138 #endif Char16Ptr(std::nullptr_t p)139Char16Ptr::Char16Ptr(std::nullptr_t p) { u_.cp = p; } ~Char16Ptr()140Char16Ptr::~Char16Ptr() {} 141 get()142char16_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)224ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) : p_(p) {} 225 #if !U_CHAR16_IS_TYPEDEF ConstChar16Ptr(const uint16_t * p)226ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) : p_(cast(p)) {} 227 #endif 228 #if U_SIZEOF_WCHAR_T==2 ConstChar16Ptr(const wchar_t * p)229ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p_(cast(p)) {} 230 #endif ConstChar16Ptr(const std::nullptr_t p)231ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p_(p) {} ~ConstChar16Ptr()232ConstChar16Ptr::~ConstChar16Ptr() { 233 U_ALIASING_BARRIER(p_); 234 } 235 get()236const char16_t *ConstChar16Ptr::get() const { return p_; } 237 238 #else 239 ConstChar16Ptr(const char16_t * p)240ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) { u_.cp = p; } 241 #if !U_CHAR16_IS_TYPEDEF ConstChar16Ptr(const uint16_t * p)242ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) { u_.up = p; } 243 #endif 244 #if U_SIZEOF_WCHAR_T==2 ConstChar16Ptr(const wchar_t * p)245ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u_.wp = p; } 246 #endif ConstChar16Ptr(const std::nullptr_t p)247ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u_.cp = p; } ~ConstChar16Ptr()248ConstChar16Ptr::~ConstChar16Ptr() {} 249 get()250const 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)262inline 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)276inline 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)290inline 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)304inline 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