1//
2// Copyright 2017 The Abseil Authors.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// https://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16// -----------------------------------------------------------------------------
17// File: numbers.h
18// -----------------------------------------------------------------------------
19//
20// This package contains functions for converting strings to numbers. For
21// converting numbers to strings, use `StrCat()` or `StrAppend()` in str_cat.h,
22// which automatically detect and convert most number values appropriately.
23
24#ifndef ABSL_STRINGS_NUMBERS_H_
25#define ABSL_STRINGS_NUMBERS_H_
26
27#include <cstddef>
28#include <cstdlib>
29#include <cstring>
30#include <ctime>
31#include <limits>
32#include <string>
33#include <type_traits>
34
35#include "absl/base/macros.h"
36#include "absl/base/port.h"
37#include "absl/numeric/int128.h"
38#include "absl/strings/string_view.h"
39
40namespace absl {
41
42// SimpleAtoi()
43//
44// Converts the given string into an integer value, returning `true` if
45// successful. The string must reflect a base-10 integer (optionally followed or
46// preceded by ASCII whitespace) whose value falls within the range of the
47// integer type. If any errors are encountered, this function returns `false`,
48// leaving `out` in an unspecified state.
49template <typename int_type>
50ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out);
51
52// SimpleAtof()
53//
54// Converts the given string (optionally followed or preceded by ASCII
55// whitespace) into a float, which may be rounded on overflow or underflow.
56// See https://en.cppreference.com/w/c/string/byte/strtof for details about the
57// allowed formats for `str`. If any errors are encountered, this function
58// returns `false`, leaving `out` in an unspecified state.
59ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out);
60
61// SimpleAtod()
62//
63// Converts the given string (optionally followed or preceded by ASCII
64// whitespace) into a double, which may be rounded on overflow or underflow.
65// See https://en.cppreference.com/w/c/string/byte/strtof for details about the
66// allowed formats for `str`. If any errors are encountered, this function
67// returns `false`, leaving `out` in an unspecified state.
68ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out);
69
70// SimpleAtob()
71//
72// Converts the given string into a boolean, returning `true` if successful.
73// The following case-insensitive strings are interpreted as boolean `true`:
74// "true", "t", "yes", "y", "1". The following case-insensitive strings
75// are interpreted as boolean `false`: "false", "f", "no", "n", "0". If any
76// errors are encountered, this function returns `false`, leaving `out` in an
77// unspecified state.
78ABSL_MUST_USE_RESULT bool SimpleAtob(absl::string_view str, bool* out);
79
80} // namespace absl
81
82// End of public API. Implementation details follow.
83
84namespace absl {
85namespace numbers_internal {
86
87// safe_strto?() functions for implementing SimpleAtoi()
88bool safe_strto32_base(absl::string_view text, int32_t* value, int base);
89bool safe_strto64_base(absl::string_view text, int64_t* value, int base);
90bool safe_strtou32_base(absl::string_view text, uint32_t* value, int base);
91bool safe_strtou64_base(absl::string_view text, uint64_t* value, int base);
92
93static const int kFastToBufferSize = 32;
94static const int kSixDigitsToBufferSize = 16;
95
96// Helper function for fast formatting of floating-point values.
97// The result is the same as printf's "%g", a.k.a. "%.6g"; that is, six
98// significant digits are returned, trailing zeros are removed, and numbers
99// outside the range 0.0001-999999 are output using scientific notation
100// (1.23456e+06). This routine is heavily optimized.
101// Required buffer size is `kSixDigitsToBufferSize`.
102size_t SixDigitsToBuffer(double d, char* buffer);
103
104// These functions are intended for speed. All functions take an output buffer
105// as an argument and return a pointer to the last byte they wrote, which is the
106// terminating '\0'. At most `kFastToBufferSize` bytes are written.
107char* FastIntToBuffer(int32_t, char*);
108char* FastIntToBuffer(uint32_t, char*);
109char* FastIntToBuffer(int64_t, char*);
110char* FastIntToBuffer(uint64_t, char*);
111
112// For enums and integer types that are not an exact match for the types above,
113// use templates to call the appropriate one of the four overloads above.
114template <typename int_type>
115char* FastIntToBuffer(int_type i, char* buffer) {
116 static_assert(sizeof(i) <= 64 / 8,
117 "FastIntToBuffer works only with 64-bit-or-less integers.");
118 // TODO(jorg): This signed-ness check is used because it works correctly
119 // with enums, and it also serves to check that int_type is not a pointer.
120 // If one day something like std::is_signed<enum E> works, switch to it.
121 if (static_cast<int_type>(1) - 2 < 0) { // Signed
122 if (sizeof(i) > 32 / 8) { // 33-bit to 64-bit
123 return FastIntToBuffer(static_cast<int64_t>(i), buffer);
124 } else { // 32-bit or less
125 return FastIntToBuffer(static_cast<int32_t>(i), buffer);
126 }
127 } else { // Unsigned
128 if (sizeof(i) > 32 / 8) { // 33-bit to 64-bit
129 return FastIntToBuffer(static_cast<uint64_t>(i), buffer);
130 } else { // 32-bit or less
131 return FastIntToBuffer(static_cast<uint32_t>(i), buffer);
132 }
133 }
134}
135
136// Implementation of SimpleAtoi, generalized to support arbitrary base (used
137// with base different from 10 elsewhere in Abseil implementation).
138template <typename int_type>
139ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out,
140 int base) {
141 static_assert(sizeof(*out) == 4 || sizeof(*out) == 8,
142 "SimpleAtoi works only with 32-bit or 64-bit integers.");
143 static_assert(!std::is_floating_point<int_type>::value,
144 "Use SimpleAtof or SimpleAtod instead.");
145 bool parsed;
146 // TODO(jorg): This signed-ness check is used because it works correctly
147 // with enums, and it also serves to check that int_type is not a pointer.
148 // If one day something like std::is_signed<enum E> works, switch to it.
149 if (static_cast<int_type>(1) - 2 < 0) { // Signed
150 if (sizeof(*out) == 64 / 8) { // 64-bit
151 int64_t val;
152 parsed = numbers_internal::safe_strto64_base(s, &val, base);
153 *out = static_cast<int_type>(val);
154 } else { // 32-bit
155 int32_t val;
156 parsed = numbers_internal::safe_strto32_base(s, &val, base);
157 *out = static_cast<int_type>(val);
158 }
159 } else { // Unsigned
160 if (sizeof(*out) == 64 / 8) { // 64-bit
161 uint64_t val;
162 parsed = numbers_internal::safe_strtou64_base(s, &val, base);
163 *out = static_cast<int_type>(val);
164 } else { // 32-bit
165 uint32_t val;
166 parsed = numbers_internal::safe_strtou32_base(s, &val, base);
167 *out = static_cast<int_type>(val);
168 }
169 }
170 return parsed;
171}
172
173} // namespace numbers_internal
174
175// SimpleAtoi()
176//
177// Converts a string to an integer, using `safe_strto?()` functions for actual
178// parsing, returning `true` if successful. The `safe_strto?()` functions apply
179// strict checking; the string must be a base-10 integer, optionally followed or
180// preceded by ASCII whitespace, with a value in the range of the corresponding
181// integer type.
182template <typename int_type>
183ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out) {
184 return numbers_internal::safe_strtoi_base(s, out, 10);
185}
186
187} // namespace absl
188
189#endif // ABSL_STRINGS_NUMBERS_H_
190