ICU 76.1  76.1
char16ptr.h
Go to the documentation of this file.
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 U_SHOW_CPLUSPLUS_API
13 
14 #include <cstddef>
15 #include <string_view>
16 
24 U_NAMESPACE_BEGIN
25 
31 #ifdef U_ALIASING_BARRIER
32  // Use the predefined value.
33 #elif (defined(__clang__) || defined(__GNUC__)) && U_PLATFORM != U_PF_BROWSER_NATIVE_CLIENT
34 # define U_ALIASING_BARRIER(ptr) asm volatile("" : : "rm"(ptr) : "memory")
35 #elif defined(U_IN_DOXYGEN)
36 # define U_ALIASING_BARRIER(ptr)
37 #endif
38 
43 class U_COMMON_API Char16Ptr final {
44 public:
50  inline Char16Ptr(char16_t *p);
51 #if !U_CHAR16_IS_TYPEDEF
52 
57  inline Char16Ptr(uint16_t *p);
58 #endif
59 #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
60 
66  inline Char16Ptr(wchar_t *p);
67 #endif
68 
73  inline Char16Ptr(std::nullptr_t p);
78  inline ~Char16Ptr();
79 
85  inline char16_t *get() const;
91  inline operator char16_t *() const { return get(); }
92 
93 private:
94  Char16Ptr() = delete;
95 
96 #ifdef U_ALIASING_BARRIER
97  template<typename T> static char16_t *cast(T *t) {
99  return reinterpret_cast<char16_t *>(t);
100  }
101 
102  char16_t *p_;
103 #else
104  union {
105  char16_t *cp;
106  uint16_t *up;
107  wchar_t *wp;
108  } u_;
109 #endif
110 };
111 
113 #ifdef U_ALIASING_BARRIER
114 
115 Char16Ptr::Char16Ptr(char16_t *p) : p_(p) {}
116 #if !U_CHAR16_IS_TYPEDEF
117 Char16Ptr::Char16Ptr(uint16_t *p) : p_(cast(p)) {}
118 #endif
119 #if U_SIZEOF_WCHAR_T==2
120 Char16Ptr::Char16Ptr(wchar_t *p) : p_(cast(p)) {}
121 #endif
122 Char16Ptr::Char16Ptr(std::nullptr_t p) : p_(p) {}
124  U_ALIASING_BARRIER(p_);
125 }
126 
127 char16_t *Char16Ptr::get() const { return p_; }
128 
129 #else
130 
131 Char16Ptr::Char16Ptr(char16_t *p) { u_.cp = p; }
132 #if !U_CHAR16_IS_TYPEDEF
133 Char16Ptr::Char16Ptr(uint16_t *p) { u_.up = p; }
134 #endif
135 #if U_SIZEOF_WCHAR_T==2
136 Char16Ptr::Char16Ptr(wchar_t *p) { u_.wp = p; }
137 #endif
138 Char16Ptr::Char16Ptr(std::nullptr_t p) { u_.cp = p; }
140 
141 char16_t *Char16Ptr::get() const { return u_.cp; }
142 
143 #endif
144 
151 public:
157  inline ConstChar16Ptr(const char16_t *p);
158 #if !U_CHAR16_IS_TYPEDEF
159 
164  inline ConstChar16Ptr(const uint16_t *p);
165 #endif
166 #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
167 
173  inline ConstChar16Ptr(const wchar_t *p);
174 #endif
175 
180  inline ConstChar16Ptr(const std::nullptr_t p);
181 
186  inline ~ConstChar16Ptr();
187 
193  inline const char16_t *get() const;
199  inline operator const char16_t *() const { return get(); }
200 
201 private:
202  ConstChar16Ptr() = delete;
203 
204 #ifdef U_ALIASING_BARRIER
205  template<typename T> static const char16_t *cast(const T *t) {
207  return reinterpret_cast<const char16_t *>(t);
208  }
209 
210  const char16_t *p_;
211 #else
212  union {
213  const char16_t *cp;
214  const uint16_t *up;
215  const wchar_t *wp;
216  } u_;
217 #endif
218 };
219 
221 #ifdef U_ALIASING_BARRIER
222 
223 ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) : p_(p) {}
224 #if !U_CHAR16_IS_TYPEDEF
225 ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) : p_(cast(p)) {}
226 #endif
227 #if U_SIZEOF_WCHAR_T==2
228 ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) : p_(cast(p)) {}
229 #endif
230 ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) : p_(p) {}
232  U_ALIASING_BARRIER(p_);
233 }
234 
235 const char16_t *ConstChar16Ptr::get() const { return p_; }
236 
237 #else
238 
239 ConstChar16Ptr::ConstChar16Ptr(const char16_t *p) { u_.cp = p; }
240 #if !U_CHAR16_IS_TYPEDEF
241 ConstChar16Ptr::ConstChar16Ptr(const uint16_t *p) { u_.up = p; }
242 #endif
243 #if U_SIZEOF_WCHAR_T==2
244 ConstChar16Ptr::ConstChar16Ptr(const wchar_t *p) { u_.wp = p; }
245 #endif
246 ConstChar16Ptr::ConstChar16Ptr(const std::nullptr_t p) { u_.cp = p; }
248 
249 const char16_t *ConstChar16Ptr::get() const { return u_.cp; }
250 
251 #endif
252 
261 inline const UChar *toUCharPtr(const char16_t *p) {
262 #ifdef U_ALIASING_BARRIER
264 #endif
265  return reinterpret_cast<const UChar *>(p);
266 }
267 
275 inline UChar *toUCharPtr(char16_t *p) {
276 #ifdef U_ALIASING_BARRIER
278 #endif
279  return reinterpret_cast<UChar *>(p);
280 }
281 
289 inline const OldUChar *toOldUCharPtr(const char16_t *p) {
290 #ifdef U_ALIASING_BARRIER
292 #endif
293  return reinterpret_cast<const OldUChar *>(p);
294 }
295 
303 inline OldUChar *toOldUCharPtr(char16_t *p) {
304 #ifdef U_ALIASING_BARRIER
306 #endif
307  return reinterpret_cast<OldUChar *>(p);
308 }
309 
310 #ifndef U_FORCE_HIDE_INTERNAL_API
311 
315 template<typename T>
317  std::is_convertible_v<T, std::u16string_view>
318 #if !U_CHAR16_IS_TYPEDEF && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 180000)
319  || std::is_convertible_v<T, std::basic_string_view<uint16_t>>
320 #endif
321 #if U_SIZEOF_WCHAR_T==2
322  || std::is_convertible_v<T, std::wstring_view>
323 #endif
324  ;
325 
326 namespace internal {
331 inline std::u16string_view toU16StringView(std::u16string_view sv) { return sv; }
332 
333 #if !U_CHAR16_IS_TYPEDEF && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 180000)
334 
339 inline std::u16string_view toU16StringView(std::basic_string_view<uint16_t> sv) {
340  return { ConstChar16Ptr(sv.data()), sv.length() };
341 }
342 #endif
343 
344 #if U_SIZEOF_WCHAR_T==2
345 
350 inline std::u16string_view toU16StringView(std::wstring_view sv) {
351  return { ConstChar16Ptr(sv.data()), sv.length() };
352 }
353 #endif
354 
359 template <typename T,
360  typename = typename std::enable_if_t<!std::is_pointer_v<std::remove_reference_t<T>>>>
361 inline std::u16string_view toU16StringViewNullable(const T& text) {
362  return toU16StringView(text);
363 }
364 
369 template <typename T,
370  typename = typename std::enable_if_t<std::is_pointer_v<std::remove_reference_t<T>>>,
371  typename = void>
372 inline std::u16string_view toU16StringViewNullable(const T& text) {
373  if (text == nullptr) return {}; // For backward compatibility.
374  return toU16StringView(text);
375 }
376 
377 } // internal
378 #endif // U_FORCE_HIDE_INTERNAL_API
379 
380 U_NAMESPACE_END
381 
382 #endif /* U_SHOW_CPLUSPLUS_API */
383 
384 #endif // __CHAR16PTR_H__
std::u16string_view toU16StringViewNullable(const T &text)
Pass-through overload.
Definition: char16ptr.h:361
uint16_t OldUChar
Default ICU 58 definition of UChar.
Definition: umachine.h:407
const char16_t * get() const
Pointer access.
const OldUChar * toOldUCharPtr(const char16_t *p)
Converts from const char16_t * to const OldUChar *.
Definition: char16ptr.h:289
#define U_ALIASING_BARRIER(ptr)
Barrier for pointer anti-aliasing optimizations even across function boundaries.
Definition: char16ptr.h:36
char16_t * get() const
Pointer access.
~ConstChar16Ptr()
Destructor.
const UChar * toUCharPtr(const char16_t *p)
Converts from const char16_t * to const UChar *.
Definition: char16ptr.h:261
std::u16string_view toU16StringView(std::u16string_view sv)
Pass-through overload.
Definition: char16ptr.h:331
char16_t UChar
The base type for UTF-16 code units and pointers.
Definition: umachine.h:378
~Char16Ptr()
Destructor.
char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types...
Definition: char16ptr.h:43
const char16_t * wrapper with implicit conversion from distinct but bit-compatible pointer types...
Definition: char16ptr.h:150
Basic definitions for ICU, for both C and C++ APIs.
#define U_COMMON_API
Set to export library symbols from inside the common library, and to import them from outside...
Definition: utypes.h:315
constexpr bool ConvertibleToU16StringView
Is T convertible to a std::u16string_view or some other 16-bit string view?
Definition: char16ptr.h:316