xref: /aosp_15_r20/external/dynamic_depth/internal/strings/numbers.h (revision a62be0856e8e1158f43b03e41bbad10f4d005fde)
1*a62be085SSadaf Ebrahimi #ifndef DYNAMIC_DEPTH_INTERNAL_STRINGS_NUMBERS_H_  // NOLINT
2*a62be085SSadaf Ebrahimi #define DYNAMIC_DEPTH_INTERNAL_STRINGS_NUMBERS_H_  // NOLINT
3*a62be085SSadaf Ebrahimi 
4*a62be085SSadaf Ebrahimi #include <stddef.h>
5*a62be085SSadaf Ebrahimi #include <stdlib.h>
6*a62be085SSadaf Ebrahimi #include <string.h>
7*a62be085SSadaf Ebrahimi #include <time.h>
8*a62be085SSadaf Ebrahimi #include <functional>
9*a62be085SSadaf Ebrahimi #include <limits>
10*a62be085SSadaf Ebrahimi #include <string>
11*a62be085SSadaf Ebrahimi 
12*a62be085SSadaf Ebrahimi #include "base/integral_types.h"
13*a62be085SSadaf Ebrahimi #include "base/port.h"
14*a62be085SSadaf Ebrahimi #include "strings/ascii_ctype.h"
15*a62be085SSadaf Ebrahimi 
16*a62be085SSadaf Ebrahimi namespace dynamic_depth {
17*a62be085SSadaf Ebrahimi namespace strings {
18*a62be085SSadaf Ebrahimi 
19*a62be085SSadaf Ebrahimi // Convert strings to numeric values, with strict error checking.
20*a62be085SSadaf Ebrahimi // Leading and trailing spaces are allowed.
21*a62be085SSadaf Ebrahimi // Negative inputs are not allowed for unsigned ints (unlike strtoul).
22*a62be085SSadaf Ebrahimi //
23*a62be085SSadaf Ebrahimi // Base must be [0, 2-36].
24*a62be085SSadaf Ebrahimi // Base 0:
25*a62be085SSadaf Ebrahimi //   auto-select base from first two chars:
26*a62be085SSadaf Ebrahimi //    "0x" -> hex
27*a62be085SSadaf Ebrahimi //    "0" -> octal
28*a62be085SSadaf Ebrahimi //    else -> decimal
29*a62be085SSadaf Ebrahimi // Base 16:
30*a62be085SSadaf Ebrahimi //   Number can start with "0x"
31*a62be085SSadaf Ebrahimi //
32*a62be085SSadaf Ebrahimi // On error, returns false, and sets *value to:
33*a62be085SSadaf Ebrahimi //   std::numeric_limits<T>::max() on overflow
34*a62be085SSadaf Ebrahimi //   std::numeric_limits<T>::min() on underflow
35*a62be085SSadaf Ebrahimi //   conversion of leading substring if available ("123@@@" -> 123)
36*a62be085SSadaf Ebrahimi //   0 if no leading substring available
37*a62be085SSadaf Ebrahimi // The effect on errno is unspecified.
38*a62be085SSadaf Ebrahimi // Do not depend on testing errno.
39*a62be085SSadaf Ebrahimi bool safe_strto32_base(const string& text, int32* value, int base);
40*a62be085SSadaf Ebrahimi bool safe_strto64_base(const string& text, int64* value, int base);
41*a62be085SSadaf Ebrahimi bool safe_strtou32_base(const string& text, uint32* value, int base);
42*a62be085SSadaf Ebrahimi bool safe_strtou64_base(const string& text, uint64* value, int base);
43*a62be085SSadaf Ebrahimi bool safe_strtosize_t_base(const string& text, size_t* value, int base);
44*a62be085SSadaf Ebrahimi 
45*a62be085SSadaf Ebrahimi // Convenience functions with base == 10.
safe_strto32(const string & text,int32 * value)46*a62be085SSadaf Ebrahimi inline bool safe_strto32(const string& text, int32* value) {
47*a62be085SSadaf Ebrahimi   return safe_strto32_base(text, value, 10);
48*a62be085SSadaf Ebrahimi }
49*a62be085SSadaf Ebrahimi 
safe_strto64(const string & text,int64 * value)50*a62be085SSadaf Ebrahimi inline bool safe_strto64(const string& text, int64* value) {
51*a62be085SSadaf Ebrahimi   return safe_strto64_base(text, value, 10);
52*a62be085SSadaf Ebrahimi }
53*a62be085SSadaf Ebrahimi 
safe_strtou32(const string & text,uint32 * value)54*a62be085SSadaf Ebrahimi inline bool safe_strtou32(const string& text, uint32* value) {
55*a62be085SSadaf Ebrahimi   return safe_strtou32_base(text, value, 10);
56*a62be085SSadaf Ebrahimi }
57*a62be085SSadaf Ebrahimi 
safe_strtou64(const string & text,uint64 * value)58*a62be085SSadaf Ebrahimi inline bool safe_strtou64(const string& text, uint64* value) {
59*a62be085SSadaf Ebrahimi   return safe_strtou64_base(text, value, 10);
60*a62be085SSadaf Ebrahimi }
61*a62be085SSadaf Ebrahimi 
62*a62be085SSadaf Ebrahimi // Convert strings to floating point values.
63*a62be085SSadaf Ebrahimi // Leading and trailing spaces are allowed.
64*a62be085SSadaf Ebrahimi // Values may be rounded on over- and underflow.
65*a62be085SSadaf Ebrahimi bool safe_strtof(const string& str, float* value);
66*a62be085SSadaf Ebrahimi 
67*a62be085SSadaf Ebrahimi bool safe_strtod(const string& str, double* value);
68*a62be085SSadaf Ebrahimi 
69*a62be085SSadaf Ebrahimi // Previously documented minimums -- the buffers provided must be at least this
70*a62be085SSadaf Ebrahimi // long, though these numbers are subject to change:
71*a62be085SSadaf Ebrahimi //     Int32, UInt32:                   12 bytes
72*a62be085SSadaf Ebrahimi //     Int64, UInt64, Int, Uint:        22 bytes
73*a62be085SSadaf Ebrahimi //     Time:                            30 bytes
74*a62be085SSadaf Ebrahimi // Use kFastToBufferSize rather than hardcoding constants.
75*a62be085SSadaf Ebrahimi static const int kFastToBufferSize = 32;
76*a62be085SSadaf Ebrahimi 
77*a62be085SSadaf Ebrahimi // ----------------------------------------------------------------------
78*a62be085SSadaf Ebrahimi // FastInt32ToBufferLeft()
79*a62be085SSadaf Ebrahimi // FastUInt32ToBufferLeft()
80*a62be085SSadaf Ebrahimi // FastInt64ToBufferLeft()
81*a62be085SSadaf Ebrahimi // FastUInt64ToBufferLeft()
82*a62be085SSadaf Ebrahimi //
83*a62be085SSadaf Ebrahimi // Like the Fast*ToBuffer() functions above, these are intended for speed.
84*a62be085SSadaf Ebrahimi // Unlike the Fast*ToBuffer() functions, however, these functions write
85*a62be085SSadaf Ebrahimi // their output to the beginning of the buffer (hence the name, as the
86*a62be085SSadaf Ebrahimi // output is left-aligned).  The caller is responsible for ensuring that
87*a62be085SSadaf Ebrahimi // the buffer has enough space to hold the output.
88*a62be085SSadaf Ebrahimi //
89*a62be085SSadaf Ebrahimi // Returns a pointer to the end of the string (i.e. the null character
90*a62be085SSadaf Ebrahimi // terminating the string).
91*a62be085SSadaf Ebrahimi // ----------------------------------------------------------------------
92*a62be085SSadaf Ebrahimi 
93*a62be085SSadaf Ebrahimi char* FastInt32ToBufferLeft(int32 i, char* buffer);    // at least 12 bytes
94*a62be085SSadaf Ebrahimi char* FastUInt32ToBufferLeft(uint32 i, char* buffer);  // at least 12 bytes
95*a62be085SSadaf Ebrahimi char* FastInt64ToBufferLeft(int64 i, char* buffer);    // at least 22 bytes
96*a62be085SSadaf Ebrahimi char* FastUInt64ToBufferLeft(uint64 i, char* buffer);  // at least 22 bytes
97*a62be085SSadaf Ebrahimi 
98*a62be085SSadaf Ebrahimi // ----------------------------------------------------------------------
99*a62be085SSadaf Ebrahimi // SimpleFtoa()
100*a62be085SSadaf Ebrahimi //    Description: converts a double or float to a string which, if passed to
101*a62be085SSadaf Ebrahimi //    strtod() or strtof() respectively, will produce the exact same original
102*a62be085SSadaf Ebrahimi //    double or float.  Exception: for NaN values, strtod(SimpleDtoa(NaN)) or
103*a62be085SSadaf Ebrahimi //    strtof(SimpleFtoa(NaN)) may produce any NaN value, not necessarily the
104*a62be085SSadaf Ebrahimi //    exact same original NaN value.
105*a62be085SSadaf Ebrahimi //
106*a62be085SSadaf Ebrahimi //    The output string is not guaranteed to be as short as possible.
107*a62be085SSadaf Ebrahimi //
108*a62be085SSadaf Ebrahimi //    The output string, including terminating NUL, will have length
109*a62be085SSadaf Ebrahimi //    less than or equal to kFastToBufferSize defined above.  Of course,
110*a62be085SSadaf Ebrahimi //    we would prefer that your code not depend on this property of
111*a62be085SSadaf Ebrahimi //    the output string.  This guarantee derives from a similar guarantee
112*a62be085SSadaf Ebrahimi //    from the previous generation of char-buffer-based functions.
113*a62be085SSadaf Ebrahimi //    We had to carry it forward to preserve compatibility.
114*a62be085SSadaf Ebrahimi // ----------------------------------------------------------------------
115*a62be085SSadaf Ebrahimi string SimpleFtoa(float value);
116*a62be085SSadaf Ebrahimi 
117*a62be085SSadaf Ebrahimi // ----------------------------------------------------------------------
118*a62be085SSadaf Ebrahimi // SimpleItoa()
119*a62be085SSadaf Ebrahimi //    Description: converts an integer to a string.
120*a62be085SSadaf Ebrahimi //    Faster than printf("%d").
121*a62be085SSadaf Ebrahimi //
122*a62be085SSadaf Ebrahimi //    Return value: string
123*a62be085SSadaf Ebrahimi // ----------------------------------------------------------------------
SimpleItoa(int32 i)124*a62be085SSadaf Ebrahimi inline string SimpleItoa(int32 i) {
125*a62be085SSadaf Ebrahimi   char buf[16];  // Longest is -2147483648
126*a62be085SSadaf Ebrahimi   return string(buf, FastInt32ToBufferLeft(i, buf));
127*a62be085SSadaf Ebrahimi }
128*a62be085SSadaf Ebrahimi 
129*a62be085SSadaf Ebrahimi // We need this overload because otherwise SimpleItoa(5U) wouldn't compile.
SimpleItoa(uint32 i)130*a62be085SSadaf Ebrahimi inline string SimpleItoa(uint32 i) {
131*a62be085SSadaf Ebrahimi   char buf[16];  // Longest is 4294967295
132*a62be085SSadaf Ebrahimi   return string(buf, FastUInt32ToBufferLeft(i, buf));
133*a62be085SSadaf Ebrahimi }
134*a62be085SSadaf Ebrahimi 
SimpleItoa(int64 i)135*a62be085SSadaf Ebrahimi inline string SimpleItoa(int64 i) {
136*a62be085SSadaf Ebrahimi   char buf[32];  // Longest is -9223372036854775808
137*a62be085SSadaf Ebrahimi   return string(buf, FastInt64ToBufferLeft(i, buf));
138*a62be085SSadaf Ebrahimi }
139*a62be085SSadaf Ebrahimi 
140*a62be085SSadaf Ebrahimi // We need this overload because otherwise SimpleItoa(5ULL) wouldn't compile.
SimpleItoa(uint64 i)141*a62be085SSadaf Ebrahimi inline string SimpleItoa(uint64 i) {
142*a62be085SSadaf Ebrahimi   char buf[32];  // Longest is 18446744073709551615
143*a62be085SSadaf Ebrahimi   return string(buf, FastUInt64ToBufferLeft(i, buf));
144*a62be085SSadaf Ebrahimi }
145*a62be085SSadaf Ebrahimi 
SimpleItoa(long i)146*a62be085SSadaf Ebrahimi inline string SimpleItoa(long i) {  // NOLINT long is OK here
147*a62be085SSadaf Ebrahimi   if (sizeof(i) == 64 / 8) {
148*a62be085SSadaf Ebrahimi     return SimpleItoa(static_cast<int64>(i));
149*a62be085SSadaf Ebrahimi   } else if (sizeof(i) == 32 / 8) {
150*a62be085SSadaf Ebrahimi     return SimpleItoa(static_cast<int32>(i));
151*a62be085SSadaf Ebrahimi   }
152*a62be085SSadaf Ebrahimi }
153*a62be085SSadaf Ebrahimi 
SimpleItoa(unsigned long i)154*a62be085SSadaf Ebrahimi inline string SimpleItoa(unsigned long i) {  // NOLINT long is OK here
155*a62be085SSadaf Ebrahimi   if (sizeof(i) == 64 / 8) {
156*a62be085SSadaf Ebrahimi     return SimpleItoa(static_cast<uint64>(i));
157*a62be085SSadaf Ebrahimi   } else if (sizeof(i) == 32 / 8) {
158*a62be085SSadaf Ebrahimi     return SimpleItoa(static_cast<uint32>(i));
159*a62be085SSadaf Ebrahimi   }
160*a62be085SSadaf Ebrahimi }
161*a62be085SSadaf Ebrahimi 
162*a62be085SSadaf Ebrahimi // Required buffer size for FloatToBuffer is kFastToBufferSize.
163*a62be085SSadaf Ebrahimi char* FloatToBuffer(float i, char* buffer);
164*a62be085SSadaf Ebrahimi 
165*a62be085SSadaf Ebrahimi }  // namespace strings
166*a62be085SSadaf Ebrahimi }  // namespace dynamic_depth
167*a62be085SSadaf Ebrahimi 
168*a62be085SSadaf Ebrahimi #endif  // DYNAMIC_DEPTH_INTERNAL_STRINGS_NUMBERS_H_  // NOLINT
169