You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 line
3.4KB

  1. // Numeric conversions (to_string, to_chars) -*- C++ -*-
  2. // Copyright (C) 2017-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/charconv.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{charconv}
  23. */
  24. #ifndef _GLIBCXX_CHARCONV_H
  25. #define _GLIBCXX_CHARCONV_H 1
  26. #pragma GCC system_header
  27. #if __cplusplus >= 201103L
  28. #include <type_traits>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  32. namespace __detail
  33. {
  34. // Generic implementation for arbitrary bases.
  35. template<typename _Tp>
  36. _GLIBCXX14_CONSTEXPR unsigned
  37. __to_chars_len(_Tp __value, int __base = 10) noexcept
  38. {
  39. static_assert(is_integral<_Tp>::value, "implementation bug");
  40. static_assert(is_unsigned<_Tp>::value, "implementation bug");
  41. unsigned __n = 1;
  42. const unsigned __b2 = __base * __base;
  43. const unsigned __b3 = __b2 * __base;
  44. const unsigned long __b4 = __b3 * __base;
  45. for (;;)
  46. {
  47. if (__value < (unsigned)__base) return __n;
  48. if (__value < __b2) return __n + 1;
  49. if (__value < __b3) return __n + 2;
  50. if (__value < __b4) return __n + 3;
  51. __value /= __b4;
  52. __n += 4;
  53. }
  54. }
  55. // Write an unsigned integer value to the range [first,first+len).
  56. // The caller is required to provide a buffer of exactly the right size
  57. // (which can be determined by the __to_chars_len function).
  58. template<typename _Tp>
  59. void
  60. __to_chars_10_impl(char* __first, unsigned __len, _Tp __val) noexcept
  61. {
  62. static_assert(is_integral<_Tp>::value, "implementation bug");
  63. static_assert(is_unsigned<_Tp>::value, "implementation bug");
  64. static constexpr char __digits[201] =
  65. "0001020304050607080910111213141516171819"
  66. "2021222324252627282930313233343536373839"
  67. "4041424344454647484950515253545556575859"
  68. "6061626364656667686970717273747576777879"
  69. "8081828384858687888990919293949596979899";
  70. unsigned __pos = __len - 1;
  71. while (__val >= 100)
  72. {
  73. auto const __num = (__val % 100) * 2;
  74. __val /= 100;
  75. __first[__pos] = __digits[__num + 1];
  76. __first[__pos - 1] = __digits[__num];
  77. __pos -= 2;
  78. }
  79. if (__val >= 10)
  80. {
  81. auto const __num = __val * 2;
  82. __first[1] = __digits[__num + 1];
  83. __first[0] = __digits[__num];
  84. }
  85. else
  86. __first[0] = '0' + __val;
  87. }
  88. } // namespace __detail
  89. _GLIBCXX_END_NAMESPACE_VERSION
  90. } // namespace std
  91. #endif // C++11
  92. #endif // _GLIBCXX_CHARCONV_H