charconv.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2018 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef ABSL_STRINGS_CHARCONV_H_
  15. #define ABSL_STRINGS_CHARCONV_H_
  16. #include <system_error> // NOLINT(build/c++11)
  17. #include "absl/base/config.h"
  18. namespace absl {
  19. ABSL_NAMESPACE_BEGIN
  20. // Workalike compatibilty version of std::chars_format from C++17.
  21. //
  22. // This is an bitfield enumerator which can be passed to absl::from_chars to
  23. // configure the string-to-float conversion.
  24. enum class chars_format {
  25. scientific = 1,
  26. fixed = 2,
  27. hex = 4,
  28. general = fixed | scientific,
  29. };
  30. // The return result of a string-to-number conversion.
  31. //
  32. // `ec` will be set to `invalid_argument` if a well-formed number was not found
  33. // at the start of the input range, `result_out_of_range` if a well-formed
  34. // number was found, but it was out of the representable range of the requested
  35. // type, or to std::errc() otherwise.
  36. //
  37. // If a well-formed number was found, `ptr` is set to one past the sequence of
  38. // characters that were successfully parsed. If none was found, `ptr` is set
  39. // to the `first` argument to from_chars.
  40. struct from_chars_result {
  41. const char* ptr;
  42. std::errc ec;
  43. };
  44. // Workalike compatibilty version of std::from_chars from C++17. Currently
  45. // this only supports the `double` and `float` types.
  46. //
  47. // This interface incorporates the proposed resolutions for library issues
  48. // DR 3080 and DR 3081. If these are adopted with different wording,
  49. // Abseil's behavior will change to match the standard. (The behavior most
  50. // likely to change is for DR 3081, which says what `value` will be set to in
  51. // the case of overflow and underflow. Code that wants to avoid possible
  52. // breaking changes in this area should not depend on `value` when the returned
  53. // from_chars_result indicates a range error.)
  54. //
  55. // Searches the range [first, last) for the longest matching pattern beginning
  56. // at `first` that represents a floating point number. If one is found, store
  57. // the result in `value`.
  58. //
  59. // The matching pattern format is almost the same as that of strtod(), except
  60. // that C locale is not respected, and an initial '+' character in the input
  61. // range will never be matched.
  62. //
  63. // If `fmt` is set, it must be one of the enumerator values of the chars_format.
  64. // (This is despite the fact that chars_format is a bitmask type.) If set to
  65. // `scientific`, a matching number must contain an exponent. If set to `fixed`,
  66. // then an exponent will never match. (For example, the string "1e5" will be
  67. // parsed as "1".) If set to `hex`, then a hexadecimal float is parsed in the
  68. // format that strtod() accepts, except that a "0x" prefix is NOT matched.
  69. // (In particular, in `hex` mode, the input "0xff" results in the largest
  70. // matching pattern "0".)
  71. absl::from_chars_result from_chars(const char* first, const char* last,
  72. double& value, // NOLINT
  73. chars_format fmt = chars_format::general);
  74. absl::from_chars_result from_chars(const char* first, const char* last,
  75. float& value, // NOLINT
  76. chars_format fmt = chars_format::general);
  77. // std::chars_format is specified as a bitmask type, which means the following
  78. // operations must be provided:
  79. inline constexpr chars_format operator&(chars_format lhs, chars_format rhs) {
  80. return static_cast<chars_format>(static_cast<int>(lhs) &
  81. static_cast<int>(rhs));
  82. }
  83. inline constexpr chars_format operator|(chars_format lhs, chars_format rhs) {
  84. return static_cast<chars_format>(static_cast<int>(lhs) |
  85. static_cast<int>(rhs));
  86. }
  87. inline constexpr chars_format operator^(chars_format lhs, chars_format rhs) {
  88. return static_cast<chars_format>(static_cast<int>(lhs) ^
  89. static_cast<int>(rhs));
  90. }
  91. inline constexpr chars_format operator~(chars_format arg) {
  92. return static_cast<chars_format>(~static_cast<int>(arg));
  93. }
  94. inline chars_format& operator&=(chars_format& lhs, chars_format rhs) {
  95. lhs = lhs & rhs;
  96. return lhs;
  97. }
  98. inline chars_format& operator|=(chars_format& lhs, chars_format rhs) {
  99. lhs = lhs | rhs;
  100. return lhs;
  101. }
  102. inline chars_format& operator^=(chars_format& lhs, chars_format rhs) {
  103. lhs = lhs ^ rhs;
  104. return lhs;
  105. }
  106. ABSL_NAMESPACE_END
  107. } // namespace absl
  108. #endif // ABSL_STRINGS_CHARCONV_H_