master
  1// -*- C++ -*-
  2//===----------------------------------------------------------------------===//
  3//
  4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5// See https://llvm.org/LICENSE.txt for license information.
  6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7//
  8//===----------------------------------------------------------------------===//
  9
 10#ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
 11#define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
 12
 13#include <__algorithm/copy_n.h>
 14#include <__assert>
 15#include <__bit/countl.h>
 16#include <__charconv/tables.h>
 17#include <__charconv/to_chars_base_10.h>
 18#include <__charconv/to_chars_result.h>
 19#include <__charconv/traits.h>
 20#include <__config>
 21#include <__cstddef/ptrdiff_t.h>
 22#include <__system_error/errc.h>
 23#include <__type_traits/enable_if.h>
 24#include <__type_traits/integral_constant.h>
 25#include <__type_traits/is_integral.h>
 26#include <__type_traits/is_same.h>
 27#include <__type_traits/make_32_64_or_128_bit.h>
 28#include <__type_traits/make_unsigned.h>
 29#include <__utility/unreachable.h>
 30#include <cstdint>
 31#include <limits>
 32
 33#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 34#  pragma GCC system_header
 35#endif
 36
 37_LIBCPP_PUSH_MACROS
 38#include <__undef_macros>
 39
 40_LIBCPP_BEGIN_NAMESPACE_STD
 41
 42template <typename _Tp>
 43inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
 44__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
 45
 46template <typename _Tp>
 47inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
 48__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) {
 49  auto __x = std::__to_unsigned_like(__value);
 50  if (__value < 0 && __first != __last) {
 51    *__first++ = '-';
 52    __x        = std::__complement(__x);
 53  }
 54
 55  return std::__to_chars_itoa(__first, __last, __x, false_type());
 56}
 57
 58template <typename _Tp>
 59inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
 60__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
 61  using __tx  = __itoa::__traits<_Tp>;
 62  auto __diff = __last - __first;
 63
 64  if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
 65    return {__tx::__convert(__first, __value), errc(0)};
 66  else
 67    return {__last, errc::value_too_large};
 68}
 69
 70#  if _LIBCPP_HAS_INT128
 71template <>
 72inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
 73__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
 74  // When the value fits in 64-bits use the 64-bit code path. This reduces
 75  // the number of expensive calculations on 128-bit values.
 76  //
 77  // NOTE the 128-bit code path requires this optimization.
 78  if (__value <= numeric_limits<uint64_t>::max())
 79    return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
 80
 81  using __tx  = __itoa::__traits<__uint128_t>;
 82  auto __diff = __last - __first;
 83
 84  if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
 85    return {__tx::__convert(__first, __value), errc(0)};
 86  else
 87    return {__last, errc::value_too_large};
 88}
 89#  endif
 90
 91template <class _Tp, __enable_if_t<!is_signed<_Tp>::value, int> = 0>
 92inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
 93__to_chars_integral(char* __first, char* __last, _Tp __value, int __base);
 94
 95template <class _Tp, __enable_if_t<is_signed<_Tp>::value, int> = 0>
 96inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
 97__to_chars_integral(char* __first, char* __last, _Tp __value, int __base) {
 98  auto __x = std::__to_unsigned_like(__value);
 99  if (__value < 0 && __first != __last) {
100    *__first++ = '-';
101    __x        = std::__complement(__x);
102  }
103
104  return std::__to_chars_integral(__first, __last, __x, __base);
105}
106
107namespace __itoa {
108
109template <unsigned _Base>
110struct _LIBCPP_HIDDEN __integral;
111
112template <>
113struct _LIBCPP_HIDDEN __integral<2> {
114  template <typename _Tp>
115  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int __width(_Tp __value) _NOEXCEPT {
116    // If value == 0 still need one digit. If the value != this has no
117    // effect since the code scans for the most significant bit set.
118    return numeric_limits<_Tp>::digits - std::__countl_zero(__value | 1);
119  }
120
121  template <typename _Tp>
122  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static __to_chars_result
123  __to_chars(char* __first, char* __last, _Tp __value) {
124    ptrdiff_t __cap = __last - __first;
125    int __n         = __width(__value);
126    if (__n > __cap)
127      return {__last, errc::value_too_large};
128
129    __last                   = __first + __n;
130    char* __p                = __last;
131    const unsigned __divisor = 16;
132    while (__value > __divisor) {
133      unsigned __c = __value % __divisor;
134      __value /= __divisor;
135      __p -= 4;
136      std::copy_n(&__base_2_lut[4 * __c], 4, __p);
137    }
138    do {
139      unsigned __c = __value % 2;
140      __value /= 2;
141      *--__p = "01"[__c];
142    } while (__value != 0);
143    return {__last, errc(0)};
144  }
145};
146
147template <>
148struct _LIBCPP_HIDDEN __integral<8> {
149  template <typename _Tp>
150  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int __width(_Tp __value) _NOEXCEPT {
151    // If value == 0 still need one digit. If the value != this has no
152    // effect since the code scans for the most significat bit set.
153    return ((numeric_limits<_Tp>::digits - std::__countl_zero(__value | 1)) + 2) / 3;
154  }
155
156  template <typename _Tp>
157  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static __to_chars_result
158  __to_chars(char* __first, char* __last, _Tp __value) {
159    ptrdiff_t __cap = __last - __first;
160    int __n         = __width(__value);
161    if (__n > __cap)
162      return {__last, errc::value_too_large};
163
164    __last             = __first + __n;
165    char* __p          = __last;
166    unsigned __divisor = 64;
167    while (__value > __divisor) {
168      unsigned __c = __value % __divisor;
169      __value /= __divisor;
170      __p -= 2;
171      std::copy_n(&__base_8_lut[2 * __c], 2, __p);
172    }
173    do {
174      unsigned __c = __value % 8;
175      __value /= 8;
176      *--__p = "01234567"[__c];
177    } while (__value != 0);
178    return {__last, errc(0)};
179  }
180};
181
182template <>
183struct _LIBCPP_HIDDEN __integral<16> {
184  template <typename _Tp>
185  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int __width(_Tp __value) _NOEXCEPT {
186    // If value == 0 still need one digit. If the value != this has no
187    // effect since the code scans for the most significat bit set.
188    return (numeric_limits<_Tp>::digits - std::__countl_zero(__value | 1) + 3) / 4;
189  }
190
191  template <typename _Tp>
192  _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static __to_chars_result
193  __to_chars(char* __first, char* __last, _Tp __value) {
194    ptrdiff_t __cap = __last - __first;
195    int __n         = __width(__value);
196    if (__n > __cap)
197      return {__last, errc::value_too_large};
198
199    __last             = __first + __n;
200    char* __p          = __last;
201    unsigned __divisor = 256;
202    while (__value > __divisor) {
203      unsigned __c = __value % __divisor;
204      __value /= __divisor;
205      __p -= 2;
206      std::copy_n(&__base_16_lut[2 * __c], 2, __p);
207    }
208    if (__first != __last)
209      do {
210        unsigned __c = __value % 16;
211        __value /= 16;
212        *--__p = "0123456789abcdef"[__c];
213      } while (__value != 0);
214    return {__last, errc(0)};
215  }
216};
217
218} // namespace __itoa
219
220template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
221_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
222  return __itoa::__integral<_Base>::__width(__value);
223}
224
225template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
226_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
227  return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
228}
229
230template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
231_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
232__to_chars_integral(char* __first, char* __last, _Tp __value) {
233  return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
234}
235
236template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
237_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
238__to_chars_integral(char* __first, char* __last, _Tp __value) {
239  return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
240}
241
242template <typename _Tp>
243_LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) {
244  _LIBCPP_ASSERT_INTERNAL(__value >= 0, "The function requires a non-negative value.");
245
246  unsigned __base_2 = __base * __base;
247  unsigned __base_3 = __base_2 * __base;
248  unsigned __base_4 = __base_2 * __base_2;
249
250  int __r = 0;
251  while (true) {
252    if (__value < __base)
253      return __r + 1;
254    if (__value < __base_2)
255      return __r + 2;
256    if (__value < __base_3)
257      return __r + 3;
258    if (__value < __base_4)
259      return __r + 4;
260
261    __value /= __base_4;
262    __r += 4;
263  }
264
265  __libcpp_unreachable();
266}
267
268template <class _Tp, __enable_if_t<!is_signed<_Tp>::value, int> >
269inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __to_chars_result
270__to_chars_integral(char* __first, char* __last, _Tp __value, int __base) {
271  if (__base == 10) [[likely]]
272    return std::__to_chars_itoa(__first, __last, __value, false_type());
273
274  switch (__base) {
275  case 2:
276    return std::__to_chars_integral<2>(__first, __last, __value);
277  case 8:
278    return std::__to_chars_integral<8>(__first, __last, __value);
279  case 16:
280    return std::__to_chars_integral<16>(__first, __last, __value);
281  }
282
283  ptrdiff_t __cap = __last - __first;
284  int __n         = std::__to_chars_integral_width(__value, __base);
285  if (__n > __cap)
286    return {__last, errc::value_too_large};
287
288  __last    = __first + __n;
289  char* __p = __last;
290  do {
291    unsigned __c = __value % __base;
292    __value /= __base;
293    *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
294  } while (__value != 0);
295  return {__last, errc(0)};
296}
297
298_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 char __hex_to_upper(char __c) {
299  switch (__c) {
300  case 'a':
301    return 'A';
302  case 'b':
303    return 'B';
304  case 'c':
305    return 'C';
306  case 'd':
307    return 'D';
308  case 'e':
309    return 'E';
310  case 'f':
311    return 'F';
312  }
313  return __c;
314}
315
316#if _LIBCPP_STD_VER >= 17
317
318to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
319
320template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
321inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
322to_chars(char* __first, char* __last, _Tp __value) {
323  using _Type = __make_32_64_or_128_bit_t<_Tp>;
324  static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
325  return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
326}
327
328template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
329inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
330to_chars(char* __first, char* __last, _Tp __value, int __base) {
331  _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
332
333  using _Type = __make_32_64_or_128_bit_t<_Tp>;
334  return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base);
335}
336
337#endif // _LIBCPP_STD_VER >= 17
338
339_LIBCPP_END_NAMESPACE_STD
340
341_LIBCPP_POP_MACROS
342
343#endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H