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